I would like to use a field as the string for searchmatch, but that results in an error stating:
Error in 'eval' command: The arguments to the 'searchmatch' function are invalid.
I've attempted to recreate the issue using fake data to demonstrate the issue.
Assuming I have data like the results from the following:
| makeresults
| eval data="index=foo|foo|1;index=foo|bar|0;index=bar|bar|1;index=bar|foo|0;index=foo OR index=bar|foo|1;index=foo OR index=bar|bar|1"
| fields - _time
| eval data=split(data, ";")
| mvexpand data
| rex field=data "^(?<filter>[^\|]+)\|(?<index>[^\|]+)\|(?<expected>[^\|]+)$"
| fields filter index expected
I'd really like to be able to append | eval actual=if(searchmatch(filter),1,0)
and have actual match the expected column
I can copy the string from filter into search match and run them individually, but I need something that scales.
EDIT:
Just to clarify, the example I provided is fairly simple in that it is only filtering by index, but in my actual data I have all sorts of filters so something that parses out the indexes and then checks won't be sufficient for my needs.
Also in my actual data, I don't have the expected column. I added that here just to indicate if I assumed the data should match.
searchmatch will not allow a field to be used in place of string. However, the match function of eval will, and match can be made to behave like searchmatch very easily!
| eval searchHits=if(match(_raw,"Type=Error"),1,0)
is the same as:
| eval searchHits=if(searchmatch("Type=Error"),1,0)
Further, match will support the regex pipe, so you can OR as well. Here's an example of both:
... | eval typeField = "Type=Error|Type=Warning"
| eval searchHits=if(match(_raw,typeField),1,0)
| stats count as EventCount sum(searchHits) AS searchHits by Type
searchmatch will not allow a field to be used in place of string. However, the match function of eval will, and match can be made to behave like searchmatch very easily!
| eval searchHits=if(match(_raw,"Type=Error"),1,0)
is the same as:
| eval searchHits=if(searchmatch("Type=Error"),1,0)
Further, match will support the regex pipe, so you can OR as well. Here's an example of both:
... | eval typeField = "Type=Error|Type=Warning"
| eval searchHits=if(match(_raw,typeField),1,0)
| stats count as EventCount sum(searchHits) AS searchHits by Type
Hi @triest,
If I understand correctly, then try appending the following as I think this may do what you want:
| eval actual=if(searchmatch("expected=1"), filter, "")
Note the quotes inside the searchmatch() - without which you'd get "Error in 'eval' command."
I've appended it to your query, which gave the following output when I ran it, with the 'actual' column showing the filters that matched, or empty if they didn't:
filter index expected actual
index=foo foo 1 index=foo
index=foo bar 0
index=bar bar 1 index=bar
index=bar foo 0
index=foo OR index=bar foo 1 index=foo OR index=bar
index=foo OR index=bar bar 1 index=foo OR index=bar
Is this what you were trying to do?
Hi triest,
maybe I misunderstand your question, but how about a case()
instead of searchmatch()
?
Since searchmatch()
takes a regex as argument you will compare against a literal filter
in your example.
Your example works btw if you do it like this:
| eval actual=if(searchmatch("filter"),1,0)
but this will match all events since you have filter
in all example events.
Would a case()
like this do the thing?
| eval actual=case(expected="1", "Yes", expected="0", "No", 1=1, "unknown")
Again I may understand the requirement completely wrong ¯\_(ツ)_/¯
😉
cheers, MuS
@MuS,
You are completely correct that in this simple case that would work. I added the expected to show if I thought the filter should match the event or not; in the real data set I wouldn't have that. I'll try to clarify the question; I really appreciate you trying.