简述
关于ELKStack日志收集Nginx日志,如果我们定义的Nginx格式使用JSON,那么Logstash可以非常轻松的按预定义好的JSON格式进行收集,这样就可以避免额外的 Filter/Grok 配置。但是如果在我们的生产环境中,Nginx日志格式在某些情况下并不是如此,那就不得不使用Logstash的Filter/Grok组件通过正则匹配过滤,下面我们就来演示下吧。
Nginx日志格式
为了帮助我们有效的理解grok的正则表达式,因此我特意将日志格式定义的复杂一些。
Google上好多案例都是套用的默认格式,为了便于大家以后更好的扩展使用,我在此并没有使用默认字段。
其对应的真实日志如下:
Logstash正则表达式
Logstash中默认已存在一部分正则表达式供我们使用,在以下路径中我们可以看到:
其中最基本的定义是在grok-patterns中,但是其中的正则搭配并不适合我们本次Nginx日志格式,因此我希望通过自定义的规则来实现格式匹配,然后使用Grok组件通过patterns_dir来调用即可。
另外,我们可以通过“”或“”这两个站点来查看我们的正则是否正确。
下面我们来通过分解日志中的各个字段来解析正则表达式:
正则表达式定义完毕后,我们可以到来验证。
「要点:」
1.上图中”URIPARAM1“ 是我们自定义的个一个正则,其规则为[A-Za-z0-9$.+!‘|(){},~@#%&/=:;_?-[]],由%{URIPARAM1:args}调用。它和默认URIPARAM规则是有区别的。如果你观察仔细的话,可以看到默认的“URIPARAM”是以?开头,而我们自定义的URIPARAM1不是。
注意:这个规则是更新的,可能由于版本的问题,将导致我们在使用默认正则时会出现“Longest prefix that matches”的提示,“after matche”会显示日志中未匹配的剩余内容。
2.http_user_agent和http_cookie字段使用“patterns#”中“nginx-access”生成的规则“%{QS:agent}”以及类似“%{QS:cookie}”也会出现“Longest prefix that matches”提示,因此这两个正则是不正确的。我们可以使用%{GREEDYDATA:agent}和%{GREEDYDATA:cookie}代替,而“GREEDYDATA .*”,是匹配的所有字符。注意其和“QS %{QUOTEDSTRING}”的区别。
3.?:%{URI:referrer}|-)正则表示如果$referer字段为空,则用"-"表示,若不为空则显示referer的内容。经测试如果直接设置成%{URI:referrer},过滤时当referer为空时,会导致grokfailure,因此需要注意此字段的正则表达式。
注意:某些字段为“-”时,可能会导致grokfailure,此时我们可以通过(?:%{XX:XX}|-)的方式进行匹配,即为空时显示“-”。
官方正则查询:
Logstash调用
「1.在logstash中定义正则目录并定义规则」
其中:
URIPARAM1是我们自定义的规则;
NGINXACCESS是我们整体自定义的规则,其中调用了URIPARAM1;
注意:若以上的日志如下
其中referrer字段为"
经过以上调整,正则就可以正确匹配了。
「2.配置文件logstash.conf」
其中:patterns_dir定义的是我们自定义的正则存放目录
「3.重启logstash」
查看kibana,字段就显示出来了。如果我们的字段前面是?,可以通过刷新下我们的“Setting”—“indices”—“Index Patterns”—“logstash-nginx-access-%{+YYYY-MM}”索引即可。
总结
经过以上对Grok正则的一番操作,以后即使我们面临更复杂的日志格式,只要对应规则从容不迫,相信我们都可以解决。但是希望大家指导,越复杂的正则匹配只会浪费服务器性能。因此当我们有海量日志的需求时,建议还是使用较容易解析的格式吧。