Splunk Search

How can I use the value of a field as an immediate search expression (dynamic search string formatting)?

greg
Communicator

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?

Tags (2)
1 Solution

jonuwz
Influencer

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.

View solution in original post

0 Karma

greg
Communicator

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.

0 Karma

jonuwz
Influencer

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.

0 Karma

greg
Communicator

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!

0 Karma

jonuwz
Influencer

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.

0 Karma

greg
Communicator

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 😉

0 Karma

sideview
SplunkTrust
SplunkTrust

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?

Get Updates on the Splunk Community!

Routing logs with Splunk OTel Collector for Kubernetes

The Splunk Distribution of the OpenTelemetry (OTel) Collector is a product that provides a way to ingest ...

Welcome to the Splunk Community!

(view in My Videos) We're so glad you're here! The Splunk Community is place to connect, learn, give back, and ...

Tech Talk | Elevating Digital Service Excellence: The Synergy of Splunk RUM & APM

Elevating Digital Service Excellence: The Synergy of Real User Monitoring and Application Performance ...