The configtracker index contains a json path of: data.changes{}.properties{}
In that path, there are numerous objects ...
data
changes
properties
+ ( contains name, old_value, new_value )
+ ( contains name, old_value, new_value )
+ ( contains name, old_value, new_value )
I've tried numerous ways of parsing data.changes{}.properties{} ... but am still finding myself unable to display the name, old_value, and new_value of each object beneath data->changes->properties ...
Ultimately, I'd like to be able to render a table of "name" where an old_value exists so that we can alert on changed correlation searches in ES.
ie: where "name" = search (and both old_value and new_value are not empty)
{ [-]
name: search
new_value: `sysmon` foo
old_value: `sysmon` bar
}
or: where "name" = cron_schedule (and both old_value and new_value are not empty)
{ [-]
name: cron_schedule
new_value: 6-56/10 * * * *
old_value: */10 * * * *
}
or: where a search schedule was enabled
{ [-]
name: enableSched
new_value: 1
old_value: 0
}
@yuanliu is on the right lines. Unless you want something from the changes level, the first mvexpand is redundant. Also, you still need to do a further spath to extract the fields you are interested in
| spath path=data.changes{}.properties{}
| mvexpand data.changes{}.properties{}
| spath input=data.changes{}.properties{}
| where isnotnull(old_value) AND isnotnull(new_value)
Thank you @yuanliu & @ITWhisperer ... this was quite helpful ...
the isnotnull doesn't seem to work where the values appear to be empty, but this did:
index=_configtracker component=ConfigChange earliest=-6h host=mysearchheads* data.path="/opt/splunk/etc/apps/*"
| spath path=data.changes{}.properties{}
| mvexpand data.changes{}.properties{}
| spath input=data.changes{}.properties{}
| table data.changes{}.stanza, name, old_value, new_value
| regex old_value="[A-Za-z0-9]"
| regex new_value="[A-Za-z0-9]"
Thank you very much.
You need to apply mvexpand to any array in the path. In your case, you have two nested arrays, data.changes{} and data.changes{}.properties{}. To reach them, you use spath. Something like
| spath path=data.changes{}
| mvexpand data.changes{}
| spath path=data.changes{}.properties{}
| mvexpand data.changes{}.properties{}
| where isnotnull(data.changes{}.properties{}.old_value)
@yuanliu is on the right lines. Unless you want something from the changes level, the first mvexpand is redundant. Also, you still need to do a further spath to extract the fields you are interested in
| spath path=data.changes{}.properties{}
| mvexpand data.changes{}.properties{}
| spath input=data.changes{}.properties{}
| where isnotnull(old_value) AND isnotnull(new_value)