ElasticSearch Watcher 故障排除:illegal_argument_exception,原因:无关的 for 循环

ElasticSearch Watcher Troubleshooting : illegal_argument_exception, reson: Extraneous for loop

我的观察器运行良好并成功发出警报,但现在我遇到了麻烦。

为了实现一些更复杂的触发条件,我把我的watcher条件从compare改成了painless script,得到了一个illegal_argument_exception,reson是Extraneous for循环。 这是我的手表 json:

PUT /_xpack/watcher/watch/test11111
{
  "trigger": {
    "schedule": {
      "interval": "1m"
    }
  },
  "input": {
    "search": {
      "request": {
        "search_type": "query_then_fetch",
        "indices": [
          "auto-article-web-prod-*"
        ],
        "types": [],
        "body": {
          "size": 0,
          "query": {
            "bool": {
              "filter": [
                {
                  "range": {
                    "@timestamp": {
                      "from": "now-20m",
                      "to": "now"
                    }
                  }
                }
              ]
            }
          },
          "aggs": {
            "failed_api": {
              "terms": {
                "field": "log_content.apiName"
              }
            }
          }
        }
      }
    }
  },
  "condition" : {
      "script" : """
      for (bucket in ctx.payload.aggregations.failed_api.buckets) {
        String key = bucket.key;
        int value = bucket.doc_count;
        if(key == 'articlenumber'){
            return value >= 5;
        }
        else if(value >= 20){
            return true;
        }
        else{
            return false;
        }
    }
      """
    },
  "actions": {
    "my-logging-action": {
    ...
    }
  }
}

响应是:

{
  "error": {
    "root_cause": [
      {
        "type": "script_exception",
        "reason": "compile error",
        "script_stack": [
          "      for (bucket in ctx.payloa ...",
          "      ^---- HERE"
        ],
        "script": "      for (bucket in ctx.payload.aggregations.failed_api.buckets) {\n        String key = bucket.key;\n        int value = bucket.doc_count;\n        if(key == 'article'){\n            return value >= 5;\n        }\n        else if(value >= 20){\n            return true;\n        }\n        else{\n            return false;\n        }\n    }",
        "lang": "painless"
      }
    ],
    "type": "script_exception",
    "reason": "compile error",
    "script_stack": [
      "      for (bucket in ctx.payloa ...",
      "      ^---- HERE"
    ],
    "script": "      for (bucket in ctx.payload.aggregations.failed_api.buckets) {\n        String key = bucket.key;\n        int value = bucket.doc_count;\n        if(key == 'article'){\n            return value >= 5;\n        }\n        else if(value >= 20){\n            return true;\n        }\n        else{\n            return false;\n        }\n    }",
    "lang": "painless",
    "caused_by": {
      "type": "illegal_argument_exception",
      "reason": "Extraneous for loop."
    }
  },
  "status": 500
}

根据我的输入,查询结果如下:

{
  "took": 120,
  "timed_out": false,
  "_shards": {
    "total": 139,
    "successful": 139,
    "skipped": 133,
    "failed": 0
  },
  "hits": {
    "total": 70,
    "max_score": 0,
    "hits": [
      ...
    ]
  },
  "aggregations": {
    "failed_api": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "articlenumber",
          "doc_count": 38
        },
        {
          "key": "authorad",
          "doc_count": 15
        },
        {
          "key": "articlepv",
          "doc_count": 13
        },
        {
          "key": "authorarticlelist",
          "doc_count": 3
        },
        {
          "key": "author",
          "doc_count": 1
        }
      ]
    }
  }
}

我检查过 Elastic 的 documentation.but 没有得到任何有用的信息。如何在无痛脚本中编写正确的循环?有没有更具体的调试信息?

最后我发现我的脚本中有错误,它会 return 在第一个循环中,并且在我更改脚本后 watcher 工作正常。