Logstash Filter Grok语法问题:两种Log4j日志适配OpenSearch异常
Log2的Grok配置异常原因及修复方案
问题排查
针对Log2的Grok配置,核心存在2个匹配错误:
1. 时间格式与TIMESTAMP_ISO8601模式不兼容
Log2的时间格式为yyyyMMdd HH:mm:ss.SSS(例如20240520 14:30:45.123),但%{TIMESTAMP_ISO8601:date}仅支持标准ISO8601格式(如2024-05-20T14:30:45.123Z),导致时间字段无法被正确捕获。
2. date过滤器匹配规则错误
即使强行捕获了Log2的时间字符串,后续date { match => ["date", "ISO8601"] }指定的格式与Log2的时间格式完全不符,无法将其转换为OpenSearch所需的@timestamp字段。
修复后的配置
针对Log2的格式特性,需自定义时间匹配模式,并调整date过滤器的兼容规则:
filter { if [fields][index] == "log1"{ grok { match => { "message" => "%{TIMESTAMP_ISO8601:date} %{LOGLEVEL:logLevel} \[%{DATA:class}\] \[%{DATA:txIp}\] \[%{DATA:mbrNo}\] %{GREEDYDATA:message}" } } } else if [fields][index] == "log2" { grok { match => { # 自定义时间模式匹配yyyyMMdd HH:mm:ss.SSS格式 "message" => "\[%{LOGLEVEL:logLevel}\]\[%{DATA:date:yyyyMMdd HH:mm:ss.SSS}\]\[%{DATA:thread}\]%{DATA:class}.%{DATA:method}\(%{DATA:line}\) - %{DATA:reqCommand}\|%{DATA:svcTrId}\|%{GREEDYDATA:message}" } # 可选优化:如果method是纯单词、line是数字,可替换为更精确的匹配 # match => { # "message" => "\[%{LOGLEVEL:logLevel}\]\[%{DATA:date:yyyyMMdd HH:mm:ss.SSS}\]\[%{DATA:thread}\]%{DATA:class}.%{WORD:method}\(%{NUMBER:line:int}\) - %{DATA:reqCommand}\|%{DATA:svcTrId}\|%{GREEDYDATA:message}" # } } } date { match => ["date", "ISO8601", "yyyyMMdd HH:mm:ss.SSS"] # 同时兼容Log1和Log2的时间格式 target => "@timestamp" remove_field => ["date"] # 可选:移除原始date字段,避免冗余 } }
补充说明
- Log2中
%c{4}输出的类名(含多级包名)可通过%{DATA:class}正常匹配,若需更严格的类名匹配,可替换为%{WORD:class}(?:\.%{WORD:class})*。 - 将
line字段用%{NUMBER:line:int}匹配,可自动转为整数类型,方便后续在OpenSearch中做数值筛选。
内容的提问来源于stack exchange,提问作者neeson.lee
相关产品推荐
相关产品推荐

