如何在AWS CloudWatch中创建过滤器检测非JSON格式日志事件?
筛选纯文本日志的过滤规则实现
核心思路
要筛选纯文本日志,核心是判断日志内容无法被解析为合法JSON——因为结构化日志是带message字段的合法JSON,而纯文本日志不满足JSON格式要求。优先使用日志系统自带的JSON解析失败检测,比正则匹配更可靠(JSON格式复杂,正则难以覆盖所有情况)。
各主流日志系统的实现规则
1. ELK Stack(Kibana/Logstash)
- Logstash 配置:
使用json过滤器标记解析失败的日志,再筛选带标记的条目:filter { json { source => "message" # 假设原始日志存储在message字段中 tag_on_failure => ["non_json_log"] # 解析失败时添加标签 } } output { # 仅输出带non_json_log标签的纯文本日志 if "non_json_log" in [tags] { elasticsearch { hosts => ["localhost:9200"] index => "plaintext-logs-%{+YYYY.MM.dd}" } } } - Kibana Discover 过滤:
直接筛选存在JSON解析错误的日志:json.parse_error:*
2. Grafana Loki(LogQL)
使用| json尝试解析日志,解析失败的日志会生成__error__字段,筛选该字段非空的条目:
{job="your-job-name"} | json | __error__ != ""
3. Splunk
用spath命令尝试解析原始日志,筛选解析失败的条目:
index=your_target_index | spath input=_raw | where isnull(_json)
(简单场景也可以用正则匹配非JSON格式,但可靠性较低):
index=your_target_index | regex _raw!="^\{.*\}$"
4. 通用正则方案(仅适合简单场景)
如果工具仅支持正则,可匹配不以{开头或不以}结尾的内容,但注意无法处理跨多行的JSON:
!^\{.*\}$
注意事项
- 优先选择日志系统自带的解析失败检测机制,避免正则匹配的局限性(比如嵌套JSON、转义字符、跨多行JSON等场景)。
- 部分系统中,纯文本日志不会被自动解析为JSON,可通过判断不存在JSON解析后的字段(如结构化日志特有的字段)辅助筛选。
内容的提问来源于stack exchange,提问作者Pouyan
相关产品推荐
相关产品推荐

