Skip to main content

Hi All,

I have already created a custom parser that works well for JSON object coming through logs. However, I now need to update the parser to support JSON arrays. but I'm unsure how to loop through a JSON array.

Sample log:  [{"test": "testing","hostname":"hostname1"},{"test":"testing","hostname":"hostname2"}]

Any guidance or assistance on how to resolve this issue would be greatly appreciated.

Thank you!

Details on using "for" loops for looping through a JSON array are available here: https://cloud.google.com/chronicle/docs/reference/parser-syntax#for_loop

-mike


One of the most important things to do when looping through a "for" loop is to initialize the variables you use within the loop to null at the beginning of the loop.  

for index,record in records { mutate { replace => { "type_label" => "" "Id_label" => "" } } mutate { convert => { "index" => "string" } on_error => "index_conversion_failed" } mutate { replace => { "type_label.key" => "type_%{index}" "type_label.value" => "%{record.attributes.type}" } on_error => "type_not_found" }

In this example we are initializing the type_label to null.  If you reuse the variable without initializing it to null then you will get unpredictable results - every time you run the parser you may see different output.  Be VERY CAREFUL with this.  


Details on using "for" loops for looping through a JSON array are available here: https://cloud.google.com/chronicle/docs/reference/parser-syntax#for_loop

-mike


@mikewilusz Thanks for your answer, but that's not what I'm looking for. I know how to loop through a JSON array if it exists inside a JSON object. The issue here is that the ingested log is not a single JSON object; instead, it is an array of objects or you can assume this as batch of logs into single log. So, now I need to loop through the array of objects and create multiple events from a single ingested log.


Can you share a sample log?

 


Can you share a sample log?

 


@sudeep_singh I have updated post. You will find sample log in description. 


One of the most important things to do when looping through a "for" loop is to initialize the variables you use within the loop to null at the beginning of the loop.  

for index,record in records { mutate { replace => { "type_label" => "" "Id_label" => "" } } mutate { convert => { "index" => "string" } on_error => "index_conversion_failed" } mutate { replace => { "type_label.key" => "type_%{index}" "type_label.value" => "%{record.attributes.type}" } on_error => "type_not_found" }

In this example we are initializing the type_label to null.  If you reuse the variable without initializing it to null then you will get unpredictable results - every time you run the parser you may see different output.  Be VERY CAREFUL with this.  


@rajukg11Thanks for the answer. but, that's not something I am looking for. I have updated sample log in post description. Please have a look. that' might be helpful for you to understand my problem. 


You have to put the entire parser in your looping logic so it creates a UDM event for each event in your array. 

 


You have to wrap the log with a dummy variable and then parse it with json in this case.  I changed the log as this: {"x":[{"test": "testing","hostname":"hostname1"},{"test":"testing","hostname":"hostname2"}] } and use the x in the for loop.  The following code is not changing the log itself, and for that you have to add mutate gsub.

filter { json { source => "message" array_function => "split_columns" on_error => "not_a_json" } statedump{} if ![not_a_json] { for msg in x { mutate { replace => { "event" => "" } } mutate { replace => { "event.idm.read_only_udm.metadata.event_type" => "GENERIC_EVENT" "event.idm.read_only_udm.principal.hostname" => "%{msg.hostname}" } } mutate { merge => { "@output" => "event" } on_error => "event_generation_failure" } } } }