Splunk Search

How to generate a conditional search based on time?

Path Finder

I need to figure out a way to execute one of two different search strings based on the time range in a first search.

If a sample is more than 2 weeks old, the associated lab data is stored in a summary index. [search1]
If a sample is less than 2 weeks old, the lab data will need to be live-calculated via a much more complicated search string (includes subsearch, join, dedup). [search2]

I tried to use multisearch, but since search2 contains non-streaming commands ( join & dedup), that didn't work.

Search1 and Search2 both return fields sample_name and sample_value, so not a single value. My understanding is that this prevents me from using eval/if based on _time or a time token from my search.

base search
| join sample_name
[ run either search1 or search2]
| table sample_name sample_value
0 Karma
1 Solution

Esteemed Legend

Like this:

base search
| join sample_name
[[|noop|stats count AS search | addinfo | eval search=if(info_max_time<relative_time(now(), "-14d@d"), "Search1 String Here", "Search2 String Here")]]
| table sample_name sample_value

View solution in original post

Path Finder

Thank you everyone for your answers.
I ended up going in a slightly different direction with my solution, but I've learned so many new things based on your collective input.

0 Karma

Esteemed Legend

So up-vote the useful answers and then pick the best one (or yours, this one) and click Accept to close the question.

Esteemed Legend

Try this:

|noop|stats count AS search | addinfo | eval search=if(info_max_time<relative_time(now(), "-14d@d"), "Search1 String Here", "Search2 String Here") | map search="search  base search
| join sample_name [ $search$ ]
| table sample_name sample_value"
0 Karma

Esteemed Legend

Like this:

base search
| join sample_name
[[|noop|stats count AS search | addinfo | eval search=if(info_max_time<relative_time(now(), "-14d@d"), "Search1 String Here", "Search2 String Here")]]
| table sample_name sample_value

View solution in original post

Path Finder

Are there any restrictions with using noop in a subsearch?
I tried this but got the error:
Error in 'SearchParser': Subsearches are only valid as arguments to commands. Error at position '195' of search query 'search index=...{snipped} {errorcontext = [ [|noop }'

0 Karma

Esteemed Legend

OK, see my other answer where I turn it inside out and use map instead of a nested subsearch.

0 Karma

Revered Legend

Here is how I'll try

Step1) create a saved search for each of search1 and search2, full query that you want to execute on the subsearch. Just a simple saved search. Say the names are search1 and search2 itself.

Step2) update your query like this

base search
 | join sample_name
 [ | savedsearch [| gentimes start=-1 | addinfo | eval search=if((info_max_time-info_min_time)>14*86400"search1","search2") | table search ] nosubstitution=t]
 | table sample_name sample_value

The addinfo command adds the fields info_min_time and info_max_time which are the earliest and latest value of the time range that you've selected. If will run subsearch | savedsearch search1 if the selected time range is more than 2 weeks/14 days or will run | savedsearch search2 otherwise.

0 Karma

SplunkTrust
SplunkTrust

The question says "more than 2 weeks old" is the criteria, so you are probably needing something like if(info_max_time <= info_search_time -14*86400,...

0 Karma

Legend

@mstark31, here is one way to do it...

1) Whatever is the timerange in the first search, you can define a Time input for the same. I have used tok_time as time in my example.

  <fieldset submitButton="false">
    <input type="time" token="tok_time" searchWhenChanged="true">
      <label>Select Time</label>
      <default>
        <earliest>-15m</earliest>
        <latest>now</latest>
      </default>
    </input>
  </fieldset>

2) Run a dumy search to compare selected Earliest and Latest Time and set the index/environment name as summary or realtime (ideally to be passed to a macro to set criteria of the base search etc.)

  <!-- Dummy Search to set index name for main query based on time range selected -->
  <search>
    <query>| makeresults
  | eval now=_time</query>
      <earliest>$tok_time.earliest$</earliest>
      <latest>$tok_time.latest$</latest>
    <sampleRatio>1</sampleRatio>
    <preview>
          <!-- Compare Todays Date with Earliest Time in the Time Range and 
         if greater than 2 week (2*7*24*60*60=1209600 seconds) set Summary 
         else set Realtime index-->
          <condition match="$result.now$-$job.searchEarliestTime$>1209600">
            <set token="selectedIndex">summary</set>
          </condition>
          <condition>
            <set token="selectedIndex">realtime</set>
          </condition>
    </preview>
</search>

Finally use the $selectedIndex$ token to set index to summary. Ideally through a macro which takes string values for environment as a paramter, this we you can set other criteria for base search if you want like summary index will have sourcetype as stash.

<!-- Use $selectedIndex$ token to set index in main search-->
<search>
  <query> base search
  | join sample_name
    [ `setindex($selectedIndex$)`
      |<remaining Search> ]
  | table sample_name sample_value
  </query>
</search>

PS: One more condition you can try out is to see if Earliest and Latest time spans for more than two weeks then go for Summary Index

 <condition match="$job.searchLatestTime$-$job.searchEarliestTime$>1209600">
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma
State of Splunk Careers

Access the Splunk Careers Report to see real data that shows how Splunk mastery increases your value and job satisfaction.

Find out what your skills are worth!