解析 Nginx 日志时的 Logstash _grokparsefailure

Posted

技术标签:

【中文标题】解析 Nginx 日志时的 Logstash _grokparsefailure【英文标题】:Logstash _grokparsefailure when parsing Nginx logs 【发布时间】:2017-07-07 14:52:10 【问题描述】:

我正在尝试使用 Logstash 解析 nginx 日志,一切看起来都很好,除了使用包含 Nginx $remote_user 的行获取此 _grokparsefailure 标记。当 $remote_user 为 '-'(未指定 $remote_user 时的默认值)时,Logstash 会完成这项工作,但使用像 user@gmail.com 这样的真正 $remote_user 会失败并放置一个 _grokparsefailure 标签:

127.0.0.1 - - [17/Feb/2017:23:14:08 +0100] "GET /favicon.ico HTTP/1.1" 302 169 "http://training-hub.tn/trainer/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, 像 Gecko) Chrome/56.0.2924.87 Safari/537.36"

=====> 工作正常

127.0.0.1 - jemlifathi@gmail.com [17/Feb/2017:23:14:07 +0100] “GET /trainer/templates/home.tmpl.html HTTP/1.1”304 0 "http://training-hub.tn/trainer/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36(KHTML,像 Gecko)Chrome/56.0.2924.87 Safari/537.36"

=====>_grokparsefailure 标签和解析日志行失败

我正在使用这个配置文件:

input      
    file       
        path => "/home/dev/node/training-hub/logs/access_log"       
        start_position => "beginning"       
        sincedb_path => "/dev/null"
        ignore_older => 0
        type => "logs"  
    


filter     
    if[type] == "logs"         
        mutate             
             gsub => ["message", "::ffff:", ""]         
               
        grok           
             match=> [
               "message" , "%COMBINEDAPACHELOG+%GREEDYDATA:extra_fields",
               "message" , "%COMMONAPACHELOG+%GREEDYDATA:extra_fields"
             ]
             overwrite=> [ "message" ]
        

        mutate 
          convert=> ["response", "integer"]
          convert=> ["bytes", "integer"]
          convert=> ["responsetime", "float"]
        
        geoip 
          source => "clientip"
          target => "geoip"
          database => "/etc/logstash/GeoLite2-City.mmdb"
          add_field => [ "[geoip][coordinates]", "%[geoip][longitude]" ]
          add_field => [ "[geoip][coordinates]", "%[geoip][latitude]"  ]
        
        mutate 
          convert => [ "[geoip][coordinates]", "float"]
        

        date 
          match=> [ "timestamp", "dd/MMM/YYYY:HH:mm:ss Z" ]
          remove_field=> [ "timestamp" ]
        

        useragent 
          source=> "agent"
           
      
 

output     elasticsearch          hosts => "localhost:9200"    

【问题讨论】:

【参考方案1】:

在使用许多值测试输出后,我意识到 Logstash 无法解析包含此类 $remote_user 的日志行,因为它不是有效的用户名(电子邮件地址),所以我添加了一个 mutate gsub 过滤器以删除 @并且邮件地址的其余部分具有有效的$remote_user

gsub => ["消息", "@(?:(?:a-z0-9?.)+a-z0-9?|[(?:(?:25[0-5]|2[0-4][0-9]| [01]?[0-9][0-9]?).)3(?:25[0-5]|2[0-4][0-9]|[01]?[0- 9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\ x53-\x7f]|\[\x01-\x09\x0b\x0c\x0e-\x7f])+)]) [", " ["]

现在,它工作正常

【讨论】:

以上是关于解析 Nginx 日志时的 Logstash _grokparsefailure的主要内容,如果未能解决你的问题,请参考以下文章

Logstash收集nginx日志之使用grok过滤插件解析日志

Logstash收集nginx日志之使用grok过滤插件解析日志

Logstash解析Nginx访问日志

logstash收集nginx访问日志

Logstash:日志解析的 Grok 模式示例

Logstash整合zabbix 过滤Nginx 错误日志并进行报警