Splunk Search

How to find max(_time) for sourcetypes & host by sourcetype host?

sjringo
Contributor

I found the following search to identify Missing / New sourcetypes and made a few changes.
I am getting data and my next enhancement is to add the latest date/time a sourcetype was 'seen'.

Here is the search I am starting with:

index=anIndex earliest=-4d latest=now
| eval recent=if(_time>(now()-129600 ),1,0) ```<--- No Logs in 1.5 Days ```
| stats count(eval(recent=1)) AS CurrentCount count(eval(recent=0)) AS HistoricalCount BY sourcetype host
| where ( (CurrentCount < 1 AND HistoricalCount > 0) OR ( CurrentCount > 0 AND HistoricalCount < 1)) ```<--- Missing & New```
| eval status=case(CurrentCount > 0 AND HistoricalCount > 0, "OK",
CurrentCount < 1 AND HistoricalCount > 0, "MISSING",
CurrentCount > 0 AND HistoricalCount < 1, "NEW",
1=1,"Unknown" )
| sort sourcetype
| table status host sourcetype CurrentCount HistoricalCount

I think this is returning the last time a sourcetype was seen:

index=anIndex earliest=-2d latest=now
| stats max(_time) as last_searched by sourcetype host
| eval lastTime=strftime(last_searched, "%m/%d/%y %H:%M:%S")
| sort sourcetype host
| table host sourcetype lastTime

But, when I try to add these two lines into my original query I do not get any data ?

| stats max(_time) as last_searched by sourcetype host
| eval lastTime=strftime(last_searched, "%m/%d/%y %H:%M:%S")

I have tried placing it in several different places but always get 'No Results found...'
What am I missing ?

Labels (2)
0 Karma
1 Solution

yeahnah
Motivator

Hi @sjringo 

Sorry, I had not accounted for you count logic.  You can use tstats like this and then apply some logic to the results.

| tstats
    max(_time) AS max_current_time
    count AS CurrentCount
  WHERE index=anIndex earliest=-129600 latest=now
  BY sourcetype host
| append [| tstats
    max(_time) AS max_historical_time
    count AS HistoricalCount
  WHERE index=anIndex earliest=-4d latest=-129600
  BY sourcetype host ]
| stats values(*) AS * BY sourcetype host
| foreach *_time [ eval <<FIELD>>_hm=strftime('<<FIELD>>', "%c") ]  ``` not really needed ```
| eval _time=if(max_current_time > max_historical_time OR isnull(max_historical_time), max_current_time, max_historical_time)
| eval status=case(CurrentCount > 0 AND HistoricalCount > 0, "OK", isnull(CurrentCount), "MISSING", isnull(HistoricalCount), "NEW", true(), "Unknown" )
| sort sourcetype
| rename status AS Status, host AS Host, sourcetype AS "Source Type", CurrentCount AS "Log Entries in 1.5 Days", HistoricalCount AS "Log Entries over 1.5 Days"
| table Status Host "Source Type" "Log Entries in 1.5 Days" "Log Entries over 1.5 Days" _time

 It might not be perfect but will hopefully get you going

View solution in original post

yeahnah
Motivator

Hi @sjringo 

In the first query the _time field is not a result field, so you obviously cannot use it.  Here's a modified query that also returns the max time for each host sourcetype.  I've also demonstrated how to use the tstats command to make the query x100 times quicker and more efficient, but you can revert back to scanning _raw events if you prefer.

| tstats max(_time) AS _time WHERE index=anIndex earliest=-4d latest=now BY sourcetype host 
| eval recent=if(_time>(now()-129600 ),1,0) ```<--- No Logs in 1.5 Days ```
| stats max(_time) AS max_time count(eval(recent=1)) AS CurrentCount count(eval(recent=0)) AS HistoricalCount BY sourcetype host
| where ( (CurrentCount < 1 AND HistoricalCount > 0) OR ( CurrentCount > 0 AND HistoricalCount < 1)) ```<--- Missing & New```
| eval status=case(CurrentCount > 0 AND HistoricalCount > 0, "OK",
    CurrentCount < 1 AND HistoricalCount > 0, "MISSING",
    CurrentCount > 0 AND HistoricalCount < 1, "NEW",
    1=1,"Unknown" )
