Logstash使用grok过滤nginx日志
在生产环境中,nginx日志格式往往使用的是自定义的格式,我们需要把logstash中的message结构化后再存储,方便kibana的搜索和统计,因此需要对message进行解析。
本文采用grok过滤器,使用match正则表达式解析,根据自己的log_format定制。
1、nginx日志格式
log_format配置如下:
log_format main '$remote_addr $remote_user [$time_local] $http_host $request_method $request_uri ' '$status $body_bytes_sent $request_time "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for "$http_cookie"'
nginx也可以添加json日志格式
# vim /usr/local/nginx/conf/nginx.conf log_format json '{"@timestamp":"$time_iso8601",' '"host":"$server_addr",' '"clientip":"$remote_addr",' '"remote_user":"$remote_user",' '"request":"$request",' '"http_user_agent":"$http_user_agent",' '"size":$body_bytes_sent,' '"responsetime":$request_time,' '"upstreamtime":"$upstream_response_time",' '"upstreamhost":"$upstream_addr",' '"http_host":"$host",' '"url":"$uri",' '"domain":"$host",' '"xff":"$http_x_forwarded_for",' '"referer":"$http_referer",' '"status":"$status"}'; access_log /var/log/nginx/access.log json;
对应的日志如下:
183.56.162.88 - [21/Dec/2017:10:36:29 +0800] wxself.gtafe.com GET /Home/Index/?returnUrl=/pages/index.html&code=G28ea0iAaAmxsFcAcy1y64fIP9I07SUgOEopckpsZF4&state=sure 302 134 0.229 "-" "Mozilla/5.0 (Linux; Android 7.0; BLN-AL40 Build/HONORBLN-AL40; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043613 Safari/537.36 wxwork/2.4.1 MicroMessenger/6.3.22 NetType/WIFI Language/zh" - "ASP.NET_SessionId=ci1ivt21p2zzfsaisode3xvj"
2、编写正则表达式
logstash中默认存在一部分正则让我们来使用,可以访问Grok Debugger来查看,可以在 $logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.0/patterns/ 目录里面查看。
基本定义在grok-patterns中,我们可以使用其中的正则,当然并不是所有的都适合nginx字段,这时就需要我们自定义正则,然后通过指定patterns_dir来调用。
同时在写正则的时候可以使用Grok Debugger或者Grok Comstructor工具来帮助我们更快的调试。在不知道如何使用logstash中的正则的时候也可使用Grok Debugger的Descover来自动匹配。
Github中也有相关的语法说明:
https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/grok-patterns
https://github.com/kkos/oniguruma/blob/master/doc/RE
通过log_format来匹配对应的正则如下:
%{IP:remote_addr} (?:%{DATA:remote_user}|-) \[%{HTTPDATE:timestamp}\] %{IPORHOST:http_host} %{DATA:request_method} %{DATA:request_uri} %{NUMBER:status} (?:%{NUMBER:body_bytes_sent}|-) (?:%{DATA:request_time}|-) \"(?:%{DATA:http_referer}|-)\" \"%{DATA:http_user_agent}\" (?:%{DATA:http_x_forwarded_for}|-) \"(?:%{DATA:http_cookie}|-)\"
message是每段读进来的日志,IPORHOST、USERNAME、HTTPDATE等都是patterns/grok-patterns中定义好的正则格式名称,对照日志进行编写。
grok pattren的语法为:%{SYNTAX:semantic},":" 前面是grok-pattrens中定义的变量,后面可以自定义变量的名称。(?:%{SYNTAX:semantic}|-)这种形式是条件判断。
如果有双引号""或者中括号[],需要加 进行转义。
3、Filebeat配置文件
修改filebeat的配置文件。如果同一台机器上要收集多个日志文件,而且每个日志要输出到不同的索引,那么可以把每个prospector单独定义一个tags,然后在logstash上通过 if 判断输出到不同的索引。
- type: log enabled: true paths: - /gta/nginx_log/www.xxx.com.log tags: ["www.xxx.com"] - type: log enabled: true paths: - /gta/nginx_log/www.yyy.com.log tags: ["www.yyy.com"]
4、编写logstash pipeline配置文件
这里通过 if 判断将不同type的日志输出到不同的索引。