如何处理Logstash grok过滤器不匹配的情况

54

我在思考如何处理我的Logstash Grok过滤器的最佳方案。我有一些特定于某些日志条目的过滤器,而不是适用于所有条目。那些不适用的过滤器总是生成_grokparsefailure标签。例如,我有一个grok过滤器适用于每个日志条目,并且它很好地工作。然后我有另一个过滤器,它是用于带有追踪返回的错误消息的。对于每个没有追踪返回的日志条目,追踪过滤器都会抛出一个grokparsefailure。

我宁愿让它在没有匹配的情况下通过规则,而不是添加解析失败的标签。我使用解析失败的标签来查找无法正确解析的内容,而不是仅仅是没有匹配到特定过滤器的内容。也许只是“解析失败”这个术语让我感到困惑。对我来说,这意味着过滤器存在问题(例如格式错误),而不是没有匹配。

所以问题是,我应该如何处理这个问题?

  • 使用?使过滤模式变为可选项

  • 使用tag_on_failure选项滥用设置为空[]

  • 使用类似“if traceback in message”的条件使过滤器具有条件性

  • 还有其他我没有考虑的方法吗?

提前感谢。

编辑

我采用了在过滤器周围添加条件的方法:

    if [message] =~ /took\s\d+/ {
        grok {
            patterns_dir => "/etc/logstash/patterns"
            match => ["message", "took\s+(?<servicetime>[\d\.]+)"]
            add_tag => [ "stats", "servicetime" ]
        }
    }

尽管如此,我仍然对反馈感兴趣。这里什么被认为是“最佳实践”?

4个回答

38

如果可能的话,我会像你正在使用的那样使用一个条件包装器。随意将其发布为答案!

如果您的应用程序仅生成几种不同的行格式,则可以使用多个匹配模式与grok过滤器。默认情况下,该过滤器将处理前面成功的匹配:

grok {
    patterns_dir => "./patterns"
    match => {
        "message" => [ 
              "%{BASE_PATTERN} %{EXTRA_PATTERN}",
              "%{BASE_PATTERN}",
              "%{SOME_OTHER_PATTERN}"
        ]
    }
}
如果您的逻辑不够直观(也许您需要多次检查相同的条件),则grep过滤器可以很有用地添加一个标记。类似这样的东西:
grep {
    drop => false #grep normally drops non-matching events
    match => ["message", "/took\s\d+/"]
    add_tag => "has_traceback"
}


...

if "has_traceback" in [tags] {
    ...
}

2
这违反了DRY原则。你不能先匹配一条消息,然后再看是否应该匹配另一条消息。特别是因为它不是一种启发式方法;如果条件满足,则必须匹配该消息,否则grok失败。 - malthe
9
我理解你的观点,但也注意到你没有提供替代解决方案。通过几个月的经验,我知道一个空的tag_on_failure可能适用于某些使用情况...但我也知道在数据解析失败时的行为几乎没有记录,并且将来可能会发生变化。 - rutter
匹配 => [ "信息", "a", "信息", "b", "信息", "c" ] 导致错误。 - Stefan K.
4
哦,它匹配了 => { "message" => [ "时长: %{NUMBER:duration}", "速度: %{NUMBER:speed}" ] } - Stefan K.
这只是关于 Logstash 文档中有关条件语句的链接的更新:https://www.elastic.co/guide/en/logstash/current/event-dependent-configuration.html#conditionals - tonyg
2
感谢 @StefanK. 找到了正确的语法。 - jmcollin92

25
您还可以在您的grok语句中添加 tag_on_failure => []
grok {
    match => ["context", "\"tags\":\[%{DATA:apptags}\]"]
    tag_on_failure => [ ]
}

grok 仍然会失败,但是不会将其添加到标签数组中。


我认为这是最标准的做法。 - alfredocambera
太好了,这样你可以创建可被不懂grok的人理解的失败标签。 - herm

9

这是最有效的方法。忽略过滤器。

filter {

        grok {
            match => [ "message", "something"]
    }

    if "_grokparsefailure" in [tags] {
            drop { }
        }
}

4

您也可以这样做:

remove_tag => [ "_grokparsefailure" ]

只要您有匹配项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接