Hi,
I'm struggling with using subsearches in eval statements, but got most of it worked out. Now I want to put the subsearch into a macro for obvious reasons, but it seems the macro doesn't expand the arguments passed to it ...
My iseval macro looks something like this:
"[ search index=main | head 1 | eval ip=\"$dnsip$\" | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value=\"null\" | eval result=\"\\\"\".result.\"\\\"\" | return $result ]"
It's doing a dummy search to calculate the hostname for a given IP, and then returning that hostname formatted as a string to the eval expression.
This works perfectly fine if I invoke the macro like this:
index=main | head 1 | eval aatest=`test_dnshost("8.8.8.8")`
It gets nicely expanded:
06-04-2015 10:19:55.462 INFO SearchParser - PARSING: search index=main | head 1 | eval aatest=`test_dnshost("8.8.8.8")`
06-04-2015 10:19:55.465 INFO SearchParser - AFTER EXPANDING MACROS: search index=main | head 1 | eval aatest=[ search index=main | head 1 | eval ip="8.8.8.8" | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value="null" | eval result="\"".result."\"" | return $result ]
But when I try to pass actual variables to this macro, it suddenly doesn't want to expand the argument anymore. The search string is:
index=main | head 1 | eval ip="8.8.8.8" | eval aatest=`test_dnshost(ip)`
which seems to expand with "ip" as an argument value, not the actual field content:
06-04-2015 10:23:18.642 INFO SearchParser - PARSING: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=`test_dnshost(ip)`
06-04-2015 10:23:18.644 INFO SearchParser - AFTER EXPANDING MACROS: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=[ search index=main | head 1 | eval ip="ip" | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value="null" | eval result="\"".result."\"" | return $result ]
Any clue why and how i might fix this?
So, the final answer ... The way I tried doing it is not possible, since apparently subsearches are always executed before the main search is executed, even if the subsearch is only needed when the eval is called. That means the value of the field passed to the macro will be empty (if it's assigned through another eval in the main search).
To solve it, the field manipulations should be done in the subsearch, or a field with an actual value (coming from the event) can be used.
So, the final answer ... The way I tried doing it is not possible, since apparently subsearches are always executed before the main search is executed, even if the subsearch is only needed when the eval is called. That means the value of the field passed to the macro will be empty (if it's assigned through another eval in the main search).
To solve it, the field manipulations should be done in the subsearch, or a field with an actual value (coming from the event) can be used.
The problem is the double-quotes in your macro which is telling Splunk to treat the dnsip
variable as a string-literal. Try this for your macro:
"[ search index=main | head 1 | eval ip=$dnsip$ | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value=\"null\" | eval result=\"\\\"\".result.\"\\\"\" | return $result ]"
That was one of the things I considered and tested, but it yields the same result (and an eval error):
06-04-2015 16:26:11.146 INFO SearchParser - PARSING: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=`test_dnshost(ip)`
06-04-2015 16:26:11.149 INFO SearchParser - AFTER EXPANDING MACROS: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=[ search index=main | head 1 | eval ip=ip | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value="null" | eval result="\"".result."\"" | return $result ]
At this point I don't care if my macro treats the argument as a variable or a string, the problem is that $dnsip$="ip" instead of $dnsip$="8.8.8.8" 🙂
But you DO care! You are passing in "8.8.8.8" by method of the vehicle of the field named ip
which has that value. Therefore, you must not use those double-quotes in the macro
. So, keep them removed and let's look at the error that you get. What is the error?
There's a few things wrong:
1) If you look at the search log posted in my previous reply, you see the same wrong expand in the subsearch: "eval ip=ip". It's still not expanding the variable, but just putting the name of the variable where $dnsip$ was
2) A macro is just about expanding some text and putting it in place, while replacing the variables with their values: with this in mind, I guess I do need the double quotes, otherwise it would end up in the form of "eval ip=8.8.8.8" (which is wrong since it's a string, not a number)
3) The error the search parser is giving with the latest version (without the quotes): "Error in 'eval' command: Failed to parse the provided arguments. Usage: eval dest_key = expression ", which makes sense, since it's trying to allocate a value to ip ("eval ip=ip") from a field that does not exist in the subsearch
So basically, the problem remains the same: the macro is just putting the name of the passed field in place of $dnsip$, instead of the value of that field.
Edit (since I don't have enough characters left in the other post): motivating my statement number 2, if I pass "8.8.8.8" directly to the macro:
Error in 'eval' command: The number 8.8.8.8 is invalid.
06-04-2015 18:08:21.311 INFO SearchParser - PARSING: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=`test_dnshost("8.8.8.8")`
06-04-2015 18:08:21.314 INFO SearchParser - AFTER EXPANDING MACROS: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=[ search index=main | head 1 | eval ip=8.8.8.8 | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value="null" | eval result="\"".result."\"" | return $result ]
OK, keep it this "broken" way and try these:
index=main | head 1 | eval aatest=`test_dnshost(\"8.8.8.8\")`
index=main | head 1 | eval aatest=`test_dnshost("8.8.8.8")`
index=main | head 1 | eval aatest=`test_dnshost(8.8.8.8)`
index=main | head 1 | eval aatest=`test_dnshost("ip")`
index=main | head 1 | eval aatest=`test_dnshost(ip)`
Do any work?
\"8.8.8.8\":
Error in 'SearchParser': The definition of macro 'test_dnshost(1)' is expected to be an eval expression that returns a string.
"8.8.8.8": see above
8.8.8.8:
Error in 'eval' command: The number 8.8.8.8 is invalid.
"ip":
06-04-2015 18:27:07.801 INFO SearchParser - AFTER EXPANDING MACROS: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=[ search index=main | head 1 | eval ip=ip | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value="null" | eval result="\"".result."\"" | return $result ]
ip:
06-04-2015 18:27:45.704 INFO SearchParser - AFTER EXPANDING MACROS: search index=main | head 1 | eval ip="8.8.8.8" | eval aatest=[ search index=main | head 1 | eval ip=ip | lookup local=true dnslookup dnsip as ip output dnshost as result | fillnull value="null" | eval result="\"".result."\"" | return $result ]
So nope. With 'broken' I guess you mean having "eval ip=$dnsip$" in the macro, without the double quotes?