Spanky
Spanky

Reputation: 5776

How to handle non-matching Logstash grok filters

I am wondering what the best approach to take with my Logstash Grok filters. I have some filters that are for specific log entries, and won't apply to all entries. The ones that don't apply always generate _grokparsefailure tags. For example, I have one grok filter that's for every log entry and it works fine. Then I have another filter that's for error messages with tracebacks. The traceback filter throws a grokparsefailure for every single log entry that doesn't have a traceback.

I'd prefer to have it just pass the rule if there isn't a match instead of adding the parsefailure tag. I use the parsefailure tag to find things that aren't parsing properly, not things that simply didn't match a particular filter. Maybe it's just the nomenclature "parse failure" that gets me. To me that means there's something wrong with the filter (e.g. badly formatted), not that it didn't match.

So the question is, how should I handle this?

Thanks in advance.

EDIT

I took the path of adding a conditional around the filter:

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

Still interested in feedback though. What is considered "best practice" here?

Upvotes: 54

Views: 70505

Answers (4)

rutter
rutter

Reputation: 11452

When possible, I'd go with a conditional wrapper just like the one you're using. Feel free to post that as an answer!

If your application produces only a few different line formats, you can use multiple match patterns with the grok filter. By default, the filter will process up to the first successful match:

grok {
    patterns_dir => "./patterns"
    match => {
        "message" => [ 
              "%{BASE_PATTERN} %{EXTRA_PATTERN}",
              "%{BASE_PATTERN}",
              "%{SOME_OTHER_PATTERN}"
        ]
    }
}

If your logic is less straightforward (maybe you need to check the same condition more than once), the grep filter can be useful to add a tag. Something like this:

grep {
    drop => false #grep normally drops non-matching events
    match => ["message", "/took\s\d+/"]
    add_tag => "has_traceback"
}


...

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

Upvotes: 38

JAR
JAR

Reputation: 413

This is the most efficient way of doing this. Ignore the filter

filter {

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

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

Upvotes: 9

Gary Rogers
Gary Rogers

Reputation: 405

You can also add tag_on_failure => [] to your grok stanza like so:

grok {
    match => ["context", "\"tags\":\[%{DATA:apptags}\]"]
    tag_on_failure => [ ]
}

grok will still fail, but will do so without adding to the tags array.

Upvotes: 25

Tony Wong
Tony Wong

Reputation: 49

You can also do this

remove_tag => [ "_grokparsefailure" ]

whenever you have a match.

Upvotes: 4

Related Questions