<?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: Extracting timebased information from multiple joins in Splunk Search</title>
    <link>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369486#M108871</link>
    <description>&lt;P&gt;@woodcock - (snort) - They annoy me every time I'm looking up a point of &lt;CODE&gt;join&lt;/CODE&gt; syntax, because I &lt;STRONG&gt;know&lt;/STRONG&gt; what verb I need to use and all that &lt;EM&gt;relative&lt;/EM&gt; stuff should be in a linked annex or something.  &lt;/P&gt;

&lt;P&gt;But, more and more, when I post here to explain that, no, &lt;CODE&gt;join&lt;/CODE&gt; is not your linkage verb of first resort, I have to sigh at the appropriateness of it all.  &lt;/P&gt;</description>
    <pubDate>Wed, 16 Aug 2017 01:30:34 GMT</pubDate>
    <dc:creator>DalJeanis</dc:creator>
    <dc:date>2017-08-16T01:30:34Z</dc:date>
    <item>
      <title>Extracting timebased information from multiple joins</title>
      <link>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369483#M108868</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;

&lt;P&gt;I am trying to join information returned by an index, with different filters, to each other and I am unable to get correct information and need help in sorting it out.&lt;/P&gt;

&lt;P&gt;So, I have an index that contains some events such as login, logoff, logonReject, InformationFlow etc. There is no particular sequence in which these events happen, i.e. a logged in user can login again without logging off.&lt;/P&gt;

&lt;P&gt;Now I want to join these events in such a way that they appear as following in the same row for a particular user:&lt;BR /&gt;
Time of InformationFlow, Time of Logoff, Time of Logon, Time of Logon Reject. &lt;/P&gt;

&lt;P&gt;I want only the first logofff, logon, logonReject event after every InformationFlow event.&lt;/P&gt;

&lt;P&gt;My query looks something like below:&lt;/P&gt;

&lt;P&gt;*&lt;BR /&gt;
index="xyZ" source=events.log ("Event=InformationFlow") | table UserId, EventTime as InformationFlowTime&lt;/P&gt;

&lt;P&gt;| join UserId type=left usetime=true earlier=false max=0 [search index="xyZ" source=events.log ("Event=Logoff") |  table UserId, EventTime as LogoffTime] &lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;| join UserId type=left usetime=true earlier=false max=0 [search index="xyZ" source=events.log ("Event=Logon") |  table UserId, EventTime as LogonTime]
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;HR /&gt;

&lt;PRE&gt;&lt;CODE&gt;| join UserId type=left usetime=true earlier=false max=0 [search index="xyZ" source=events.log ("Event=LogonReject") |  table UserId, EventTime as LogonReject]
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;HR /&gt;

&lt;PRE&gt;&lt;CODE&gt;| table UserId, InformationFlowTime, LogoffTime, LogonTime, LogonReject
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;*&lt;/P&gt;

&lt;P&gt;Now the problem is, the query above gives me all possible combinations of InformationFlowTime with LogonTime, LogoffTime etc whereas I want only the first LogonTime, LogoffTime, LogonRejects after each InformationFlow type of event.&lt;BR /&gt;
if I remove &lt;STRONG&gt;max=0&lt;/STRONG&gt; from the query, it just gives me the most recent LogonTime, LogoffTime etc  because I am using &lt;STRONG&gt;earlier=false&lt;/STRONG&gt; in the join.&lt;/P&gt;

&lt;P&gt;Can someone help tell me how I can join the data in the right order that they appear? I am running out of ideas here.&lt;/P&gt;

&lt;P&gt;Thanks,&lt;BR /&gt;
TG&lt;/P&gt;</description>
      <pubDate>Tue, 15 Aug 2017 07:37:46 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369483#M108868</guid>
      <dc:creator>targoyal</dc:creator>
      <dc:date>2017-08-15T07:37:46Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting timebased information from multiple joins</title>
      <link>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369484#M108869</link>
      <description>&lt;P&gt;I find it very annoying that the first two pages in the documentation for &lt;CODE&gt;join&lt;/CODE&gt; are not about how to use &lt;CODE&gt;join&lt;/CODE&gt;, but a description of all the different things you can use &lt;STRONG&gt;instead&lt;/STRONG&gt; of &lt;CODE&gt;join&lt;/CODE&gt;.    &lt;/P&gt;

