我的真实模式更复杂,但我已尝试将问题归结为核心问题。有些我不明白。请尝试一下http://grokconstructor.appspot.com/do/match
我正在尝试匹配以下几行:
Start-Date: 2017-08-07 06:48:12
End-Date: 2017-08-07 06:48:12
Start-Date: 2017-08-07 12:55:16
End-Date: 2017-08-07 12:56:01
使用附加模式:
DATE_EU2 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[\s]+?%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
DATE_COMB %{DATE_EU2}?%{DATE_EU}?%{DATE_US}?
主要模式如下:
Start-Date: %{DATE_COMB:starttime}\nEnd-Date: %{DATE_COMB:endtime}
使用多行过滤器:
^\n (negated)
运行该程序你应该(希望!)得到:
Start-Date: 2017-08-07 06:48:12 End-Date: 2017-08-07 06:48:12 Start-Date: 2017-08-07 12:55:16 End-Date: 2017-08-07 12:56:01
MATCHED
starttime 2017-08-07··06:48:12
endtime 2017-08-07··06:48:12
after match: Start-Date: 2017-08-07 12:55:16 End-Date: 2017-08-07 12:56:01
因此它匹配第一条记录,但与第二条记录不匹配。如果我在主模式末尾添加一个 '\z',那么它将匹配第二条记录,但不匹配第一条记录。因此它显然将整行视为一行。但为什么呢?我的多行过滤器规定,如果一行不以换行符开头,则它是前一条记录的一部分,对吗?那么应该在中间留下一个空白行,该空白行显然以换行符开头,因此应该构成一个单独的事件,不是吗?
任何指点都值得感激。
答案1
输入
Start-Date: 2017-08-07 06:48:12
End-Date: 2017-08-07 06:48:12
Start-Date: 2017-08-07 12:55:16
End-Date: 2017-08-07 12:56:01
多行过滤器 = ^\n
(否定)
多行过滤器将依次查看每一行以查看应该合并的内容。
First line starts with `^Start-Date` (merged)
Second line starts with `^End-Date` (merged)
Third line is blank (merged, unless logstash skips blank lines)
Fourth line starts with `^Start-Date` (merged)
Fifth line starts with `^End-Date` (merged)
尝试匹配\n
,尤其是在行的开头是没有意义的。
最好将^End-Date:
其与前一个进行匹配和合并。(或者,如果某个事件有更多行,并且总是以 开头Start-Date:
,则匹配该行并取反。)
根据评论和使用 Grok 构造函数的测试进行编辑。
如果使用空行作为记录分隔符更有意义,^\z
或者^\Z
似乎有效。\Z
忽略任何最终终止符,但看到\z
在我的测试中也有效,它似乎确认了当传递到过滤器时,该行是一个完全空的字符串(没有换行符或任何其他终止字符)。