web-dev-qa-db-ja.com

logstashフィルターで複数行のログエントリを処理する方法は?

バックグラウンド:

次のパターンを持つカスタム生成ログファイルがあります。

[2014-03-02 17:34:20] - 127.0.0.1|ERROR| E:\xampp\htdocs\test.php|123|subject|The error message goes here ; array (
  'create' => 
  array (
    'key1' => 'value1',
    'key2' => 'value2',
    'key3' => 'value3'
  ),
)
[2014-03-02 17:34:20] - 127.0.0.1|DEBUG| flush_multi_line

2番目のエントリ[2014-03-02 17:34:20] - 127.0.0.1|DEBUG| flush_multi_lineはダミー行です。複数行のイベントが終了したことをlogstashに知らせるために、この行は後で削除されます。

私の設定ファイルは次のとおりです。

input {
  stdin{}
}

filter{
  multiline{
      pattern => "^\["
      what => "previous"
      negate=> true
  }
  grok{
    match => ['message',"\[.+\] - %{IP:ip}\|%{LOGLEVEL:loglevel}"]
  }

  if [loglevel] == "DEBUG"{ # the event flush  line
    drop{}
  }else if [loglevel] == "ERROR"  { # the first line of multievent
    grok{
      match => ['message',".+\|.+\| %{PATH:file}\|%{NUMBER:line}\|%{Word:tag}\|%{GREEDYDATA:content}"] 
    }
  }else{ # its a new line (from the multi line event)
    mutate{
      replace => ["content", "%{content} %{message}"] # Supposing each new line will override the message field
    }
  }  
}

output {
  stdout{ debug=>true }
}

contentフィールドの出力は次のとおりです:The error message goes here ; array (

問題:

私の問題は、コンテンツフィールドへの複数行の残りを保存したいことです:

The error message goes here ; array (
  'create' => 
  array (
    'key1' => 'value1',
    'key2' => 'value2',
    'key3' => 'value3'
  ),
)

そのため、後でメッセージフィールドを削除できます。

@ messageフィールドには複数行のイベント全体が含まれているため、mutate filterを試してみましたreplace関数を使用しましたが、動作させるには:(.

マルチラインフィルターの動作方法がわかりません。誰かがこれに光を当てることができれば、本当にありがたいです。

おかげで、

アブドゥ。

27
emonik

私はソースコードを調べて、それを見つけました:

  • 複数行フィルターはキャンセルされますすべてのイベント保留中のイベントのフォローアップと見なされるこの場合、複数行フィルターは適用されません。
  • フィルターを通過する唯一のイベントは、新しいものと見なされるイベントです(私の場合は[で始まるもの)

作業コードは次のとおりです。

input {
   stdin{}
}  

filter{
      if "|ERROR|" in [message]{ #if this is the 1st message in many lines message
      grok{
        match => ['message',"\[.+\] - %{IP:ip}\|%{LOGLEVEL:loglevel}\| %{PATH:file}\|%{NUMBER:line}\|%{Word:tag}\|%{GREEDYDATA:content}"]
      }

      mutate {
        replace => [ "message", "%{content}" ] #replace the message field with the content field ( so it auto append later in it )
        remove_field => ["content"] # we no longer need this field
      }
    }

    multiline{ #Nothing will pass this filter unless it is a new event ( new [2014-03-02 1.... )
        pattern => "^\["
        what => "previous"
        negate=> true
    }

    if "|DEBUG| flush_multi_line" in [message]{
      drop{} # We don't need the dummy line so drop it
    }
}

output {
  stdout{ debug=>true }
}

乾杯、

アブドゥ

12
emonik

grokと複数行の処理はこの問題で言及されています https://logstash.jira.com/browse/LOGSTASH-509

Grok正規表現の前に「(?m)」を追加するだけで、突然変異は必要ありません。問題の例:

pattern => "(?m)<%{POSINT:syslog_pri}>(?:%{SPACE})%{GREEDYDATA:message_remainder}"
11
sbange

複数行フィルターは、メッセージに「\ n」を追加します。例えば:

"[2014-03-02 17:34:20] - 127.0.0.1|ERROR| E:\\xampp\\htdocs\\test.php|123|subject|The error message goes here ; array (\n  'create' => \n  array (\n    'key1' => 'value1',\n    'key2' => 'value2',\n    'key3' => 'value3'\n  ),\n)"

ただし、grokフィルターは「\ n」を解析できません。したがって、\ nを別の文字に置き換える必要があります(空白スペースなど)。

mutate {
    gsub => ['message', "\n", " "]
}

次に、grokパターンはメッセージを解析できます。例えば:

 "content" => "The error message goes here ; array (   'create' =>    array (     'key1' => 'value1',     'key2' => 'value2',     'key3' => 'value3'   ), )"
5
Ben Lim

問題は単にフィルターの順序だけではありません。スタッシュを記録するには順序が非常に重要です。複数行のログ行の出力が終了したことを示すために、別の行は必要ありません。 grokの前に複数行フィルターが最初に表示されることを確認してください(以下を参照)

追伸ログ行の最後にxmlが追加され、複数行にまたがる複数行のログ行を解析することができましたが、コンテンツの同等の変数(以下のxmlrequestという名前)にNice clean xmlオブジェクトを取得しました。あなたがログにXMLを記録することについて何か言う前に...私は知っています...それは理想的ではありません...しかしそれは別の議論のためです:)):

filter { 
multiline{
        pattern => "^\["
        what => "previous"
        negate=> true
    }

mutate {
    gsub => ['message', "\n", " "]
}

mutate {
    gsub => ['message', "\r", " "]
}

grok{
        match => ['message',"\[%{Word:ONE}\] \[%{Word:TWO}\] \[%{Word:THREE}\] %{GREEDYDATA:xmlrequest}"]
    }

xml {
source => xmlrequest
remove_field => xmlrequest
target => "request"
  }
}
1
Luis Pereira