具有转义“[”,“(”和“)”字符问题的Grok正则表达式

时间:2017-07-21 14:28:15

标签: logstash logstash-grok

弹性新手在这里 - 使用新的5.5安装。我有一个看起来像这样的日志行:

  

[2015/10/01 @ 19:48:22.785-0400] P-4780 T-2208 I DBUTIL:(451)prostrct   在CON:。

上为timk519创建会话开始

我有以下正则表达式:

\[%{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]属性不是   map,但类型为[java.lang.String],带有{header = {   processor_type =“grok”&amp; 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)部分,因为msgnum字段周围有转义的parens \(和\),因此无法将该行识别为合法字符串。

我是否错误地逃避了什么?这是一个错误吗?

更新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设置,现在正则表达式匹配我想要的传入日志流。 THX!

1 个答案:

答案 0 :(得分:2)

魔鬼在细节中,起初错误并不明显。 Grok Debugger失败的原因是您使用了DATE模式。这种模式解析如下:

DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}

MONTHNUMMONTHDAY都是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}

这将返回以下输出:

{
  "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"
}