Logstash——multiline 插件,匹配多行日誌

本文內容

  • 測試數據
  • 字段屬性
  • 按多行解析運行時日誌
  • 把多行日誌解析到字段
  • 參考資料

在處理日誌時,除了訪問日誌外,還要處理運行時日誌,該日誌大都用程序寫的,好比 log4j。運行時日誌跟訪問日誌最大的不一樣是,運行時日誌是多行,也就是說,連續的多行才能表達一個意思。html

本文主要說明,如何用 multiline 出來運行日誌。正則表達式

若是能按多行處理,那麼把他們拆分到字段就很容易了。ruby

遷移到:http://www.bdata-cap.com/newsinfo/1712113.html

測試數據


[16-04-12 03:40:01 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.
[16-04-12 03:40:02 DEBUG] impl.JdbcEntityInserter:- from product_category product_category
where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null
order by product_category.ORDERS asc
[16-04-12 03:40:03 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.
[16-04-12 03:40:04 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.
[16-04-12 03:40:05 DEBUG] impl.JdbcEntityInserter:- from product_category product_category
where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null
order by product_category.ORDERS desc
[16-04-12 03:40:06 DEBUG] impl.JdbcEntityInserter:- from product_category product_category
where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null
order by product_category.ORDERS asc
[16-04-12 03:40:07 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.

測試是在7秒內發生的(固然是假數據)。能夠看到,第2、5、六秒的日誌是多行的,有條SQL語句。其餘是單行的。app

字段屬性


 

對 multiline 插件來講,有三個設置比較重要:negate、pattern 和 what。ide

negate測試

  • 類型是 booleanui

  • 默認爲 falsespa

否認正則表達式(若是沒有匹配的話)。插件

patterndebug

  • 必須設置

  • 類型爲 string

  • 沒有默認值

要匹配的正則表達式。

what

  • 必須設置

  • 能夠爲 previous 或 next

  • 沒有默認值

若是正則表達式匹配了,那麼該事件是屬於下一個或是前一個事件?

按多行解析運行時日誌


示例1:若配置文件以下所示,

input {
        file{
                path=>"/usr/local/elk/logstash/logs/c.out"
                type=>"runtimelog"
                codec=> multiline {
                        pattern => "^\["
                        negate => true
                        what => "previous"
                }
                start_position=>"beginning"
                sincedb_path=>"/usr/local/elk/logstash/sincedb-access"
                ignore_older=>0
        }
}
output{
        stdout{
                codec=>rubydebug
        }
}

說明:匹配以「[」開頭的行,若是不是,那確定是屬於前一行的。

解析結果以下所示,能解析出6個JSON:

{
    "@timestamp" => "2016-06-01T04:37:43.147Z",
       "message" => "[16-04-12 03:40:01 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:37:43.152Z",
       "message" => "[16-04-12 03:40:02 DEBUG] impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:37:43.152Z",
       "message" => "[16-04-12 03:40:03 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:37:43.155Z",
       "message" => "[16-04-12 03:40:04 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:37:43.157Z",
       "message" => "[16-04-12 03:40:05 DEBUG] impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS desc",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:37:43.159Z",
       "message" => "[16-04-12 03:40:06 DEBUG] impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}

解析時,最後一行日誌,不會解析。只有當再追加一條日誌時,纔會解析最後一條日誌。

示例2:若將配置文件修改成,

input {
        file{
                path=>"/usr/local/elk/logstash/logs/c.out"
                type=>"runtimelog"
                codec=>multiline  {
                        pattern => "^\["
                        negate => true
                        what => "next"
                }
                start_position=>"beginning"
                sincedb_path=>"/usr/local/elk/logstash/sincedb-access"
                ignore_older=>0
        }
}
output{
        stdout{
                codec=>rubydebug
        }
}

解析結果爲,能解析出7個JSON:

{
    "@timestamp" => "2016-06-01T04:40:43.232Z",
       "message" => "[16-04-12 03:40:01 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:40:43.237Z",
       "message" => "[16-04-12 03:40:02 DEBUG] impl.JdbcEntityInserter:- from product_category product_category",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:40:43.238Z",
       "message" => "where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc\n[16-04-12 03:40:03 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:40:43.239Z",
       "message" => "[16-04-12 03:40:04 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:40:43.244Z",
       "message" => "[16-04-12 03:40:05 DEBUG] impl.JdbcEntityInserter:- from product_category product_category",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:40:43.245Z",
       "message" => "where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS desc\n[16-04-12 03:40:06 DEBUG] impl.JdbcEntityInserter:- from product_category product_category",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T04:40:43.249Z",
       "message" => "where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc\n[16-04-12 03:40:07 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}

示例3:若將配置文件修改成,

codec=>multiline  {
        pattern => "^\["
        negate => false
        what => "previous"
}

則解析結果爲:

{
    "@timestamp" => "2016-06-01T05:38:50.853Z",
       "message" => "[16-04-12 03:40:01 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.\n[16-04-12 03:40:02 DEBUG] impl.JdbcEntityInserter:- from product_category product_category",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T05:38:50.856Z",
       "message" => "where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T05:38:50.858Z",
       "message" => "order by product_category.ORDERS asc\n[16-04-12 03:40:03 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.\n[16-04-12 03:40:04 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.\n[16-04-12 03:40:05 DEBUG] impl.JdbcEntityInserter:- from product_category product_category",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T05:38:50.860Z",
       "message" => "where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T05:38:50.861Z",
       "message" => "order by product_category.ORDERS desc\n[16-04-12 03:40:06 DEBUG] impl.JdbcEntityInserter:- from product_category product_category",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}
{
    "@timestamp" => "2016-06-01T05:38:50.863Z",
       "message" => "where product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog"
}

 

 

 

 

 

 

 

把多行日誌解析到字段


配置文件以下所示:

input {
        file{
                path=>"/usr/local/elk/logstash/logs/c.out"
                type=>"runtimelog"
                codec=>multiline  {
                        pattern => "^\["
                        negate => true
                        what => "previous"
                }
                start_position=>"beginning"
                sincedb_path=>"/usr/local/elk/logstash/sincedb-access"
                ignore_older=>0
        }
}
filter {
        grok {
                match=>["message","\[%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level}\] %{GREEDYDATA:msg}"]
        }
}
output{
        stdout{
                codec=>rubydebug
        }
}

解析後結果:

{
    "@timestamp" => "2016-06-01T06:33:26.426Z",
       "message" => "[16-04-12 03:40:01 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog",
     "timestamp" => "16-04-12 03:40:01",
         "level" => "DEBUG",
           "msg" => "model.MappingNode:- ['/store/shopclass'] matched over."
}
{
    "@timestamp" => "2016-06-01T06:33:26.485Z",
       "message" => "[16-04-12 03:40:02 DEBUG] impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog",
     "timestamp" => "16-04-12 03:40:02",
         "level" => "DEBUG",
           "msg" => "impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc"
}
{
    "@timestamp" => "2016-06-01T06:33:26.491Z",
       "message" => "[16-04-12 03:40:03 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog",
     "timestamp" => "16-04-12 03:40:03",
         "level" => "DEBUG",
           "msg" => "model.MappingNode:- ['/store/shopclass'] matched over."
}
{
    "@timestamp" => "2016-06-01T06:33:26.492Z",
       "message" => "[16-04-12 03:40:04 DEBUG] model.MappingNode:- ['/store/shopclass'] matched over.",
      "@version" => "1",
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog",
     "timestamp" => "16-04-12 03:40:04",
         "level" => "DEBUG",
           "msg" => "model.MappingNode:- ['/store/shopclass'] matched over."
}
{
    "@timestamp" => "2016-06-01T06:33:26.494Z",
       "message" => "[16-04-12 03:40:05 DEBUG] impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS desc",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog",
     "timestamp" => "16-04-12 03:40:05",
         "level" => "DEBUG",
           "msg" => "impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS desc"
}
{
    "@timestamp" => "2016-06-01T06:33:26.495Z",
       "message" => "[16-04-12 03:40:06 DEBUG] impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "path" => "/usr/local/elk/logstash/logs/c.out",
          "host" => "vcyber",
          "type" => "runtimelog",
     "timestamp" => "16-04-12 03:40:06",
         "level" => "DEBUG",
           "msg" => "impl.JdbcEntityInserter:- from product_category product_category\nwhere product_category.PARENT_ID is null and product_category.STATUS = ? and product_category.DEALER_ID is null\norder by product_category.ORDERS asc"
}

參考資料


相關文章
相關標籤/搜索