logstash if statement within grok statement
Asked Answered
M

1

6

I'm creating a logstash grok filter to pull events out of a backup server, and I want to be able to test a field for a pattern, and if it matches the pattern, further process that field and pull out additional information.

To that end I'm embedding an if statement within the grok statement itself. This is causing the test to fail with Error: Expected one of #, => right after the if.

This is the filter statement:

filter {
    grok {
        patterns_dir => "./patterns"
        # NetWorker logfiles have some unusual fields that include undocumented engineering codes and what not
        # time is in 12h format (ugh) so custom patterns need to be used.
        match => [ "message", "%{NUMBER:engcode1} %{DATESTAMP_12H:timestamp}  %{NUMBER:engcode2} %{NUMBER:engcode3} %{NUMBER:engcode4} %{NUMBER:ppid} %{NUMBER:pid} %{NUMBER:engcode5} %{WORD:processhost} %{WORD:processname} %{GREEDYDATA:daemon_message}" ]
        # attempt to find completed savesets and pull that info from the daemon_message field
        if [daemon_message] =~ /done\ saving\ to\ pool/  { 
            grok {
                match => [ "daemon_message", "%{WORD:savehost}\:%{WORD:saveset} done saving to pool \'%{WORD:pool}\' \(%{WORD:volume}\) %{WORD:saveset_size}" ]
            }
        }
    }
    date {
        # This is requred to set the time from the logline to the timestamp and not have it create it's own.
        # Note the use of the trailing 'a' to denote AM or PM. 
        match => ["timestamp", "MM/dd/yyyy HH:mm:ss a"]
    } 
}

This block fails with the following:

$ /opt/logstash/bin/logstash -f ./networker_daemonlog.conf --configtest
Error: Expected one of #, => at line 12, column 12 (byte 929) after # Basic dumb simple networker daemon log grok filter for the NetWorker daemon.log 
# no smarts to this and not really pulling any useful info from the files (yet)
filter {
    grok {
... lines deleted ...
        # attempt to find completed savesets and pull that info from the daemon_message field
        if 

I'm new to logstash, and I realise that using a conditional within the grok statement may not be possible, but I'd prefer doing conditional processing this way to additional match lines as this would leave the daemon_message field intact for other uses while pulling out the data I want.

ETA: I should also point out that totally removing the if statement allows the configtest to pass and the filter to parse logs.

Thanks in advance...

Malissa answered 14/3, 2015 at 6:14 Comment(0)
A
17

Conditionals go outside the filters, so something like:

if [field] == "value" {
     grok {
          ...
     }
]

would be correct. In your case, do the first grok, then test to run the second, i.e.:

grok {
    match => [ "message", "%{NUMBER:engcode1} %{DATESTAMP_12H:timestamp}  %{NUMBER:engcode2} %{NUMBER:engcode3} %{NUMBER:engcode4} %{NUMBER:ppid} %{NUMBER:pid} %{NUMBER:engcode5} %{WORD:processhost} %{WORD:processname} %{GREEDYDATA:daemon_message}" ]
}
if [daemon_message] =~ /done\ saving\ to\ pool/  {
    grok {
        match => [ "daemon_message", "%{WORD:savehost}\:%{WORD:saveset} done saving to pool \'%{WORD:pool}\' \(%{WORD:volume}\) %{WORD:saveset_size}" ]
    }  
}

This is really running two regexps for a record that matches. Since grok will only make fields when the regexp matches, you can do this:

grok {
    match => [ "message", "%{NUMBER:engcode1} %{DATESTAMP_12H:timestamp}  %{NUMBER:engcode2} %{NUMBER:engcode3} %{NUMBER:engcode4} %{NUMBER:ppid} %{NUMBER:pid} %{NUMBER:engcode5} %{WORD:processhost} %{WORD:processname} %{GREEDYDATA:daemon_message}" ]
}
grok {
    match => [ "daemon_message", "%{WORD:savehost}\:%{WORD:saveset} done saving to pool \'%{WORD:pool}\' \(%{WORD:volume}\) %{WORD:saveset_size}" ]
}

You'd have to measure the performance across your actual log files since this will run fewer regexps, but the second one is more complicated.

If you really want to go nuts, you can do all of this in one grok{}, using the break_on_match feature.

Autoerotic answered 15/3, 2015 at 16:21 Comment(6)
Ok, I was afraid of that. I was hoping to be able to split up the daemon_message field while populating new fields, but that seems to be beyond the logstash software.. Thanks..Malissa
The examples above are making new fields from your input; what else did you need?Autoerotic
Ah, sorry, I misunderstood. Yes, this is exactly what I want. Thanks again.Malissa
Are these conditionals documented anywhere?Ventilate
@ElzoValugi, they keep moving the doc around, but the current link is at elastic.co/guide/en/logstash/current/…Autoerotic
@AlainCollins Can you please edit the answer and add this link ?Vaden

© 2022 - 2024 — McMap. All rights reserved.