当前位置首页 > Nginx知识

Logstash使用grok过滤nginx日志

阅读次数:324 次  来源:admin  发布时间:

在生产环境中,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"'

ginx也可以添加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-patter

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的日志输出到不同的索引。

input {
    beats {
            port => 5044
    }
}

filter {
    if "www.xxx.com" in [tags] {
        grok {
                match => { "message" => "%{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}|-)\""}
        }
        mutate {
                convert => ["status","integer"]
                convert => ["body_bytes_sent","integer"]
                convert => ["request_time","float"]
        }
        geoip {
                source=>"remote_addr"
        }
        date {
                match => [ "timestamp","dd/MMM/YYYY:HH:mm:ss Z"]
        }
        useragent {
                source=>"http_user_agent"
        }
}
    
}

output {
if "www.xxx.com" in [tags] {
                elasticsearch {
                       hosts => ["10.1.128.101:9200"]
                       index => "www.xxx.com_10.1.144.60"
                       user => 'elastic'
                       password => '123456'
                      }
}

        stdout { codec => rubydebug }
}
上一篇:ubuntu切换工作区域
下一篇:VirtualBox内刚刚安装完Debian9系统,也无法设置共享文件夹。解决的方法就是安装VirtualBox客户端增强包。