如何将日志的ctx.payload.hits.total及错误消息传入Webhook Watcher转换脚本
问题描述
我有一个运行正常的Webhook Watcher,当日志中出现"Error"字样时会自动创建OTRS工单,当前配置如下:
{ "trigger": { "schedule": { "interval": "1m" } }, "input": { "search": { "request": { "search_type": "query_then_fetch", "indices": [ "*" ], "rest_total_hits_as_int": true, "body": { "query": { "bool": { "must": [ { "query_string": { "query": "Error" } }, { "range": { "@timestamp": { "gte": "now-1m" } } } ] } } } } } }, "condition": { "compare": { "ctx.payload.hits.total": { "gte": 1 } } }, "actions": { "create_otrs": { "transform": { "script": { "source": "return ['Ticket':['Queue':'Engineering Team','Priority':'P3','CustomerUser':'root','Title':'RESTCreateTest','State':'new','Type':'Incident'],'Article':['ContentType':'text/plain;charset=utf8','Subject':'RestCreateTest','Body':'This is only a test']]", "lang": "painless" } }, "webhook": { "scheme": "http", "host": "myotrs.com", "port": 80, "method": "post", "path": "/otrs/GenericTicketConnectorREST/User=<User>&Pass=<Password>", }, "headers": {}, "body": "{{#toJson}}ctx.payload{{/toJson}}" } } } }
目前工单内容固定为This is only a test,我希望将日志中的具体错误消息以及ctx.payload.hits.total(错误数量)传入工单内容中,请问如何在转换脚本中引用这些变量?
附日志文档示例:
{ "_index": ".ds-logs-elastic_agent.filebeat-default", "_source": { "input_source": "https://ser.example.com:80/export", "agent": { "name": "syslog01", "id": "5836558b-b17d-445e", "type": "filebeat", "ephemeral_id": "36bdfeca-3c60", "version": "8.3.3" }, "service.name": "filebeat", "log": { "file": { "path": "/opt/Elastic/Agent/data/elastic-agent-0ffbed/logs/default/filebeat-20230127-12.ndjson" }, "offset": 248078415 }, "elastic_agent": { "id": "5836558b-b17d", "version": "8.3.3", "snapshot": false }, "message": "\"\"\"Error while processing http request: failed to execute rf.collectResponse: failed to execute http client.Do: failed to execute http client.Do: Post \"https://ser.example.com:80/export\": POST https://ser.example.com:80/export giving up after 6 attempts\"\"\"", "log.logger": "input.httpjson-cursor", "input": { "type": "filestream" }, "log.origin": { "file.line": 128, "file.name": "httpjson/input.go" }, "@timestamp": "2023-01-27T14:44:42.790Z", "ecs": { "version": "8.0.0" }, "data_stream": { "namespace": "default", "type": "logs", "dataset": "elastic_agent.filebeat" }, "host": { "hostname": "syslog01", "os": { "kernel": "3.10.25-gentoo", "name": "Gentoo", "type": "linux", "family": "", "version": "", "platform": "gentoo" }, "containerized": false, "log.level": "error", "input_url": "https://ser.example.com:8089/export", "id": "httpjson-system.security-ba2ec41b-457b-442a", "event": { "agent_id_status": "verified", "ingested": "2023-01-27T14:44:58Z", "dataset": "elastic_agent.filebeat" } }, "_id": "pCWw84UB8FDLddfs", "_score": 2.2840834 } }
解决方案
修改transform中的Painless脚本,直接从ctx.payload提取所需数据,同时修正原配置的语法错误(webhook部分多余逗号),以下是完整修改后的配置:
{ "trigger": { "schedule": { "interval": "1m" } }, "input": { "search": { "request": { "search_type": "query_then_fetch", "indices": [ "*" ], "rest_total_hits_as_int": true, "body": { "query": { "bool": { "must": [ { "query_string": { "query": "Error" } }, { "range": { "@timestamp": { "gte": "now-1m" } } } ] } } } } } }, "condition": { "compare": { "ctx.payload.hits.total": { "gte": 1 } } }, "actions": { "create_otrs": { "transform": { "script": { "source": """ // 获取错误总数 int errorCount = ctx.payload.hits.total; // 拼接所有错误消息 StringBuilder errorMessages = new StringBuilder(); for (def hit : ctx.payload.hits.hits) { errorMessages.append("- ").append(hit._source.message).append("\\n\\n"); } // 构建工单内容 return [ 'Ticket': [ 'Queue': 'Engineering Team', 'Priority': 'P3', 'CustomerUser': 'root', 'Title': '系统错误告警 - 共发现' + errorCount + '条错误', 'State': 'new', 'Type': 'Incident' ], 'Article': [ 'ContentType': 'text/plain;charset=utf8', 'Subject': '系统错误告警', 'Body': '在过去1分钟内共发现' + errorCount + '条错误日志,详情如下:\\n\\n' + errorMessages.toString() ] ]; """, "lang": "painless" } }, "webhook": { "scheme": "http", "host": "myotrs.com", "port": 80, "method": "post", "path": "/otrs/GenericTicketConnectorREST/User=<User>&Pass=<Password>", "headers": {}, "body": "{{#toJson}}ctx.payload{{/toJson}}" } } } }
关键修改说明
- 错误数量获取:直接通过
ctx.payload.hits.total拿到本次查询到的错误日志总数,用于工单标题和内容。 - 错误消息提取:遍历
ctx.payload.hits.hits数组,每个元素的_source.message字段就是日志中的错误详情,将所有消息拼接成列表。 - 工单内容动态生成:将错误数量和消息插入到工单的Title和Body中,替换原来的固定文本。
- 语法修正:移除原配置中
webhook.path后面的多余逗号,避免JSON解析错误。
内容的提问来源于stack exchange,提问作者mrin9san
相关产品推荐
相关产品推荐

