• nginx 之 grok 过滤


    简介

      前面我们的nginx日志编码使用的json,logstash直接输入预定义好的 JSON 数据,这样就可以省略掉 filter/grok 配置,但是在我们的生产环境中,日志格式往往使用的是普通的格式,因此就不得不使用logstash的filter/grok进行过滤,下面我们就来讲下如何配置。

    配置

    1.nginx日志格式 
    为了帮助我们有效的理解grok的正则表达式,因此在这我们将日志格式定义的复杂一些,基本是各个使用的字段都涉及到了,google上好多都是套用的默认格式,我费好大劲才弄明白。

    log_format main '$time_local - $upstream_addr $server_addr:$server_port '
                    '$request_method $uri $args '
                    '- $remote_addr $server_protocol [$http_user_agent] [$http_cookie] $http_referer '
                    '$host $status 0 0 $bytes_sent $request_length 0'
                    '"$upstream_cache_status" $request_time $upstream_response_time';
    • 1
    • 2
    • 3
    • 4
    • 5

    对应的日志如下:

    08/Jan/2016:08:27:43 +0800 - 10.10.6.212:8088 10.10.6.110:80 GET /vvv/test/stat/index proptype=11&level=2&srtype=2&city=dz&region=XJ&begindate=2016-01-08&enddate=2016-01-08&apiKey=c2c959b203d669a9a21861379cb4523c&test=2 - 10.10.6.10 HTTP/1.1 [Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36] [JSESSIONID=kq3v6xi2b74j1a9yxvfvcq131] http://10.10.6.110/test www.test.com 200 0 0 485 209 0"-" 1.642 1.642
    • 1

    2.编写正则表达式 
    logstash中默认存在一部分正则表达式来让我们套用,在如下的文件中我们可以看到:

    ls /usr/local/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.2/patterns
    aws  bacula  bro  exim  firewalls  grok-patterns  haproxy  java  junos  linux-syslog  mcollective  mcollective-patterns  mongodb  nagios  postgresql  rails  redis  ruby
    
    • 1
    • 2
    • 3

    其中最基本的定义是在grok-patterns中,但是某些正则不适合我们的nginx字段,此时就需要我们来自定义,然后grok通过patterns_dir来调用即可。 
    另外,我们可以通过http://grokconstructor.appspot.com/do/matchhttp://grokdebug.herokuapp.com/这两个站点来查看我们的正则是否正确。(ps:个人觉得第一个好用)

    下面我们来通过分解日志中的各个字段来一一对应下正则:

    nginx日志字段定义nginx访问字段正则表达式
    $time_local 08/Jan/2016:08:27:43 +0800 %{HTTPDATE:timestamp}
    - - -
    $upstream_addr 10.10.6.212:8088 %{HOSTPORT:upstream}
    serveraddr:server_port 10.10.6.110:80 %{HOSTPORT:request_server}
    $request_method GET %{WORD:request_method}
    $uri /vvv/test/stat/index %{URIPATH:uri}
    $args proptype=11&level=2&srtype=2&city=dz&region=XJ&begindate=2016-01-08&enddate=2016-01-08&apiKey=c2c959b203d669a9a21861379cb4523c&test=2 %{URIPARAM1:args}
    - - -
    $remote_addr 10.10.6.10 %{IP:clientip}
    $server_protocol HTTP/1.1 HTTP/%{NUMBER:httpversion}
    [$http_user_agent] [Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36] \ [%{GREEDYDATA:agent}\ ]
    [$http_cookie] [JSESSIONID=kq3v6xi2b74j1a9yxvfvcq131] \ [%{GREEDYDATA:cookie}\ ]
    $http_referer http://10.10.6.110/test (?:%{URI:referrer}|-)
    $host www.test.com %{HOSTNAME:domain}
    $status 200 %{NUMBER:status:int}
    0 0 0
    0 0 0
    $bytes_sent 485 %{NUMBER:body_sent:int}
    $request_length 209 %{NUMBER:request_length:int}
    0”$upstream_cache_status” 0”-“ 0\”-\”
    $request_time 1.642 %{NUMBER:request_time:float}
    $upstream_response_time 1.642 %{NUMBER:response_time:float}

    ok,我们nginx日志的所有字段都已经定义完毕,我们可以到http://grokconstructor.appspot.com/do/match看下是否有问题: 

    注意要点: 
    (1)上图中URIPARAM1 [A-Za-z0-9$.+!‘|(){},~@#%&/=:;_?-[]]是我们自定义的个一个正则,由%{URIPARAM1:args}调用, 
    它和默认正则库/usr/local/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.2/patterns/grok-patterns中的URIPARAM \?[A-Za-z0-9$.+!‘|(){},~@#%&/=:;_?-[]<>]是不一样的,可以看到默认的URIPARAM是以?开头,我们自定义的URIPARAM1而不是,也可通过https://github.com/elastic/logstash/blob/v1.4.2/patterns/grok-patterns查看(这个规则是更新的,可能由于版本的问题和你使用的不一样),正是由于这点差别导致我们在使用默认正则会出现“Longest prefix that matches”的提示,“after matche”会显示日志中未匹配的剩余内容,如下图:
     
    也就是说我们的匹配是异常的,一旦有这样的提示,就说明我们的正则有问题。

    (2)httpuseragenthttp_cookie字段使用http://grokdebug.herokuapp.com/patterns#中“nginx-access”生成的规则“%{QS:agent}”以及类似“%{QS:cookie}”也会出现“Longest prefix that matches”提示,因此这两个正则是不正确的,我就使用了%{GREEDYDATA:agent}和%{GREEDYDATA:cookie},在/usr/local/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.2/patterns/grok-patterns或https://github.com/elastic/logstash/blob/v1.4.2/patterns/grok-patterns我们可以查到“GREEDYDATA .*”,匹配的所有字符,注意和“QS %{QUOTEDSTRING}”的区别。 
    (3)?:%{URI:referrer}|-)正则表示如果$referer字段为空,则用-表示,若不为空则显示referer的内容,经测试如果直接设置成%{URI:referrer},过滤时当referer为空时,导致grokfailure,因此需要注意此字段的正则表达式。

    某些字段为“-”,可能导致grokfailure,此时我们可以通过(?:%{XX:XX}|-)的方式进行匹配,即为空时显示“-”。

    (4)可能你想知道所有的正则是如何定义的,我们可以查看https://github.com/kkos/oniguruma/blob/master/doc/RE 
    3.logstash调用 
    (1)在logstash中定义正则目录并定义规则

    mkdir -p /usr/local/logstash/patterns
    vim /usr/local/logstash/patterns/nginx
    URIPARAM1 [A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]]*
    NGINXACCESS %{HTTPDATE:timestamp} - %{HOSTPORT:upstream} %{HOSTPORT:request_server} %{WORD:request_method} %{URIPATH:uri} %{URIPARAM1:args} - %{IP:clientip} HTTP/%{NUMBER:httpversion} \[%{GREEDYDATA:agent}\] \[%{GREEDYDATA:cookie}\] %{URI:referer} %{HOSTNAME:host} %{NUMBER:status:int} 0 0 %{NUMBER:body_sent:int} %{NUMBER:request_length:int} 0\"-\" %{NUMBER:request_time:float} %{NUMBER:response_time:float}
    • 1
    • 2
    • 3
    • 4

    其中URIPARAM1是我们自定义的部分,而NGINXACCESS也是我们自定的正则,其中又调用了URIPARAM1。

    (2)配置文件logstash.conf

    input {
            file {
                    path => "/data/nginx/logs/api.creprice.log"
                    type => "nginx-access"
                    start_position => "beginning"
                    sincedb_path => "/usr/local/logstash/sincedb"
            }
    }
    filter {
            if [type] == "nginx-access" {
                    grok {
                            patterns_dir => "/usr/local/logstash/patterns"
                            match => {
                                    "message" => "%{NGINXACCESS}"
                            }
                    }
                    date {
                            match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
                            }
            }
    }
    output {
            if [type] == "nginx-access" {
                    elasticsearch {
                            hosts => ["10.10.10.16:9200"]
                            manage_template => true
                            index => "logstash-nginx-access-%{+YYYY-MM}"
                    }
            }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    其中:patterns_dir定义的是我们自定义的正则存放目录

    (3)重启logstash,查看kibana,我们的字段就显示出来了,如果我们的字段前面是?,请刷新下我们的“Setting”——“indices”——“Index Patterns”——“logstash-nginx-access-%{+YYYY-MM}”即可。

    总结

    通过上面对正则的了解,即使是在复杂的日志,我们只要对应规则也可以一一解开,下面的工作就是让我们应用到生产环境吧。

  • 相关阅读:
    点击cell后 cell的背景不变,cell上的字体颜色发生改变的功能实现
    各种属性设置
    多列表 ,菜单
    正则表达式
    多个storyboard之间的跳转问题
    关于uicollectionview的个人学习
    uiscrollview的自动布局
    手动自动布局
    关于简单的跳转问题
    深入理解@class和#import的区别
  • 原文地址:https://www.cnblogs.com/lize3379/p/6118788.html
Copyright © 2020-2023  润新知