1

我正在尝试用 grok 解析日志文件。我使用的配置允许我解析单行事件,但如果是多行的(使用 java 堆栈跟踪)则不能。

#what i get on KIBANA for a single line:
{
  "_index": "logstash-2015.02.05",
  "_type": "logs",
  "_id": "mluzA57TnCpH-XBRbeg",
  "_score": null,
  "_source": {
    "message": " -  2014-01-14 11:09:35,962 [main] INFO  (api.batch.ThreadPoolWorker)   user.country=US",
    "@version": "1",
    "@timestamp": "2015-02-05T09:38:21.310Z",
    "path": "/root/test2.log",
    "time": "2014-01-14 11:09:35,962",
    "main": "main",
    "loglevel": "INFO",
    "class": "api.batch.ThreadPoolWorker",
    "mydata": "  user.country=US"
  },
  "sort": [
    1423129101310,
    1423129101310
  ]
}

#what i get for a multiline with Stack trace:
  {
  "_index": "logstash-2015.02.05",
  "_type": "logs",
  "_id": "9G6LsSO-aSpsas_jOw",
  "_score": null,
  "_source": {
    "message": "\tat oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:20)",
    "@version": "1",
    "@timestamp": "2015-02-05T09:38:21.380Z",
    "path": "/root/test2.log",
    "tags": [
      "_grokparsefailure"
    ]
  },
  "sort": [
    1423129101380,
    1423129101380
  ]
}
input {
  file {
    path => "/root/test2.log"
    start_position => "beginning"
    codec => multiline {
      pattern => "^ -  %{TIMESTAMP_ISO8601} "
      negate => true
      what => "previous"
    }
  }
}

filter {
 grok {
    match => [ "message", " -%{SPACE}%{SPACE}%{TIMESTAMP_ISO8601:time} \[%{WORD:main}\] %{LOGLEVEL:loglevel}%{SPACE}%{SPACE}\(%{JAVACLASS:class}\) %{GREEDYDATA:mydata} %{JAVASTACKTRACEPART}"]
  }
    date {
    match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
}

output {
  elasticsearch {
    host => "194.3.227.23"
  }
 # stdout { codec => rubydebug}
}

谁能告诉我我的配置文件做错了什么?谢谢。这是我的日志文件示例: - 2014-01-14 11:09:36,447 [main] INFO (support.context.ContextFactory) 创建默认上下文 - 2014-01-14 11:09:38,623 [main] 错误(支持.context.ContextFactory) 使用用户 cisuser 和驱动程序 oracle.jdbc.driver.OracleDriver java.sql.SQLException: ORA-28001: 密码已过期oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70) 在 oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:131) **

*> 编辑:这是我正在使用的最新配置

https://gist.github.com/anonymous/9afe80ad604f9a3d3c00#file-output-L1 *

**

4

1 回答 1

6

第一点,使用文件输入重复测试时,一定要使用sincedb_path => "/dev/null"确保从文件开头读取。

关于多行,您的问题内容或多行模式一定有问题,因为没有一个事件具有由多行编解码器添加的多行标记或在聚合行时过滤器。您的消息字段应包含由换行符\n分隔的所有行(在我的情况下为 \r\n 在 Windows 上)。这是您的输入配置的预期输出

{
"@timestamp" => "2015-02-10T11:03:33.298Z",
   "message" => " -  2014-01-14 11:09:35,962 [main] INFO  (api.batch.ThreadPoolWorker)   user.country=US\r\n\tat oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:20\r",
  "@version" => "1",
      "tags" => [
    [0] "multiline"
],
      "host" => "localhost",
      "path" => "/root/test.file"
}

关于 grok,当你想匹配一个多行字符串时,你应该使用这样的模式。

filter {
  grok {
    match => {"message" => [
      "(?m)^ -%{SPACE}%{TIMESTAMP_ISO8601:time} \[%{WORD:main}\] %   {LOGLEVEL:loglevel}%{SPACE}\(%{JAVACLASS:class}\) %{DATA:mydata}\n%{GREEDYDATA:stack}",
      "^ -%{SPACE}%{TIMESTAMP_ISO8601:time} \[%{WORD:main}\] %{LOGLEVEL:loglevel}%{SPACE}\(%{JAVACLASS:class}\) %{GREEDYDATA:mydata}"]
}

} }

(?m)前缀指示正则表达式引擎进行多行匹配。然后你会得到一个像

{
"@timestamp" => "2015-02-10T10:47:20.078Z",
   "message" => " -  2014-01-14 11:09:35,962 [main] INFO  (api.batch.ThreadPoolWorker)   user.country=US\r\n\tat oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:20\r",
  "@version" => "1",
      "tags" => [
    [0] "multiline"
],
      "host" => "localhost",
      "path" => "/root/test.file",
      "time" => "2014-01-14 11:09:35,962",
      "main" => "main",
  "loglevel" => "INFO",
     "class" => "api.batch.ThreadPoolWorker",
    "mydata" => "  user.country=US\r",
     "stack" => "\tat oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:20\r"
}

您可以使用此在线工具http://grokconstructor.appspot.com/do/match构建和验证您的多行模式

最后一个警告,如果您在路径设置中使用列表或通配符,则使用多行编解码器的 Logstash 文件输入当前存在一个错误,该错误会混淆来自多个文件的内容。唯一的解决方法是使用多行过滤器

高温高压

编辑:我专注于多行字符串,您需要为非单行字符串添加类似的模式

于 2015-02-10T11:16:49.273 回答