次のパターンを持つカスタム生成ログファイルがあります。
[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関数を使用しましたが、動作させるには:(.
マルチラインフィルターの動作方法がわかりません。誰かがこれに光を当てることができれば、本当にありがたいです。
おかげで、
アブドゥ。
私はソースコードを調べて、それを見つけました:
作業コードは次のとおりです。
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 }
}
乾杯、
アブドゥ
grokと複数行の処理はこの問題で言及されています https://logstash.jira.com/browse/LOGSTASH-509
Grok正規表現の前に「(?m)」を追加するだけで、突然変異は必要ありません。問題の例:
pattern => "(?m)<%{POSINT:syslog_pri}>(?:%{SPACE})%{GREEDYDATA:message_remainder}"
複数行フィルターは、メッセージに「\ 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' ), )"
問題は単にフィルターの順序だけではありません。スタッシュを記録するには順序が非常に重要です。複数行のログ行の出力が終了したことを示すために、別の行は必要ありません。 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"
}
}