我正在尝试解析包含XML和其他任意输出的日志文件。 在特定情况下,我想检查预订是否已成功发送给客户。
[11-28-51.440000] Sending reservation to customer
[11-28-51.492900] <?xml version="1.0" encoding="UTF-8"?><SendReservation><ReservationId>1289</ReservationId><Customer>2892</Customer>...</SendReservation>
[11-28-51.493000] Status: Successfull
[11-28-52.261000] Something different
[11-28-51.520000] Sending reservation to customer
[11-28-54.548900] <?xml version="1.0" encoding="UTF-8"?><SendReservation><ReservationId>2732</ReservationId><Customer>7856</Customer>...</SendReservation>
[11-28-54.600000] Status: Error: Reservation was rejected
现在使用logstash我需要解析预订的一些字段,包括ReservationId。为此,我可以使用logstash XML过滤器。 但是我必须将它与成功/错误状态结合起来,这是在XML输出作为普通文本之后打印的。
我尝试使用多行输入:
input {
file {
path => "test.log"
start_position => "beginning"
type => "reservation"
codec => multiline {
pattern => "\[(.*?)\](.*?)<\?xml[^>]*>"
negate => true
what => previous
}
}
}
有了这个,我将在logstash事件中收到一条消息:
"message" => "[11-28-51.492900] <?xml version="1.0" encoding="UTF-8"?><SendReservation><ReservationId>1289</ReservationId><Customer>2892</Customer>...</SendReservation>\n[11-28-51.493000] Status: Successfull\n[11-28-52.261000] Something different\n[11-28-51.520000] Sending reservation to customer
为了能够使用XML过滤器解析XML,我需要有一个包含有效XML的字段source。因此,我试图删除之前的时间戳和xml之后的所有内容。
mutate {
gsub => [ "message", "^(.*?)<\?xml[^>]*>", "" ]
}
mutate {
gsub => [ "message", "(?<=<\/SendReservation>).*$", "" ]
}
此时我看到,正则表达式匹配仅在消息的第一行(第一行\ n之前)起作用。这意味着,在结束标记之后删除所有内容将不起作用。这是我的第一个问题,这可能与多行有关。
第二个问题是,我不知道如何移动XML内容,我尝试将“消息”剪切到一个新字段中,我可以在XML过滤器中使用它作为源字段。我尝试了grok overwrite,但它需要一个现有的字段,我必须创建一个新字段。
总而言之,我想要的是从我的多行消息中创建一个头部和尾部字段。 Head将包含带有XML的第一行,保存主要信息,并使用一些其他信息来结束其余信息,我必须将其与之相关联。
答案 0 :(得分:1)
好的,感谢https://regex101.com和http://grokconstructor.appspot.com我自己找到了
我必须使用
grok { match => { "message" => "(?<head>(\[(.*?)\](.*?)<\?xml[^>]*>(.*?)<\/SendReservation>))+(?<tail>(?<=<\/SendReservation>)(.|\n)*$)" } }
回答第一个问题:
我必须考虑\ n:?<=<\/SendReservation>)(.|\n)*$
回答第二个问题:
Logstash从所有正则表达式组名称创建字段。在这种情况下,grok模式(?<head>(regex_for_xml))+(?<tail>(regex_for_text))
将创建head
和tail
字段。