具有转义“[”、“(”和“)”字符问题的 Grok 正则表达式
Grok regex with escaped “[“, “(“, and “)” chars problems
这里是 Elastic 新手 - 使用新的 5.5 安装。我的日志行如下所示:
[2015/10/01@19:48:22.785-0400] P-4780 T-2208 I DBUTIL : (451) prostrct
create session begin for timk519 on CON:.
我有以下正则表达式:
\[%{DATE:date}@%{TIME:time}-(?<gmtoffset>\d{4})\]\s*(?<procid>P-[0-9]+)\s*(?<threadid>T-[0-9]+)\s*(?<msgtype>[ifIF])\s*(?<processtype>[a-zA-Z]+)\s*(?<usernumber>[0-9]+|[:])\s*\((?<msgnum>[0-9]+|[\-]+)\)\s*%{GREEDYDATA:message}
当我在 kibana grok 调试器中尝试它时,它不起作用并且出现以下错误:
GrokDebugger: [parse_exception] [pattern_definitions] property isn't a
map, but of type [java.lang.String], with { header={
processor_type="grok" & property_name="pattern_definitions" } }
这似乎是由于行首的 \[。如果我用句点“.”替换前导 \[我明白了
.%{DATE:date}@%{TIME:time}-(?<gmtoffset>\d{4})\]\s*(?<procid>P-[0-9]+)\s*(?<threadid>T-[0-9]+)\s*(?<msgtype>[ifIF])\s*(?<processtype>[a-zA-Z]+)\s*(?<usernumber>[0-9]+|[:])\s*\((?<msgnum>[0-9]+|[\-]+)\)\s*%{GREEDYDATA:message}
grok 调试器和 https://grokdebug.herokuapp.com/ 非常适合这种模式。
当我将此正则表达式放入 logstash 时,它无法识别该行的 msgnum (451) 部分,因为转义了 parens \( 和 \)在 msgnum 字段周围,因此无法将该行识别为合法字符串。
我是不是转义不正确?这是一个错误吗?
更新 2017-07-21
我通过将 ( 和 ) 放在 [(] 和 [)] 中来解决转义问题。我还没有找到解决匹配前导 [ 的方法。
更新 2017-07-24
下面的答案是一个史诗般的收获,我用它来创建以下自定义模式:
DBTIME %{TIME}[-+]\d{4}
DBTIMESTAMP %{YEAR}/%{MONTHNUM}/%{MONTHDAY}@%{DBTIME}
我已经在我的 grok 语句中实现了,如下所示:
\[%{DBTIMESTAMP:dbdatetime}\]\s*%{PROCESSID:processid}\s*%{DBTHREADID:threadid}\s*%{DBMSGTYPE:msgtype}\s*%{PROCESSTYPE:processtype}?\s*%{USERNUMBER:usernumber}?\s*:\s*[(]%{MSGNUMBER:msgnumber}[)].\s*%{GREEDYDATA:eventmessage}\s*\r
然后我使用日期过滤器将 dbdatetime 转换为 @timestamp 设置,现在正则表达式匹配传入的日志流,这正是我想要的。谢谢!
细节决定成败,错误一开始并不明显。 Grok 调试器失败的原因是因为您使用了 DATE
模式。此模式解析如下:
DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
MONTHNUM
和 MONTHDAY
都是 2 位数字模式,这实际上意味着它们与您所在年份的 15 匹配。这就是模式不起作用的原因,因为 \[%{DATE}
实际上不匹配(它缺少 20)。为什么模式 .%{DATE}
很难工作?因为您没有将 [
与点匹配,所以您匹配的是年份的 0
。
如何解决这个问题?使用自定义模式来匹配日期。像这样的东西有效:
\[(?<date>%{YEAR}/%{MONTHNUM}/%{MONTHDAY})@%{TIME:time}-(?<gmtoffset>\d{4})\]\s*(?<procid>P-[0-9]+)\s*(?<threadid>T-[0-9]+)\s*(?<msgtype>[ifIF])\s*(?<processtype>[a-zA-Z]+)\s*(?<usernumber>[0-9]+|[:])\s*\((?<msgnum>[0-9]+|[\-]+)\)\s*%{GREEDYDATA:message}
这将return以下输出:
{
"date": "2015/10/01",
"msgnum": "451",
"procid": "P-4780",
"processtype": "DBUTIL",
"message": "prostrct create session begin for timk519 on CON:.",
"threadid": "T-2208",
"usernumber": ":",
"gmtoffset": "0400",
"time": "19:48:22.785",
"msgtype": "I"
}
这里是 Elastic 新手 - 使用新的 5.5 安装。我的日志行如下所示:
[2015/10/01@19:48:22.785-0400] P-4780 T-2208 I DBUTIL : (451) prostrct create session begin for timk519 on CON:.
我有以下正则表达式:
\[%{DATE:date}@%{TIME:time}-(?<gmtoffset>\d{4})\]\s*(?<procid>P-[0-9]+)\s*(?<threadid>T-[0-9]+)\s*(?<msgtype>[ifIF])\s*(?<processtype>[a-zA-Z]+)\s*(?<usernumber>[0-9]+|[:])\s*\((?<msgnum>[0-9]+|[\-]+)\)\s*%{GREEDYDATA:message}
当我在 kibana grok 调试器中尝试它时,它不起作用并且出现以下错误:
GrokDebugger: [parse_exception] [pattern_definitions] property isn't a map, but of type [java.lang.String], with { header={ processor_type="grok" & property_name="pattern_definitions" } }
这似乎是由于行首的 \[。如果我用句点“.”替换前导 \[我明白了
.%{DATE:date}@%{TIME:time}-(?<gmtoffset>\d{4})\]\s*(?<procid>P-[0-9]+)\s*(?<threadid>T-[0-9]+)\s*(?<msgtype>[ifIF])\s*(?<processtype>[a-zA-Z]+)\s*(?<usernumber>[0-9]+|[:])\s*\((?<msgnum>[0-9]+|[\-]+)\)\s*%{GREEDYDATA:message}
grok 调试器和 https://grokdebug.herokuapp.com/ 非常适合这种模式。
当我将此正则表达式放入 logstash 时,它无法识别该行的 msgnum (451) 部分,因为转义了 parens \( 和 \)在 msgnum 字段周围,因此无法将该行识别为合法字符串。
我是不是转义不正确?这是一个错误吗?
更新 2017-07-21
我通过将 ( 和 ) 放在 [(] 和 [)] 中来解决转义问题。我还没有找到解决匹配前导 [ 的方法。
更新 2017-07-24
下面的答案是一个史诗般的收获,我用它来创建以下自定义模式:
DBTIME %{TIME}[-+]\d{4}
DBTIMESTAMP %{YEAR}/%{MONTHNUM}/%{MONTHDAY}@%{DBTIME}
我已经在我的 grok 语句中实现了,如下所示:
\[%{DBTIMESTAMP:dbdatetime}\]\s*%{PROCESSID:processid}\s*%{DBTHREADID:threadid}\s*%{DBMSGTYPE:msgtype}\s*%{PROCESSTYPE:processtype}?\s*%{USERNUMBER:usernumber}?\s*:\s*[(]%{MSGNUMBER:msgnumber}[)].\s*%{GREEDYDATA:eventmessage}\s*\r
然后我使用日期过滤器将 dbdatetime 转换为 @timestamp 设置,现在正则表达式匹配传入的日志流,这正是我想要的。谢谢!
细节决定成败,错误一开始并不明显。 Grok 调试器失败的原因是因为您使用了 DATE
模式。此模式解析如下:
DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
MONTHNUM
和 MONTHDAY
都是 2 位数字模式,这实际上意味着它们与您所在年份的 15 匹配。这就是模式不起作用的原因,因为 \[%{DATE}
实际上不匹配(它缺少 20)。为什么模式 .%{DATE}
很难工作?因为您没有将 [
与点匹配,所以您匹配的是年份的 0
。
如何解决这个问题?使用自定义模式来匹配日期。像这样的东西有效:
\[(?<date>%{YEAR}/%{MONTHNUM}/%{MONTHDAY})@%{TIME:time}-(?<gmtoffset>\d{4})\]\s*(?<procid>P-[0-9]+)\s*(?<threadid>T-[0-9]+)\s*(?<msgtype>[ifIF])\s*(?<processtype>[a-zA-Z]+)\s*(?<usernumber>[0-9]+|[:])\s*\((?<msgnum>[0-9]+|[\-]+)\)\s*%{GREEDYDATA:message}
这将return以下输出:
{
"date": "2015/10/01",
"msgnum": "451",
"procid": "P-4780",
"processtype": "DBUTIL",
"message": "prostrct create session begin for timk519 on CON:.",
"threadid": "T-2208",
"usernumber": ":",
"gmtoffset": "0400",
"time": "19:48:22.785",
"msgtype": "I"
}