A short question of GROK to handle hex number

Hello every experts,

I have met a short question.

Here is a source input content, it is one function back trace of an issue, the content shows as below:

101c2f8f 1106f017 129570e2 1210da9a 1290fa12 10fb825d120e33ed 120e188f 1058b38c

As we known, the function back trace are constiuted by several hexadecimal number group, every group should be included 8 hex numbers. but some of them are missing one space that result 16 hex numbers are in one group.

I use GROK plugin to add a field which named "fcn", such liks this:

grok {
        match => {
                        "message" => [
                                                (?<fcn>((\h){8}\s*)*)
                                                ]
                         }
        }

then the output shows as below:

{
  "fcn": [
    [
      "101c2f8f 1106f017 129570e2 1210da9a 1290fa12 10fb825d120e33ed 120e188f 1058b38c"
    ]
  ]
}

My expect output want to be:

[
  "101c2f8f 1106f017 129570e2 1210da9a 1290fa12 10fb825d 120e33ed 120e188f 1058b38c"
]

how should I do that can split them as every 8 hex numbers constitued one hex group?

Thank you.

Judging by your example, you actually need to insert characters at some point in the string and otherwise capture the field as-is. That would be hard or messy to do with grok + some other method.

The best option I think would be some custom Ruby code, e.g.

filter {
    ruby {
        code => "
            # remove whitespace -> split every 8 chars -> join by whitespace
            event.set('fcn', event.get('message').delete(' ').scan(/.{8}/).join(' '))
        "
    }
}

Mermigkas,

Thanks a lot for your help, which make me understand to use ruby code to realize my object.
But actually my input message include a lot of other information, such as process name, service name and so on, there are included a lot of useful space. which shows as below:

{process:sbl.elf (35),service:tafe,output:{Function Trace:101c2f8f 1106f017 129570e2 1210da9a 1290fa12 10fb825d120e33ed 120e188f 1058b38c f67dab28}}

If I use your code that may impact other format of infomration. are there some better methods to handle it?

Thanks again!

You can use any other method to extract the fields, like grok, which will result in a malformed fcn field. Then use the above Ruby code on that field to fix it's format.

Hi Mermigkas,

I want to use your ruby code to handle my log event, but I want only handle the function trace part, and firstly I have parsed the message by grok plugin:
The sub pattern shows as below:

"process:%{GREEDYDATA:process}\s*service:%{WORD:service},output:{Function Trace:%{GREEDYDATA:fcn}}"

How can I use your ruby code to only handle the fcn part? Thank you.

Just paste the Ruby code block after the grok part in your filters. It should work as-is.

Hi Mermigkas,

How can I only get the fcn part from message in ruby code? can you make a example? because in the below code you will get all the message content, delete the space will impact other parts.

event.set('parsed_fcn', event.get('message').delete(' ').scan(/.{8}/).join(' '))

Ah, you are correct. Use

filter {
    ruby {
        code => "
            event.set('parsed_fcn', event.get('fcn').delete(' ').scan(/.{8}/).join(' '))
        "
    }
}

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