使用 Grok for Logstash 解析 Apache2 错误日志

Posted

技术标签:

【中文标题】使用 Grok for Logstash 解析 Apache2 错误日志【英文标题】:Parse Apache2 Error logs with Grok for Logstash 【发布时间】:2013-06-24 06:32:12 【问题描述】:

我正在尝试解析我的 apache2 错误日志,但遇到了一些麻烦。它似乎与过滤器不匹配。我很确定时间戳是错误的,但我不确定,我真的找不到任何文档来解决这个问题。另外,有没有办法将fields.errmsg 中的内容提供给我@message

日志

[Wed Jun 26 22:13:22 2013] [error] [client 10.10.10.100] php Fatal error:  Uncaught exception '\Foo\Bar'

发件人配置

input 
        file 
                'path' => '/var/log/apache2/*-error.log'
                'type' => 'apache-error'
        



filter 
        grok 
                type => "apache-error"
                pattern => "\[%HTTPDATE:timestamp\] \[%WORD:class\] \[%WORD:originator %IP:clientip\] %GREEDYDATA:errmsg"
        



output 
        stdout 
        redis 
                'data_type' => 'list'
                'host' => 'logstash.server.net'
                'key' => 'logstash'
        

【问题讨论】:

【参考方案1】:

不适合我:

EEE MMM dd HH:mm:ss yyyy

为我工作(Apache 2.4):

EEE MMM dd HH:mm:ss.SSSSSS yyyy

【讨论】:

【参考方案2】:

我们的错误日志看起来有些不同:

[Tue Dec 08 12:30:35.997887 2015] [ssl:info] [pid 1178:tid 1072] (70014)End of file found: [client 10.129.24.77:49987] AH01991: SSL input filter read failed.

但我发现了一个完美的预定义模式:

HTTPD24_ERRORLOG

在Logstash source看到这个

【讨论】:

这是更好的方法 值得注意的是,HTTPD_ERRORLOG 将适用于 2.0 和 2.4 格式,因此如果您将带有 ansible 的 logstash 发送到异构环境(如我),那么您可能应该使用包罗万象的版本两者都适用。 @Robbie 能否请您展示一下您的过滤器配置,您是如何使用它的?【参考方案3】:

喂!

我知道我参加聚会有点晚了,但它开始了!

我在系统上创建了一个/etc/logstash/patterns.d/ 目录,并在其中创建了一个名为apache-error 的文件,其中包含:

APACHE_ERROR_TIME %DAY %MONTH %MONTHDAY %TIME %YEAR
APACHE_ERROR_LOG \[%APACHE_ERROR_TIME:timestamp\] \[%LOGLEVEL:loglevel\] (?:\[client %IPORHOST:clientip\] )0,1%GREEDYDATA:errormsg

/etc/logstash/patterns.d/ 将在logstash 配置中引用如下:

grok 
  patterns_dir => [ "/etc/logstash/patterns.d" ]
  match => [ "message", "%APACHE_ERROR_LOG" ]

您可以在 Grok Debugger 进行测试,就像 Adam 在他的评论中提到的那样。似乎与您发送的示例日志条目一起工作得很好。我一直在与我的一位客户合作得很好。

上面的模式将最终消息放在errormsg 字段中。所以我只删除了message 字段。

这是我目前在我的 logstash 配置中使用的:

filter 
  if [type] == "apache_error_log" 

    grok 
      patterns_dir => [ "/etc/logstash/patterns.d" ]
      match => [ "message", "%APACHE_ERROR_LOG" ]
    

    if !("_grokparsefailure" in [tags]) 

      mutate 
        remove_field => [ "message" ]
        add_field =>  ["timestamp_submitted", "%@timestamp"]
      

      date 
        # Try to pull the timestamp from the 'timestamp' field (parsed above with
        # grok). The apache time format looks like: "18/Aug/2011:05:44:34 -0700"
        #                        Sat Feb 08 06:31:09 2014
        match => [ "timestamp", "EEE MMM dd HH:mm:ss yyyy" ]
        remove_field => [ "timestamp" ]
      

      geoip 
        source => "clientip"
      
    
  

请注意,我使用的是apache_error_log,而不是apache-error

试一试。我很想知道这是否适用于您和其他人!

干杯!

【讨论】:

谢谢!一个快速说明:我正在使用 GELF 输出插件将日志发送到 Graylog2。它要求消息字段不能丢失,所以我不得不相应地调整模式。 我猜日志错误日志格式自这篇文章以来发生了变化,但如果它对某人有所帮助,我将 APACHE_ERROR_LOG 模式更新为如下所示:APACHE_ERROR_LOG \[%APACHE_ERROR_TIME:timestamp\] \[:%LOGLEVEL:loglevel\] \[pid %NUMBER:pid\] (?:\[client %IPORHOST:clientip:%POSINT:port\] )0,1%GREEDYDATA:errormsg 似乎对我不起作用.. [Sun Oct 11 23:38:09.105800 2015] [mpm_event:notice] [pid 21264:tid 140035264497536] AH00489: Apache/2.4.7 (Ubuntu) configured -- resuming normal operations 这个对我有用APACHE_ERROR_LOG \[%APACHE_ERROR_TIME:timestamp\] \[%WORD:source:%LOGLEVEL:loglevel\] \[pid %NUMBER:pid:tid %NUMBER:tid\] (?:\[client %IPORHOST:clientip:%POSINT:port\] )0,1%GREEDYDATA:errormsg 如果其他人也遇到这种情况,我需要在其中添加一个sslAPACHE_ERROR_TIME %DAY %MONTH %MONTHDAY %TIME %YEAR APACHE_ERROR_LOG \[%APACHE_ERROR_TIME:timestamp\] \[ssl:%LOGLEVEL:loglevel\] \[pid %NUMBER:pid\] (?:\[client %IPORHOST:clientip:%POSINT:port\] )0,1%GREEDYDATA:errormsg【参考方案4】:

Logstash 有一个内置的 apache 日志解析器。

这是一个例子......

grok 
   type    => 'company'
   pattern => ["%COMBINEDAPACHELOG"]
   add_tag => "apache"

作为参考,可以查看Logstash的docs

【讨论】:

感谢您指出这一点 - 没有意识到这一点。在将 Grok 模式放入配置文件之前,您应该使用 GrokDebugger 检查您的 Grok 模式。这是不言自明的。 grokdebug.herokuapp.com 不错。这有帮助。知道如何获得它,所以@message@fields.message 相同吗? 我不确定它是如何工作的。我知道您可以使用replace => [ "@message", "%message_remainder" ] 之类的东西来更新字段的值,但我不知道如何将@fields 添加到新的message 变量中。出于兴趣,你会用它做什么?我想不出一个用例。 我不希望整个日志行都是@message,我只想要实际的错误 消息本身将始终存储在@message 中,除非您使用replace 函数更改它。我建议您继续前进的道路(来自问题中的 sn-p)。最好创建一个新变量errmsg,然后访问错误消息,只需查看@fields.errmsg

以上是关于使用 Grok for Logstash 解析 Apache2 错误日志的主要内容,如果未能解决你的问题,请参考以下文章

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

Logstash使用grok解析IIS日志

Logstash使用grok解析IIS日志

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

在logstash中使用grok模式解析我的json文件?

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