Getting Data In

need help with spath for json Array

att35
Builder

Hi,

Need some help with the following JSON data.

 ModifiedProperties: [ [-]
     { [-]
       Name: Group.ObjectID
       NewValue: 111111-2222222-333333-444444
       OldValue:
     }
     { [-]
       Name: Group.DisplayName
       NewValue: Group A
       OldValue:
     }
     { [-]
       Name: Group.WellKnownObjectName
       NewValue:
       OldValue:
     }
   ]

I want to extract the 2nd set of values for each event such that Group.DisplayName can become a field in itself, e.g. Group.DisplayName.NewValue=A, Group.DisplayName.OldValue=B.

But right now, default extraction is doing something like this

 

json_array_default.png

 

How can I create KV pairs for Group.DisplayName within this JSON array? I tried few combinations using spath but was not successful.

 

Thank you

Labels (2)
Tags (1)
0 Karma

tscroggins
Influencer

Hi @att35,

Assuming _raw is properly formatted--and both your original Splunk Web screenshot and your new formatted event imply it is--you can use a combination of eval and spath commands to iterate over the array and create new fields:

| eval tmp="{".mvjoin(mvmap(json_array_to_mv(json_extract(json(_raw), "ModifiedProperties")), "\"".spath(_raw, "Name").".NewValue\":\"".spath(_raw, "NewValue")."\",\"".spath(_raw, "Name").".OldValue\":\"".spath(_raw, "OldValue")."\""), ",")."}"
| spath input=tmp
| fields - tmp

The eval command creates a tmp field with the following value:

{"Group.ObjectID.NewValue":"111111-2222222-333333-444444","Group.ObjectID.OldValue":"","Group.DisplayName.NewValue":"Group A","Group.DisplayName.OldValue":"","Group.WellKnownObjectName.NewValue":"","Group.WellKnownObjectName.OldValue":""}

The spath command extracts the *.NewValue and *.OldValue fields from the tmp field.

Note that empty values will be empty strings and null values will have the string value 'null'. If you want null values to be null fields, you can use the foreach command the nullif() eval function to override them:

| foreach Group.*.NewValue [ eval "<<FIELD>>"=nullif('<<FIELD>>', "null") ]
| foreach Group.*.OldValue [ eval "<<FIELD>>"=nullif('<<FIELD>>', "null") ]

Search memory usage may be higher when using temporary fields to store and manipulate JSON objects in this way, and you may need to run multiple searches over smaller time ranges, depending on your user's search limits and workload policy.

0 Karma

PickleRick
SplunkTrust
SplunkTrust

This is again an example of data formatted in a way non-friendly to Splunk (at least in your case). While you can use @ITWhisperer 's search to get your results, bear in mind that it's not field extraction that happens in this search, it's data manipulation. You don't _have_ the fields in your data, you have to create them manually by manipulating and correlating other data extracted from events.

It is one of the hard decisions that must be made when exporting data do json. You have two possible approaches - one is to dynamically name the fields like

{ "Group1":  {  "NewValue":"a", "OldValue":"b" }, "Group2": { "NewValue":"c", "OldValue":"d" }}

Another is - as is in your case - to have what you have as field name, exported as a "label" to a constant name.

[ { "Name": "Group1", "NewValue": "a", "OldValue":"b"}, { " Name": "Group1", "NewValue": "c", "OldValue": "d" }}]

Each of those approaches has its pros and cons.

The first form is not very friendly if you want to do some aggregations and other similar manipulations because your fields are not statically named so you might have to do some strange things with foreach and wildcarding in stats when manipulating them. But you can search with conditions like "Group1.NewValue=a". But you can't do "stats count by GroupName" or something like that

The second form though doesn't "tie" values with the name - Splunk doesn't support structured data, it flattens the JSONs and XMLs on parsing - so you have to bend over backwards to get your specific values for interesting "field" and you can't simply use conditions like "Group1.NewValue=a" in your search. but you can do "stats count by Name".

So it's always something. One way or another your data format will end up being a burden.

 

0 Karma

ITWhisperer
SplunkTrust
SplunkTrust

Please share the raw text of your events, anonymised appropriately, in a code block, not a picture, to assist volunteers designing a solution to meet your requirements.

0 Karma

att35
Builder

Thanks @ITWhisperer 

I have updated the original post with event text.

0 Karma

ITWhisperer
SplunkTrust
SplunkTrust

What you have posted is not the raw text, and is therefore not valid JSON!

Having said that, try something like this

| spath ModifiedProperties{} output=ModifiedProperties
| eval ModifiedProperties=mvindex(ModifiedProperties,1)
| spath input=ModifiedProperties
| eval {Name}.NewValue=NewValue
| eval {Name}.OldValue=OldValue
| fields - Name NewValue OldValue ModifiedProperties
0 Karma
Get Updates on the Splunk Community!

New This Month in Splunk Observability Cloud - Metrics Usage Analytics, Enhanced K8s ...

The latest enhancements across the Splunk Observability portfolio deliver greater flexibility, better data and ...

Alerting Best Practices: How to Create Good Detectors

At their best, detectors and the alerts they trigger notify teams when applications aren’t performing as ...

Discover Powerful New Features in Splunk Cloud Platform: Enhanced Analytics, ...

Hey Splunky people! We are excited to share the latest updates in Splunk Cloud Platform 9.3.2408. In this ...