You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复Elastic Watcher JVM内存告警Painless脚本编译错误

Elastic Watcher JVM内存告警Painless脚本编译错误修复方案

编译错误根因

移除transform后查询正常,说明索引检索、字段映射均无问题,无详情compile error基本都是以下三类Painless语法问题导致:

  • 带.的字段访问方式错误:host.name、service.name这类字段名本身包含点,若直接用source.host.name写法,Painless会将其解析为嵌套对象属性访问,和实际平级存储的字段结构不匹配,直接触发编译失败。
  • 语法不符合Painless规范:比如用var声明变量(Painless仅支持def做类型推断)、漏写语句分号、未做类型强转导致数值运算类型不匹配、字符串嵌套引号冲突。
  • transform返回结构不合法:Watcher要求transform脚本必须返回可序列化的Map/List结构,未写return语句、返回基本类型值都会触发校验错误。

可直接复用的正确配置

transform 数据处理片段

"transform": {
  "script": {
    "lang": "painless",
    "source": """
      def alertThreshold = 90.0;
      def targetAlerts = new ArrayList();
      for (def hit : ctx.payload.hits.hits) {
        def docSource = hit._source;
        // 安全读取字段,缺省值设为0避免空指针
        def usedSurvivor = docSource.getOrDefault('memory_used_g1_survivor_space', 0);
        def usedEden = docSource.getOrDefault('memory_used_g1_eden_space', 0);
        def usedOld = docSource.getOrDefault('memory_used_g1_old_gen', 0);
        def maxSurvivor = docSource.getOrDefault('memory_max_g1_survivor_space', 0);
        def maxEden = docSource.getOrDefault('memory_max_g1_eden_space', 0);
        def maxOld = docSource.getOrDefault('memory_max_g1_old_gen', 0);

        // 强转为double避免整数除法精度丢失
        def totalUsed = (double)usedSurvivor + usedEden + usedOld;
        def totalMax = (double)maxSurvivor + maxEden + maxOld;
        // 跳过最大内存为0的异常数据,避免除零错误
        if (totalMax <= 0) {
          continue;
        }

        def heapUsage = (totalUsed / totalMax) * 100;
        if (heapUsage > alertThreshold) {
          targetAlerts.add([
            'host.name': docSource.getOrDefault('host.name', 'unknown_host'),
            'service.name': docSource.getOrDefault('service.name', 'unknown_service'),
            'heap_usage_percent': Math.round(heapUsage * 100) / 100,
            'heap_used_bytes': totalUsed,
            'heap_max_bytes': totalMax
          ]);
        }
      }
      return ['matched_alerts': targetAlerts];
    """
  }
}

condition 判断片段

"condition": {
  "script": {
    "lang": "painless",
    "source": "return ctx.payload.matched_alerts.size() > 0;"
  }
}

action部分直接引用ctx.payload.matched_alerts里的字段做告警模板渲染即可。

Painless脚本调试方法

无需第三方工具,用Elastic原生能力即可精确定位错误:

  • 用Kibana开发工具的Painless执行接口单独测试脚本,指定watcher_transform上下文,传入查询返回的样例文档作为测试输入,接口会返回精确到行号的编译错误信息,不会出现无详情报错。测试请求模板:
POST _scripts/painless/_execute
{
  "script": {
    "lang": "painless",
    "source": "粘贴待测试的Painless脚本内容"
  },
  "context": "watcher_transform",
  "context_setup": {
    "payload": {
      "hits": {
        "hits": [
          // 粘贴实际查询返回的样例文档作为测试输入
          {
            "_source": {
              "memory_max_g1_survivor_space": 1073741824,
              "memory_max_g1_eden_space": 4294967296,
              "memory_max_g1_old_gen": 8589934592,
              "memory_used_g1_survivor_space": 987842478,
              "memory_used_g1_eden_space": 4127195136,
              "memory_used_g1_old_gen": 8053063680,
              "host.name": "prod-app-03",
              "service.name": "payment-service"
            }
          }
        ]
      }
    }
  }
}
  • 调试阶段可在脚本返回结果中加入中间计算值(比如totalUsed、totalMax),执行后即可直接查看每一步运算结果是否符合预期,无需每次模拟运行完整Watcher流程。脚本验证通过后再粘回Watcher配置即可。

内容的提问来源于stack exchange,提问作者Abo1787

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:37:03