I have a set of rules in one of my sourcetypes:
Rule Expr Value
Rule0 <0 Value0
Rule1 =1 Value1
...
Rule5 >=5 Value5
As long as field Expr is a mathematical expression, I want to incorporate it as a part of a search:
sourcetype="Logs" | ... | sourcetype="Rules" Rule=<calculated> | where LogError <Expr goes here>
i.e. to substitute the part of the query with the field value.
So after substitution I would have (say, Rule5 was hit):
sourcetype="Logs" | ... | sourcetype="Rules" Rule="Rule5" | where LogError >= 5 | table Value
but ">= 5" is dynamically formatted based on search results, not hardcoded in the query text.
I guess there could be some sort of search string formatting, but didn't find anything except "map" command. However, I'm not really sure how to use map here.
How is that possible to do such substitution?
Is there any well-known Splunk command or practice?
You can do this with case, its not dynamic, but far quicker than using a map to kick of a search for each of your operators.
1st, clean up the expr, so that it only contains the operator, and not the number.
2nd, sanitize the comparison value
next, we create a "we matched the expression field" and use that to filter on.
... | eval matched=case(oper==">" AND LogError > value,1,oper=="=>" AND LogError >= value,1,oper=="=" AND LogError == value,1,oper=="!=" AND LogError != value,1,oper=="<" AND LogError < value,1, oper=="<=" AND LogError <= value,1,1==1,0) | where matched==1 | ....
so what we're doing is 6 tests, if either of them are successful, matched = 1 and we exit the case statement. The last expression acts as a default 1==1, is always true, and if we get this far, matched = 0
From here its easy to filter.
And, this can easily by macro-ed if you need to do this often, or need to swap out LogError for something else.
Hi, a) yes, they are b) I guess you are implying $foo$ tokens that can be taken from one search and substituted in another downstream search. If so, I wouldn't like to split one search to two, as it looks like an unnecessary complication.
I think I will go with parsing the expression using if or case as suggested below though it seems to be a 'brute force' approach.
You can do this with case, its not dynamic, but far quicker than using a map to kick of a search for each of your operators.
1st, clean up the expr, so that it only contains the operator, and not the number.
2nd, sanitize the comparison value
next, we create a "we matched the expression field" and use that to filter on.
... | eval matched=case(oper==">" AND LogError > value,1,oper=="=>" AND LogError >= value,1,oper=="=" AND LogError == value,1,oper=="!=" AND LogError != value,1,oper=="<" AND LogError < value,1, oper=="<=" AND LogError <= value,1,1==1,0) | where matched==1 | ....
so what we're doing is 6 tests, if either of them are successful, matched = 1 and we exit the case statement. The last expression acts as a default 1==1, is always true, and if we get this far, matched = 0
From here its easy to filter.
And, this can easily by macro-ed if you need to do this often, or need to swap out LogError for something else.
Great tip about field substitution, but still it does the replacement for the field values, not for the query text. I understand that what I'm trying to find is a not a standard everyday thing in Splunk, but that was a good chance to try.
So the option with CASE wins, it works and works fast. Thanks again for the answer!
there is some text substitution you can do.
i.e.
eval field1="boogie" | eval field2="field3" | eval {field2}=field1
{field2} gets substituted to "field3", so field3=boogie.
I havent seen anywhere outside direct assignments where this works though.
Yeah, the answer is boring, and I tried for a few mins to come up with a more funky solution. But, 13 (at worst) comparisons is about as cheap a solution as you'll get. So it depends on how you define elegant ;).
Even if you could do direct text replacement, string copy + compare would very likely be more expensive.
Thank you for the response!
This was the first thing I deciced to do and looks like it's the only way to do it quickly. Actually I hoped to avoid such obvious parsing of expression (luckily 6 cases only, but anyway) because it's boring and not that elegant as direct text substitution could be 😉
Are you thinking that A) the expression and thus the calculation might be different for each row in the search results? If so then I do not know of a way but maybe someone else does. B) Alternatively could there be one determination for the expression and/or calculated values, and then those values are pulled out and incorporated into another search?