I am using a subsearch to build part of a query. The query is complex so I need to build the search that I want and then return it. (We have not yet upgraded to a version that has the return command.) I can return the entire expression, but Splunk thinks it is a string and does a search againt the string and not the value of the string. I can also return the temp variable equal to the expression, but that is not what I want either. Here is an idea of what I am doing:
[ search ID="*" error
| eval search="( ID=".ID." error ) OR ( accessID=".ID." type=access "
| stats values(search) as searches
| eval NewSearch=mvjoin(searches," OR ")
| ???? NewSearch
] | ....
I am using this example as a guide.
It's simpler than you think:
[ ID=* error | eval search="( ID=".ID." error ) OR ( accessID=".ID." type=access )" | fields search ]
and that's it. You don't need the stats or mvjoin, as the subsearch takes care of that. The trick is that the field has to be named either search
or query
for Splunk to just return the string.
There is some weird behavior with quoting of terms though with subsearch, so the return
command is a lot more reliable. You can actually just copy and register the return.py
command from a newer version of Splunk into yours and it should work fine. In that case:
[ ID=* error | eval search="( ID=".ID." error ) OR ( accessID=".ID." type=access )" | return 10000 $search ]
will be more reliable.
It's simpler than you think:
[ ID=* error | eval search="( ID=".ID." error ) OR ( accessID=".ID." type=access )" | fields search ]
and that's it. You don't need the stats or mvjoin, as the subsearch takes care of that. The trick is that the field has to be named either search
or query
for Splunk to just return the string.
There is some weird behavior with quoting of terms though with subsearch, so the return
command is a lot more reliable. You can actually just copy and register the return.py
command from a newer version of Splunk into yours and it should work fine. In that case:
[ ID=* error | eval search="( ID=".ID." error ) OR ( accessID=".ID." type=access )" | return 10000 $search ]
will be more reliable.
When I use search, I just get the first instance. When I use different variable, I get them all. This is what I did to get it to work:
[ search ID="*" error
| eval sch="( ID=".ID." error ) OR ( accessID=".ID." type=access "
| stats values(sch) as searches
| eval search=mvjoin(searches," OR ")
| fields search
] | ....
Thanks for your help...
whereas the complete set of sourcetypes is :
Subsearch evaluated to the following search expression: "( sourcetype=multiline errror ) OR ( sourcetype=multiline type=access ) OR ( sourcetype=multline errror ) OR ( sourcetype=multline type=access ) OR ( sourcetype=syslog errror ) OR ( sourcetype=syslog type=access ) OR ( sourcetype=tcp-raw errror ) OR ( sourcetype=tcp-raw type=access )"
On 5.X the subsearch evaluates to just the 1st row returned.
i.e.
* [ search sourcetype=* | eval search="( sourcetype=".sourcetype." error ) OR ( sourcetype=".sourcetype." type=access )" | fields search ]
Evaluates to :
Subsearch evaluated to the following search expression: ( sourcetype=multline error ) OR ( sourcetype=multline type=access )
There's more than 1 sourcetype :
sourcetype=* | stats dc(sourcetype)
= 4
Try
[ search ID="*" error
| dedup ID
| eval search="( ID=".ID." errror ) OR ( accessID=".ID." type=access )"
| stats values(search) as searches
| eval search=mvjoin(searches," OR ")
| fields search
| format "" "" "" "" "" ""
]
For every ID we find we create a field called search that looks like :
( ID=xxxxx error ) OR ( accessID=xxxxx type=access )
Then we join them all together with an " OR "
Then we return the "search" field with special formating so the result is returned as is.
Note:
the field "search" is special when used in conjunction with format.
compare :
* earliest=-60m | dedup sourcetype | stats values(sourcetype) as sourcetypes| eval wibble=mvjoin(sourcetypes," OR ") | fields wibble | format "" "" "" "" "" ""
with
* earliest=-60m | dedup sourcetype | stats values(sourcetype) as sourcetypes| eval search=mvjoin(sourcetypes," OR ") | fields search | format "" "" "" "" "" ""
the first is returning:
wibble="(ID=xxxxx error)OR(accessID=xxxxx type=access)"
and the second is returning:
"(ID=xxxxx error)OR(accessID=xxxxx type=access)"
what I want is:
(ID=xxxxx error)OR(accessID=xxxxx type=access)
I want to evaluate the expression and not compare against it.