【问题标题】:Parse Apache2 Error logs with Grok for Logstash使用 Grok for Logstash 解析 Apache2 错误日志
【发布时间】: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'
        }
}

【问题讨论】:

    标签: apache apache2 logstash logstash-grok


    【解决方案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
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-19
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多