| sort sourcetype
| table status host sourcetype CurrentCount HistoricalCount max_time
| stats max(max_time) as last_searched by sourcetype host
| eval lastTime=strftime(last_searched, "%m/%d/%y %H:%M:%S")

  Hope that helps

sjringo
Contributor

Ok, I had to massage your posting somewhat to work with what I was looking for.

I am aware of TSTATS but struggling to get it to work for the query that I am starting with ?

Here is what I have working:

index=anIndex earliest=-4d latest=now

| eval recent=if(_time>(now()-129600 ),1,0) ```<--- No Logs in 1.5 Days ```

| stats max(_time) AS max_time count(eval(recent=1)) AS CurrentCount count(eval(recent=0)) AS HistoricalCount BY sourcetype host

| where ( (CurrentCount < 1 AND HistoricalCount > 0) OR ( CurrentCount > 0 AND HistoricalCount < 1)) ```<--- Missing & New```

| eval status=case(CurrentCount > 0 AND HistoricalCount > 0, "OK", CurrentCount < 1 AND HistoricalCount > 0, "MISSING", CurrentCount > 0 AND HistoricalCount < 1, "NEW", 1=1,"Unknown" )

| eval lastTime=strftime(max_time, "%m/%d/%y %H:%M:%S")

| sort sourcetype

| rename status AS Status, host AS Host, sourcetype AS "Source Type", CurrentCount AS "Log Entries in 1.5 Days", HistoricalCount AS "Log Entries over 1.5 Days", lastTime AS "Last Log Entry"

| table Status Host "Source Type" "Log Entries in 1.5 Days" "Log Entries over 1.5 Days" "Last Log Entry"

Any help in getting it to work with TSTATS would be appreciated...

0 Karma

yeahnah
Motivator

Hi @sjringo 

Sorry, I had not accounted for you count logic.  You can use tstats like this and then apply some logic to the results.

| tstats
    max(_time) AS max_current_time
    count AS CurrentCount
  WHERE index=anIndex earliest=-129600 latest=now
  BY sourcetype host
| append [| tstats
    max(_time) AS max_historical_time
    count AS HistoricalCount
  WHERE index=anIndex earliest=-4d latest=-129600
  BY sourcetype host ]
| stats values(*) AS * BY sourcetype host
| foreach *_time [ eval <<FIELD>>_hm=strftime('<<FIELD>>', "%c") ]  ``` not really needed ```
| eval _time=if(max_current_time > max_historical_time OR isnull(max_historical_time), max_current_time, max_historical_time)
| eval status=case(CurrentCount > 0 AND HistoricalCount > 0, "OK", isnull(CurrentCount), "MISSING", isnull(HistoricalCount), "NEW", true(), "Unknown" )
| sort sourcetype
| rename status AS Status, host AS Host, sourcetype AS "Source Type", CurrentCount AS "Log Entries in 1.5 Days", HistoricalCount AS "Log Entries over 1.5 Days"
| table Status Host "Source Type" "Log Entries in 1.5 Days" "Log Entries over 1.5 Days" _time

 It might not be perfect but will hopefully get you going

sjringo
Contributor

Getting results using your updated TSTATS query.  I am going to need a little time to compare data from both queries and mash up the results just to figure out if both results are returning the same results, etc...

But the speed of the query results is better.  a few seconds compared to 15 minutes !!!

TSTATS is still a little bit fuzzy but having something that works will help me going forward...

Thanks for your help ...

0 Karma
Get Updates on the Splunk Community!

Customer Experience | Splunk 2024: New Onboarding Resources

In 2023, we were routinely reminded that the digital world is ever-evolving and susceptible to new ...

Celebrate CX Day with Splunk: Take our interactive quiz, join our LinkedIn Live ...

Today and every day, Splunk celebrates the importance of customer experience throughout our product, ...

How to Get Started with Splunk Data Management Pipeline Builders (Edge Processor & ...

If you want to gain full control over your growing data volumes, check out Splunk’s Data Management pipeline ...