Try something like
if [message] == "[Metadata]" or [message] == "[Events]" or [message] =~ /^$/ {
drop {}
} else {
if [message] =~ /^[0-9a-zA-Z]+:/ {
dissect { mapping => { "message" => "%{key}: %{value}" } }
ruby {
init => '
@@metadata = {}
'
code => '
@@metadata[event.get("key")] = event.get("value")
'
}
drop {}
} else {
ruby {
code => '
event.set("metadata", @@metadata)
'
}
}
}
Essentially, if the line looks like "key: value" then stash it as metadata. If it does not then add all the stashed metadata items to the event.
I think this requires "--pipeline.workers 1"
This kind of ruby solution tends to be fragile, and has to be tuned to the input.
I use a class variable (@@metadata) rather than an instance variable (@metadata) because we need the same variable to visible across multiple ruby filters.