How to groking and nested output

Hello,
I am having a log from a router and I have parsed with grok. But the thing I am struggling with is that I cannot create nested json object. For Example,

 proto TCP (ACK,FLAG)

To perse above log, I have applied following regex,

proto[[:blank:]](?<PROTOCOL>TCP|UDP)[[:blank:]](?<FLAG>\([A-Z,]+\))

So results are following,

  "PROTOCOL": [
    [
      "TCP"
    ]
  ],
  "FLAG": [
    [
      "(ACK,FIN)"
    ]
  ],

But how can I achieve something like the following,

  "PROTOCOL": [
    [
      "TCP"
    ]
  ],
  "FLAG": [
    [
      "TYPE: ["ACK", "FIN"]
    ]
  ],

Hi there!

What about doing it in two steps?

input { 
  generator { 
    count => 1 
    lines => [ 'proto TCP (ACK,FLAG)' ] 
  } 
}

filter {
  grok {
    match => { "message" => "proto\s+%{WORD:PROTOCOL}\s+\(%{DATA:to_split}\)" }
  }

  ruby {
    code => "
      unless (flags = event.get('to_split')).nil?
        event.set('[FLAG][TYPE]', flags.delete(' ').split(','))
        event.remove('to_split')
      end
    "
  }
}

output {
  stdout{}
}

Also, look at my grok filter and take a leaf out of it to improve yours if you want (that [[:blank:]] for example is both bulky and dangerous IMO)

1 Like

Use mutate+gsub to remove the parentheses, then use mutate+split to separate the flags, then use mutate+rename to change the name of the field.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.