&lt;P&gt;There's a reason.&lt;/P&gt;

&lt;P&gt;When approaching data in splunk, you need to start with the events, not the relations between the events.&lt;/P&gt;

&lt;P&gt;&lt;STRONG&gt;THROWING THEM ALL IN THE POT&lt;/STRONG&gt;&lt;/P&gt;

&lt;P&gt;You want to link each &lt;CODE&gt;InformationFlow&lt;/CODE&gt; event with certain the other events.  So, let's start by throwing &lt;STRONG&gt;all&lt;/STRONG&gt; those events in a pot...&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;index="xyZ" source=events.log ("Event=InformationFlow" OR "Event=Logoff" OR 
                               "Event=Logon" OR "Event=LogonReject" ) 
| rename COMMENT as "limit to the fields we want, and set the time fields based on event"
| fields UserId, Event, EventTime
| eval timetype=Event."Time"
| eval {timetype}=EventTime
| rename COMMENT as "now we have all the events present, and the times set"
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;That brackets thing &lt;CODE&gt;{xxx}=&lt;/CODE&gt; is just a tricky way of writing this following chunk of code, which is how we usually do it, because pulling data from differential records isn't normally so simple a pattern.  However, you have a very simple fact pattern, so it makes the above elegant little code snippet possible.  You might prefer the following, just because it is more "normal" to read....&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;| rename COMMENT as "this does the same thing as the above stuff, a different way."
| rename COMMENT as "limit to the fields we want, and set the time fields based on event"
| fields UserId, Event, EventTime
| eval InformationFlowTime=if(Event="InformationFlow",EventTime,null())
| eval LogoffTime=if(Event="Logoff",EventTime,null())
| eval LogonTime=if(Event="Logon",EventTime,null())
| eval LogonRejectTime=if(Event="LogonReject",EventTime,null())
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;Now that they are all in the pot, let's stir, shall we?  &lt;/P&gt;

&lt;P&gt;&lt;STRONG&gt;STIRRING UNTIL THEY'RE SOUP&lt;/STRONG&gt;&lt;/P&gt;

&lt;P&gt;We need to figure out which of the various records are relevant.  You have said that you only want the first records of each kind AFTER the &lt;CODE&gt;InformationFlow&lt;/CODE&gt; record. So, let's &lt;CODE&gt;sort&lt;/CODE&gt; the records into order, copy the latest &lt;CODE&gt;InformationFlowTime&lt;/CODE&gt; down onto all the following records, and then finally pick the lowest time for each of the relevant types of record.  &lt;/P&gt;

&lt;P&gt;Some might be &lt;CODE&gt;null&lt;/CODE&gt;; for example, if there are no &lt;CODE&gt;LogonReject&lt;/CODE&gt; records between two &lt;CODE&gt;InformationFlow&lt;/CODE&gt; records, then the &lt;CODE&gt;LogonRejectTime&lt;/CODE&gt; for that &lt;CODE&gt;InformationFlow&lt;/CODE&gt; record will be &lt;CODE&gt;null&lt;/CODE&gt;.&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;| rename COMMENT as "now we have all the events present, and the times set"
| sort 0 UserId, EventTime
| streamstats prior(InformationFlowTime) as PriorInf  by UserId
| eventstats min(LogoffTime) as minLogoff, min(LogonTime) as minLogon, min(LogonRejectTime) as minReject by UserId PriorInf

| rename COMMENT as "and finally, kill everything that isn't an information flow record"
| search Event="InformationFlow"
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;HR /&gt;

&lt;P&gt;&lt;STRONG&gt;MORE COMPLICATED STEWS&lt;/STRONG&gt;&lt;/P&gt;

