I stumbled upon this 6 year old post https://discuss.elastic.co/t/keeping-global-variables-in-ls/39908 which describes the exact same scenario as mine.
After following this post, I was able to get partial success using ruby filter.
My progress. so far:
-
Using ruby filter, store the value of task_name field in a variable called @@taskname that will persist for later user.
-
Using GROK, search for events where you want to insert the above field.
-
Field inserted in all the lines that match in step 2.
What I am stuck at:
-
"_grokparsefailure" tag gets inserted in all events, even though the patterns have matched and the task_name field was inserted.
-
When I run Logstash again, then all 4 events get the same task_name inserted. Actual behavior should be, 2 events get task_name as "Formatting xfs filesystem" and the other 2 should get the. 2nd task name. If I run it again, I get one of the events getting a null value. Any ideas for the reason behind this random behaviour?
I have made sure to set the Logstash workers to '1' for thread safety.
Below is my conf
## Parse Logs
input {
file {
path => "/var/log/dummy.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
grok {
patterns_dir => ["./patterns"]
match => { "message" => "%{GROK_PATTERN}TASK%{SPACE}\[%{WORD:role}%{SPACE}\:%{SPACE}%{GREEDYDATA:task_name}\]" }
}
## Store the value in @@taskname
ruby {
init => '@@taskname = ""'
code => '
if event.get("task_name")
@@taskname = event.get("task_name")
end'
}
## Match events where the @@taskname should be added
grok {
patterns_dir => ["./patterns"]
match => { "message" => "%{GROK_PATTERN}%{WORD:task_status}\:%{SPACE}\[%{HOSTNAME:hostname}.*" }
}
## Insert the field
if [task_status] =~ "changed" {
ruby { code => 'event.set("task_name", @@taskname)' }
}
}
output {
elasticsearch {
hosts => ["TESTVM-1:9200"]
index => "dummy_logs"
}
stdout {}
}