Nested json as a string field


(ssh) #1

hi

i use json filter plugin in my logstash config.
here if i face nested json, i got _jsonparsefailure tag.
my target is that i just want nested json as string. not another json.
eg:

{ "agent": "Mozilla/5.0 (compatible; MSIE 9.0)", "ip": "192.168.24.44", request": "/index.html", "message": "{ "status": 200, "bytes": 52353 }"}

above log, i expect

agent : Mozilla/5.0 (compatible; MSIE 9.0)
ip : 192.168.24.44"
request : /index.html
message : { "status": 200, "bytes": 52353 }

is that possible?

could anyone help me to point out this?


#2

request needs a leading "

Even then, it does not appear to be valid JSON. No matter, we can fix things. We can modify that input so that the double quotes within the message field are escaped. That is, we need to transform it into

{ "agent": "Mozilla/5.0 (compatible; MSIE 9.0)", "ip": "192.168.24.44", request": "/index.html", "message": "{ \"status\": 200, \"bytes\": 52353 }"}

This is expensive (because it uses GREEDYDATA at the start of a pattern), fragile, and ugly. But for that exact input it works.

filter {
    grok { match => { "message" => [ "%{GREEDYDATA:beginning}\"message\": \"(?<middle>[^}]+)}%{GREEDYDATA:end}" ] } }
    mutate { gsub => [ "middle", '"', '\"' ] }
    mutate { add_field => { "quotedmessage" => '%{beginning}"message": "%{middle}}%{end}' } }
    filter { json { source => "quotedmessage" } }
}

Alternatively, we can strip off the quotes around the message field, let the json filter parse it, then convert it back to a string.

filter {
    mutate { gsub => [ "message", '"message": "', '"message": ', "message", '"([^"]+)$', '\1' ] }
    json { source => "message" }
    mutate { replace => { "message" => "%{message}" } }
}

(ssh) #3

thank you @Badger


(system) closed #4

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