Similar to this unanswered question: Ingest: foreach + grok processor - how to write result into an array?
I'm trying to parse a multiline document. Each line is a step in trace route and I'd like to process each line into an array.
Here's the relevant field, execbeat's exec.stdout
for a windows tracert
command:
Tracing route to example.com [123.456.789.10]
over a maximum of 30 hops:
1 24 ms 1 ms 1 ms 123.456.789.14
2 2 ms 1 ms 2 ms example.com [123.456.789.12]
3 5 ms 1 ms 1 ms example.com [123.456.789.10]
Trace complete.
Desired output, though I'd also be happy with separate top level arrays for each key, or even joined strings.
{
...
"hops": [
{"hop_step": 1, "hop_ip": "123.456.789.14", "rtt_1": 24, "rtt_2": 1},
{"hop_step": 2, "hop_ip": "123.456.789.12", "rtt_1": 2, "rtt_2": 1}
[... up to 30]
]
}
Here's my pipeline:
PUT _ingest/pipeline/tracert
{
"description": "A pipeline for parsing tracert results",
"processors": [
{
"set": {
"field": "hops",
"value": ""
}
},
{
"split": {
"field": "exec.stdout",
"separator": "[\r\n]+"
}
},
{
"foreach": {
"field": "exec.stdout",
"processor": {
"grok": {
"field": "_ingest._value",
"patterns": ["%{POSINT:hop_step}\\s+%{POSINT:rtt_1} ms\\s+ %{POSINT:rtt_2} ms\\s+ %{POSINT:rtt_3} ms\\s+%{USERNAME:hop_server_name}? \\[?%{IP:hop_ip}"],
"ignore_failure" : true
}
}
}
}
]
}
Grok works great and discards the non-matching lines, retaining the ones I like. But since foreach can only accept 1 processor, there's no way to capture those values, and they are overwritten by subsequent lines.
This seems like a common case; how can I do this?