&lt;P&gt;Now, if an &lt;CODE&gt;InformationFlow&lt;/CODE&gt; record was something that happened  &lt;STRONG&gt;while&lt;/STRONG&gt; someone was logged on, and you needed the immediate prior &lt;CODE&gt;Logon&lt;/CODE&gt; and the immediate following &lt;CODE&gt;Logoff&lt;/CODE&gt;, then you'd do the above procedure once in each direction for the relevant type of records. &lt;CODE&gt;sort -&amp;gt; streamstats -&amp;gt; eventstats -&amp;gt; (sort or reverse) -&amp;gt; streamstats -&amp;gt; eventstats&lt;/CODE&gt;.&lt;/P&gt;

&lt;P&gt;You could also do intermediate &lt;CODE&gt;eval&lt;/CODE&gt;s and &lt;CODE&gt;streamstats&lt;/CODE&gt; or &lt;CODE&gt;eventstats&lt;/CODE&gt; processing if you only wanted the events that were in a certain order... for instance, if you wanted &lt;CODE&gt;LogonRejects&lt;/CODE&gt; only &lt;STRONG&gt;before&lt;/STRONG&gt; the first successful &lt;CODE&gt;Logon&lt;/CODE&gt; after each &lt;CODE&gt;InformationFlow&lt;/CODE&gt;, and you only want &lt;CODE&gt;Logoffs&lt;/CODE&gt; &lt;STRONG&gt;after&lt;/STRONG&gt; the first successful &lt;CODE&gt;Logon&lt;/CODE&gt;.  &lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;| rename COMMENT as "now we have all the events present, and the times set"
| sort 0 UserId, EventTime
| streamstats prior(InformationFlowTime) as PriorInf  by UserId
| eventstats min(LogonTime) as minLogon, min(LogonRejectTime) as minReject by UserId PriorInf
| eval minReject = if (minReject &amp;gt; minLogon,null(),minReject)
| search Event!="LogonReject"
| eval LogoffTime=if(LogoffTime&amp;lt;minLogon,null(),LogoffTime)
| eventstats min(LogoffTime) as minLogoff by UserId PriorInf

| rename COMMENT as "and finally, kill everything that isn't an information flow record"
| search Event="InformationFlow"
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;There are various other patterns that are quite useful, but the above will help you with your current use case.  &lt;/P&gt;

&lt;P&gt;Happy splunking!&lt;/P&gt;</description>
      <pubDate>Tue, 15 Aug 2017 14:28:37 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369484#M108869</guid>
      <dc:creator>DalJeanis</dc:creator>
      <dc:date>2017-08-15T14:28:37Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting timebased information from multiple joins</title>
      <link>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369485#M108870</link>
      <description>&lt;P&gt;s/annoying/highly agreeable/g&lt;/P&gt;</description>
      <pubDate>Tue, 15 Aug 2017 23:27:38 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369485#M108870</guid>
      <dc:creator>woodcock</dc:creator>
      <dc:date>2017-08-15T23:27:38Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting timebased information from multiple joins</title>
      <link>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369486#M108871</link>
      <description>&lt;P&gt;@woodcock - (snort) - They annoy me every time I'm looking up a point of &lt;CODE&gt;join&lt;/CODE&gt; syntax, because I &lt;STRONG&gt;know&lt;/STRONG&gt; what verb I need to use and all that &lt;EM&gt;relative&lt;/EM&gt; stuff should be in a linked annex or something.  &lt;/P&gt;

&lt;P&gt;But, more and more, when I post here to explain that, no, &lt;CODE&gt;join&lt;/CODE&gt; is not your linkage verb of first resort, I have to sigh at the appropriateness of it all.  &lt;/P&gt;</description>
      <pubDate>Wed, 16 Aug 2017 01:30:34 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Search/Extracting-timebased-information-from-multiple-joins/m-p/369486#M108871</guid>
      <dc:creator>DalJeanis</dc:creator>
      <dc:date>2017-08-16T01:30:34Z</dc:date>
    </item>
  </channel>
</rss>

