与典型的单行日志不同,java异常日志有多行,而且他们并不总是完全统一的,因此,大多数grok规则都无法开箱即用,在大多数情况下,需要特殊的配置才能正确搜集异常日志。

匹配多行日志

我们根据日期来匹配多行日期,也就是如果匹配到当前行不是以日期开头的,就将改行归类到前一个日期行

之前看到其他文章都是根据匹配空格来匹配多行,但是有的java日常日志会输出Cause by,Cause by那行并不是以空格开始的

2021-03-25 05:10:48,019 [http-nio-8080-exec-12] ERROR /api/getIndex.jsp - 系统出现异常
sun.reflect.GeneratedMethodAccessor1281: 异常
at sun.reflect.GeneratedMethodAccessor1281.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
2021-03-25 05:10:58,523 [http-nio-8080-exec-35] INFO com.up.cs.util.filterutil.UrlFilter - 拦截请求

logstash匹配多行

input {
file {
path => "/var/log/test.log"
start_position => "beginning"
stat_interval => "2"
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601}"
negate => true
what => "previous"
}
}
}

grok解析日志

%{TIMESTAMP_ISO8601:timestamp} 匹配日期时间

%{SYSLOG5424SD:thread} 匹配线程

%{LOGLEVEL:severity} 匹配日志级别

(?m) %{GREEDYDATA:message} 匹配后面所有内容(包含异常的多行日志)

(?m)%{TIMESTAMP_ISO8601:timestamp} %{SYSLOG5424SD:thread} %{LOGLEVEL:severity} %{GREEDYDATA:message}

日期处理

我们需要将日志输出中日志作为我们后面显示在kibana中的指标,并不能以logstash采集的时间作为日志时间指标

date {
match => ["timestamp" , "yyyy-MM-dd HH:mm:ss"]
}