Knowledge Management

Is it even possible to make a recursive macro?

jprior
Explorer

I have a macro like this:

1 + if(true(), 1, `myMacro(1)`)

And I get an infinite recursion error when I use it in a query like this:

| makeresults
| eval foo = `myMacro(1)`

Error in 'SearchParser': Reached maximum recursion depth (100) while expanding macros. Check for infinitely recursive macro definitions.

 

It seems like the macro call is actually being executed during the "expanding macro" operation, and that causes the infinite recursion. This is unexpected since the recursive macro call is actually in a part of the code that can never execute. I can't imagine any way that a macro could actually use recursion... since the macro "expands" outside of the context of the recursive logic. It will always get a recursion error.

 

Labels (1)
Tags (2)
0 Karma
1 Solution

bowesmana
SplunkTrust
SplunkTrust

@jprior Technically the parameter to control macro depth is documented as

max_macro_depth = <integer>
* Maximum recursion depth for macros. Specifies the maximum levels for macro
  expansion.
* It is considered a search exception if macro expansion does not stop after
  this many levels.
* Value must be greater than or equal to 1.
* Default: 100

The word 'recursion' is used in the description of the 'max_macro_depth'  parameter and also in the error you get when you try to use macros recursively as in your example, so whilst one could get into a debate about the use of the word 'recursion' and 'recursive', it's really just about depth, so macro A expands macro B, which expands C and so on.  We use the term nested macros, rather than recursive macros, which as you've discovered is not possible.

When you know that macros are expanded before the search and cannot be affected by the data in the events, recursion is in practice impossible.

We regularly use nested macros to a number of levels in some of our frameworks as macros lend themselves to creating structure. For example,  you can define

`my_macro(type_a)`

where 'type_a' is a fixed value and the definition has type as an argument, which then expands to 

`nested_macro_$type$`

so you can use fixed values in macro calls to reference somewhat dynamic macro trees.

Reference to limits.conf here

https://docs.splunk.com/Documentation/Splunk/9.2.1/Admin/Limitsconf#Parsing

 

View solution in original post

bowesmana
SplunkTrust
SplunkTrust

Macros are expanded before the search runs, so it cannot evaluate the macro definition based on the result of any contained logic because there is no data in the pipeline.

jprior
Explorer

What about if all the values passed into the macro are hard coded values? Like in my example, I'm just passing in 1.

0 Karma

ITWhisperer
SplunkTrust
SplunkTrust

Macro expansion is just textual, there is no context held during expansion, so the expansion doesn't interpret any values passed to the macro, it simply replaces the text of the macro "call" with the body of the macro substituting parameters as it goes, then tries to expand any macros which have been added, and so on.

0 Karma

jprior
Explorer

So then it seems like the answer is: No, it is not possible to create a recursive macro.

Then I don't understand why there is a max recursion limit. That limit seems useless since it's not actually possible to use recursion. It should just return an error the moment recursion is detected.

0 Karma

bowesmana
SplunkTrust
SplunkTrust

@jprior Technically the parameter to control macro depth is documented as

max_macro_depth = <integer>
* Maximum recursion depth for macros. Specifies the maximum levels for macro
  expansion.
* It is considered a search exception if macro expansion does not stop after
  this many levels.
* Value must be greater than or equal to 1.
* Default: 100

The word 'recursion' is used in the description of the 'max_macro_depth'  parameter and also in the error you get when you try to use macros recursively as in your example, so whilst one could get into a debate about the use of the word 'recursion' and 'recursive', it's really just about depth, so macro A expands macro B, which expands C and so on.  We use the term nested macros, rather than recursive macros, which as you've discovered is not possible.

When you know that macros are expanded before the search and cannot be affected by the data in the events, recursion is in practice impossible.

We regularly use nested macros to a number of levels in some of our frameworks as macros lend themselves to creating structure. For example,  you can define

`my_macro(type_a)`

where 'type_a' is a fixed value and the definition has type as an argument, which then expands to 

`nested_macro_$type$`

so you can use fixed values in macro calls to reference somewhat dynamic macro trees.

Reference to limits.conf here

https://docs.splunk.com/Documentation/Splunk/9.2.1/Admin/Limitsconf#Parsing

 

jprior
Explorer

Ok thanks for the answer. That really cleared it up.

0 Karma

isoutamo
SplunkTrust
SplunkTrust

Hi

I'm not sure if you found some useful from this presentation https://www.youtube.com/watch?v=1yEhbKXRFMg ?

r. Ismo

Get Updates on the Splunk Community!

3 Ways to Make OpenTelemetry Even Better

My role as an Observability Specialist at Splunk provides me with the opportunity to work with customers of ...

What's New in Splunk Cloud Platform 9.2.2406?

Hi Splunky people! We are excited to share the newest updates in Splunk Cloud Platform 9.2.2406 with many ...

Enterprise Security Content Update (ESCU) | New Releases

In August, the Splunk Threat Research Team had 3 releases of new security content via the Enterprise Security ...