【问题标题】:Ignore and move to next pattern if log contains a specific word如果日志包含特定单词,则忽略并移至下一个模式
【发布时间】:2018-10-23 16:02:20
【问题描述】:

我有一个来自 spring 日志文件的日志文件。日志文件有三种格式。前两种格式各占一行,中间如果有关键字app-info,就是自己开发者打印的消息。如果不是,则由spring框架打印。我们可能会将开发人员的消息与 Spring 框架的消息不同。第三种格式是多行堆栈跟踪。

我们有一个我们自己的格式的例子,例如

2018-04-27 10:42:49 [http-nio-8088-exec-1] - INFO  - app-info - injectip ip 192.168.16.89

上面一行有app-info的关键作品,所以是我们自己的开发者。

2018-04-27 10:42:23 [RMI TCP Connection(10)-127.0.0.1] - INFO  - org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'

上面一行没有app-info关键字,所以是spring框架打印出来的。

在我的 Grok 过滤器中,第一种模式用于从 spring 框架打印的消息,第二种用于开发人员的消息,第三种格式用于多行堆栈跟踪。我想首先正则表达式明确提到 spring 框架模式没有关键字 app-info 以便它可以得到 paserexception 并遵循开发人员自己的格式的第二种模式。所以我在regex tool 中有以下格式,但我得到了编译错误。我的正则表达式如下:

