我有一个自定义生成的日志文件,其格式如下:
[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
第二个条目[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 }
}
内容字段的输出为:The error message goes here ; array (
我的问题是我想将多行的其余部分存储到内容字段:
The error message goes here ; array (
'create' =>
array (
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3'
),
)
所以我可以稍后删除消息字段。
@message 字段包含整个多行事件,因此我尝试使用 mutate过滤器,并使用替换函数,但我&# 39;我只是无法让它发挥作用:(。
我不了解Multiline过滤器的工作方式,如果有人能对此有所了解,我们将非常感激。
谢谢,
阿卜杜迪。
答案 0 :(得分:12)
我浏览了源代码并发现:
以下是工作代码:
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 }
}
干杯,
阿卜杜迪
答案 1 :(得分:10)
本期https://logstash.jira.com/browse/LOGSTASH-509
中提到了grok和多行处理只需添加"(?m)"在你的grok正则表达式面前,你不会需要变异。问题示例:
pattern => "(?m)<%{POSINT:syslog_pri}>(?:%{SPACE})%{GREEDYDATA:message_remainder}"
答案 2 :(得分:5)
多行过滤器会在消息中添加“\ 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' ), )"
答案 3 :(得分:1)
问题不仅仅是过滤器的排序。记录存储顺序非常重要。您不需要另一行来指示您已完成输出多行日志行。只需确保在grok之前首先出现多行过滤器(见下文)
P.S。我已经设法解析了多行日志行,其中xml被附加到日志行的末尾并且它跨越了多行但仍然有一个很好的干净xml对象到我的内容等效变量(下面名为xmlrequest)。在你说一些关于在日志中记录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"
}
}