OK I have been reading most of the morning and I have to just be missing something very simple.
To explain what I am trying to do.
1. Lets take the simple query index=* host=*test*|dedup host|table host
This will obviously give me a unique list of hosts.
2. Second Query index=* host=*test* "Bleebles"|dedup host|table host
This query will give me a unique list of hosts where the string "Bleebles" was found. (Obviously this is just example data)
What I am trying (And failing) at is marrying these two queries up, and returning ONLY hostnames that DO NOT return records with the string "Bleebles" but of course issue #1 is when I invert the logic on search #2 I get EVERY record that has been splunked and doesn't match (Which is literally all the data)
Can anyone help with the logic I am missing here, using the two very basic queries above how would I first generate the full host list (That's the easy part) but then print a deduped list of hostnames that did NOT return a result in query #2, thereby giving me an exceptions list?
Try something like this:
index=* host=*test* | eval hasString=if(match(_raw,"Bleebles"),1,0) | stats max(hasString) as hasString by host | where hasString=0 |table host
index=* host=*test* | where not match(_raw,"Bleebles")|dedup host|table host
This one still gives me the entire list (Not just the exceptions) but what I wrote does work, I just need to figure out why it takes so long to run and what I can do to improve it.
But at least it is accurate which is a start!
OK I think I may have finally figured this out, posting what I did in case anyone else comes across this down the line.
index=* host=*test* | join type=outer host [ search index=* host=*test* "Bleebles" | stats count by host ] | where isnull(count) | dedup host | table host | sort by host
This appears to be working so far!