Grok field extract: One pattern, multiple matches


(Jon Rust) #1

Oracle alert logs contain multiple ORA- codes. I can't figure how to tell grok to match all and return an array of the matches.

 if [msg] =~ /ORA-/ {
    grok {
       match => [ "msg","(?<ora_code>ORA-[0-9]+)" ]
    }
 }

Log example might have:

ORA-12345: some message ORA-45678: some other message

Is it possible?


(Ry Biesemeyer) #2

You're looking for break_on_match => false :slightly_smiling_face:


(Jon Rust) #3

That didn't do the trick. Tried this:

 if [msg] =~ /ORA-/ {
    grok {
       break_on_match => false
       match => [ "msg","(?<ora_code>ORA-[0-9]+)" ]
    }
 }

(Ry Biesemeyer) #4

d'oh! that flag will keep looking at patterns but not at the input after a match. I think I can whip up something quick with a ruby script for you though.


#5

Use ruby.

  code => "
    s = event.get('message')
    r = s.scan(/(ORA-[0-9]{5})/)
    r = r.flatten
    event.set('OracleErrors', r.join('/'))
  "

Actually, if you want an array, do not do the join, just set OracleErrors to r.


(Jon Rust) #6

That did the trick. Thanks.

  if [msg] =~ /ORA-/ {
     ruby {
        code => "
           mat = event.get('msg').scan(/(ORA-[0-9]+)/)
           event.set('ora_code', mat.flatten)
        "
     }

(Ry Biesemeyer) #7

I whipped up a quick ruby filter with tests that capture edge-cases (such as the event not having a value at msg, or the string containing no matches):


(system) #8

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