(?<timestamp>[\d\-\s\:]+)\s\[(?<threadname>[\d\.\w\s\(\)\-]+)\]\s-\s(?<loglevel>[\w]+)\s+-\s+(?<systemmsg>[^((?app-info).)*\s\.\w\-\'\:\d\[\]\/]+)

由于在 Grok 过滤器中,我使用来自 this link 的指令

filter {
   grok {
     match => [ "message", "PATTERN1", "PATTERN2" , "PATTERN3" ]
    }
}

我目前在logstash中的配置如下,模式中没有明确提到app-info:

filter {
  grok {
    match => [
      "message",
        '(?<timestamp>[\d\-\s\:]+)\s\[(?<threadname>[\d\.\w\s\(\)\-]+)\]\s-\s(?<loglevel>[\w]+)\s+-\s+(?<systemmsg>[\s\.\w\-\'\:\d\[\]\/^[app-info]]+)',
        '(?<timestamp>[\d\-\s\:]+)\s\[(?<threadname>[\d\.\w\s\(\)\-]+)\]\s-\s(?<loglevel>[\w]+)\s+-\s(?<appinfo>app-info)\s-\s(?<systemmsg>[\w\d\:\{\}\,\-\(\)\s\"]+)',
        '(?<timestamp>[\d\-\s\:]+)\s\[(?<threadname>[\w\-\d]+)\]\s-\s(?<loglevel>[\w]+)\s\-\s(?<appinfo>app-info)\s-\s(?<params>params):(?<jsonstr>[\"\w\d\,\:\.\{\}]+)\s(?<exceptionname>[\w\d\.]+Exception):\s(?<exceptiondetail>[\w\d\.]+)\n\t(?<extralines>at[\s\w\.\d\~\?\n\t\(\)\_\[\]\/\:\-]+)\n\d'
      
    ]      
  }

}

使用上述logstash配置中的格式,处理时使用

2018-04-27 10:42:49 [http-nio-8088-exec-1] - INFO  - app-info - injectip ip 192.168.16.89

第一种模式(spring framework 模式)已经可以了,所以它不属于我们自己的开发者格式的第二种模式。解析器解析成功如下:

  {
  "timestamp": [
    [
      "2018-04-27 10:42:49"
    ]
  ],
  "threadname": [
    [
      "http-nio-8088-exec-1"
    ]
  ],
  "loglevel": [
    [
      "INFO"
    ]
  ],
  "systemmsg": [
    [
      "app-info - injectip ip 192.168.16.89\n\n"
    ]
  ]
}

我可以让第一个模式清楚地提到 systemmsg 不应包含关键字“app-info”的任何提示?

编辑:

我的目标是,如果没有关键字 app-info,我让模式 1 来处理日志。如果有关键字app-info,我让模式2来处理日志。

使用以下不包含关键字 app-info 的日志(模式 1 应有效),

2018-04-27 10:42:23 [RMI TCP Connection(10)-127.0.0.1] - INFO  - org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'

我得到以下结果与根据您的建议修改的第一个模式不匹配,这不是我的目标。

(?<timestamp>[\d\-\s\:]+)\s\[(?<threadname>[\d\.\w\s\(\)\-]+)\]\s-\s(?<loglevel>[\w]+)\s+-\s+(?<systemmsg>[^(?:(?!app\-info).)*\s\.\w\-\'\:\d\[\]\/]+)

demo。我的目标是提取时间戳、线程名称、日志级别和系统消息。但是第一个模式并没有给我预期的结果。该工具说没有匹配。

如果我删除 ^(?:(?!app-info).)*,那么上面的日志(没有关键字 app-info)解析器就可以工作。见demo 但是现在,它也适用于包含不期望的关键字 app-info 的日志,因为现在我想提取时间戳、线程名、日志级别、app-info(是否存在)(该字段应被提取或分组),然后系统消息。期望是第一个解析器返回错误,让第二个解析器处理日志。 demo 可以看到解析器也适用于关键字 app-info 的日志。 Systemmsg 将字段 app-info 放入其值中,这不是预期的。

所以我想要模式 1,处理不带关键字 app-info 的日志,模式 2 处理带关键字 app-info 的日志。所以我明确让模式 1 在包含关键字 app-info 时抛出解析错误或异常。

【问题讨论】:

  • 请阅读更新后的答案。

标签: logstash elastic-stack logstash-grok


【解决方案1】:

我的目标是让模式 1 处理没有关键字 app-info 的日志。如果 有app-info,第一个模式会抛出解析错误,这样 第二个解析器可以处理日志。

您可以使用以下作为您的第一个模式,

(?<data>^(?!.*app-info).*)%{LOGLEVEL:log}%{DATA:other_data}%{IP:ip}$

它会做的是,如果在任何位置有app-info,它将忽略日志,并移动到2nd PATTERN

示例


不带app-info的日志,

2018-04-27 10:42:49 [http-nio-8088-exec-1] - INFO  injectip ip 192.168.16.89

您可以根据自己的要求对其进行过滤。

输出

{
  "data": [
    [
      "2018-04-27 10:42:49 [http-nio-8088-exec-1] - "
    ]
  ],
  "log": [
    [
      "INFO"
    ]
  ],
  "other_data": [
    [
      "  injectip ip "
    ]
  ],
  "ip": [
    [
      "192.168.16.89"
    ]
  ]
}

现在用app-info登录,

2018-04-27 10:42:49 [http-nio-8088-exec-1] - INFO app-info  injectip ip 192.168.16.89

输出

No Matches

test it here

编辑 2:

如果你让PATTERN1 等于(?&lt;data&gt;^(?!.*app-info).*)

你会得到的,

{
  "data": [
    [
      "2018-04-27 10:42:49 [http-nio-8088-exec-1] - INFO  injectip ip 192.168.16.89"
    ]
  ]
}

然后您可以为 data 字段添加第二个 grok 过滤器,如下所示,

grok {
  match => {"data" => "DEFINE PATTERN HERE"}
}

【讨论】:

  • 非常感谢您的回答。 @Sufiyan Ghori。我的目标是让模式 1 处理没有关键字 app-info 的日志。如果有 app-info,第一个模式将抛出解析错误,以便第二个解析器可以处理日志。我将更详细的信息和结果放入原始问题作为第二版。
  • 非常感谢@Sufiyan Ghori!在数据部分,我将如何划分它,以便我可以分别获取时间戳和线程名称。 http-nio-8088-exec-1 是我的线程名。
  • 为此,您需要创建另一个模式来匹配 data 字段。最简单的方法是用(?&lt;data&gt;^(?!.*app-info).*) 替换整个模式(?&lt;data&gt;^(?!.*app-info).*)%{LOGLEVEL:log}%{DATA:other_data}%{IP:ip}$,然后创建新的grok 以匹配data 字段并过滤它。如果对您有帮助,请随时投票并接受答案。
  • 非常感谢您的回答。如果您能告诉我如何编写这种类型的 grok,我将不胜感激。它超出了我对 logstash 和 Grok 的了解。
  • 嗨@SufiyanGhori 你能在这里检查一下吗?如果您有任何想法来实现这一点,请告诉我。 stackoverflow.com/questions/51749854/…
【解决方案2】:

我为此使用了 GREEDYDATA,假设您有以下日志行

重定向控制器:点击数据重定向成功:{a:123, b:345}

并且您想捕获直到“数据”然后使用 GREEDYDATA 如下

%{GREEDYDATA}数据:%{SPACE}%{模式的其余部分}

【讨论】:

    猜你喜欢
    • 2022-08-15
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    相关资源
    最近更新 更多