<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: How to extract events from multi-level json? in Splunk Search</title>
    <link>https://community.splunk.com/t5/Splunk-Search/How-to-extract-events-from-multi-level-json/m-p/328650#M97829</link>
    <description>&lt;P&gt;I'm not sure I have a better approach for you, but I think I have something at least.  I wonder if spath can do more than I know how to use it, but might be worth looking into.&lt;/P&gt;

&lt;P&gt;I know when I ingest json like this, I try to put each result in its own event, but that may not be an option or may not make sense with this data.&lt;/P&gt;

&lt;P&gt;That said, I'm trying to put them in their own event with spl instead.  I use sed to create a delimiter (|) where I want it, and then split on the delimiter.  That will get me an array of runs.  Making sure I have the testId field extracted as well, i can then use mvexpand to put each run in its own event.&lt;/P&gt;

&lt;P&gt;Then I can use spath to pull that run apart, zip all of the step data together in one array and expand one more time.  A simple rex to separate the step data, and then table everything together.&lt;/P&gt;

&lt;P&gt;Not sure if this will work for you, especially if you have a ton more data to tie together, but maybe it least give you some ideas.&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;source="test.json" sourcetype="_json"
| rex "testId\":\s*\"(?&amp;lt;testId&amp;gt;[^\"]+)"
| rex mode=sed "s/(\{[^\"]*\"runId)/|\1/g"
| eval runs=split(_raw,"|")
| eval runs=mvindex(runs,1,mvcount(runs)-1)
| mvexpand runs
| fields testId, runs
| spath input=runs
| rename steps{}.* as *
| eval myevent = mvzip(name,startTime), myevent=mvzip(myevent,result)
| fields testId, runId, myevent
| mvexpand myevent
| rex field=myevent "^(?&amp;lt;name&amp;gt;[^,]+),(?&amp;lt;startTime&amp;gt;[^,]+),(?&amp;lt;result&amp;gt;.+)"
| table testId, runId, name, startTime,result
&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Sat, 27 Jan 2018 01:01:52 GMT</pubDate>
    <dc:creator>maciep</dc:creator>
    <dc:date>2018-01-27T01:01:52Z</dc:date>
    <item>
      <title>How to extract events from multi-level json?</title>
      <link>https://community.splunk.com/t5/Splunk-Search/How-to-extract-events-from-multi-level-json/m-p/328649#M97828</link>
      <description>&lt;P&gt;Please believe me &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt; that I have searched for an answer until my index finger bled (pun intended, but seriously...I have searched).&lt;BR /&gt;&lt;BR /&gt;
I have the JSON (below) &lt;STRONG&gt;&lt;EM&gt;already indexed&lt;/EM&gt;&lt;/STRONG&gt;.  (Re-indexing is a very last resort.) The fields appear as:&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;testId, results{}.*, and results{}.steps{}.\
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;I need one event per  &lt;STRONG&gt;result&lt;/STRONG&gt; with the following fields:&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt; testId, runId, startTime, result, name
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;The &lt;STRONG&gt;runId&lt;/STRONG&gt; value is unique within &lt;STRONG&gt;results{}&lt;/STRONG&gt;.  The &lt;STRONG&gt;name&lt;/STRONG&gt; value is unique within &lt;STRONG&gt;results{}.steps{}&lt;/STRONG&gt; (and the names are repeated with each run, ie "CASE1", ..., "CASE9")&lt;/P&gt;

&lt;P&gt;I understand the basics of mvzip and mvexpand. I'm open to a different approach if possible because (1) I can't get it to work with multiple levels and (2) there are actually 14 other fields not shown below, which are spread through each level.&lt;/P&gt;

&lt;P&gt;Is using crazy long mvzip and eval commands my only option? If so, how does it work with multiple levels?&lt;/P&gt;

&lt;P&gt;Thanks!&lt;/P&gt;

&lt;HR /&gt;

&lt;P&gt;Sample JSON&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;{
  "testId": "perfScenario1",
  "results": [
    {
      "runId": "GUID1",
      "steps": [
        {
          "startTime": "2018-01-20T00:00:00.000Z",
          "result": "1.3",
          "name": "CASE1"
        },
        {
          "startTime": "2018-01-20T00:02:00.000Z",
          "result": "0.2",
          "name": "CASE2"
        },
        ...
      ]
    },
    {
      "runId": "GUID2",
      "steps": [
        {
          "startTime": "2018-01-20T06:00:00.000Z",
          "result": "1.3",
          "name": "CASE1"
        },
        {
          "startTime": "2018-01-20T06:00:00.000Z",
          "result": "0.2",
          "name": "CASE2"
        },
        ...
      ]
    },
    ...
  ]
}
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 26 Jan 2018 20:51:23 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Search/How-to-extract-events-from-multi-level-json/m-p/328649#M97828</guid>
      <dc:creator>mgallacher</dc:creator>
      <dc:date>2018-01-26T20:51:23Z</dc:date>
    </item>
    <item>
      <title>Re: How to extract events from multi-level json?</title>
      <link>https://community.splunk.com/t5/Splunk-Search/How-to-extract-events-from-multi-level-json/m-p/328650#M97829</link>
      <description>&lt;P&gt;I'm not sure I have a better approach for you, but I think I have something at least.  I wonder if spath can do more than I know how to use it, but might be worth looking into.&lt;/P&gt;

&lt;P&gt;I know when I ingest json like this, I try to put each result in its own event, but that may not be an option or may not make sense with this data.&lt;/P&gt;

&lt;P&gt;That said, I'm trying to put them in their own event with spl instead.  I use sed to create a delimiter (|) where I want it, and then split on the delimiter.  That will get me an array of runs.  Making sure I have the testId field extracted as well, i can then use mvexpand to put each run in its own event.&lt;/P&gt;

&lt;P&gt;Then I can use spath to pull that run apart, zip all of the step data together in one array and expand one more time.  A simple rex to separate the step data, and then table everything together.&lt;/P&gt;

&lt;P&gt;Not sure if this will work for you, especially if you have a ton more data to tie together, but maybe it least give you some ideas.&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;source="test.json" sourcetype="_json"
| rex "testId\":\s*\"(?&amp;lt;testId&amp;gt;[^\"]+)"
| rex mode=sed "s/(\{[^\"]*\"runId)/|\1/g"
| eval runs=split(_raw,"|")
| eval runs=mvindex(runs,1,mvcount(runs)-1)
| mvexpand runs
| fields testId, runs
| spath input=runs
| rename steps{}.* as *
| eval myevent = mvzip(name,startTime), myevent=mvzip(myevent,result)
| fields testId, runId, myevent
| mvexpand myevent
| rex field=myevent "^(?&amp;lt;name&amp;gt;[^,]+),(?&amp;lt;startTime&amp;gt;[^,]+),(?&amp;lt;result&amp;gt;.+)"
| table testId, runId, name, startTime,result
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 27 Jan 2018 01:01:52 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Search/How-to-extract-events-from-multi-level-json/m-p/328650#M97829</guid>
      <dc:creator>maciep</dc:creator>
      <dc:date>2018-01-27T01:01:52Z</dc:date>
    </item>
  </channel>
</rss>

