Splunk® Cloud Services

SPL2 Search Reference

Custom eval functions

You can create your own custom eval functions to extend SPL2. Custom functions are user-defined functions that you declare in an SPL2 module. Custom eval functions have zero or more parameters and return a single value.

You can use custom eval functions in the WHERE clause of the from command and in the eval and where commands.

Custom functions provide a structured way to share and reuse blocks of SPL2. Custom functions are similar to macros, but they have more capabilities than macros, such as data type checking and advanced optimizations.

For information about the built-in eval functions, see Quick Reference for SPL2 eval functions.

Custom eval function syntax

The required syntax is in bold.

function <function-name>
( [ $<parameter-name> [: <parameter-type>] [=<default-value>] ], ...) [: <function-type> ]
{
[ <SPL-statement>... ]
return <expression>
}

The parenthesis are required, even if a <function-parameter> isn't specified.

The curly braces { } are required, even if a <SPL-statement> isn't specified.

Required arguments

function-name
Syntax: function <function-name>
Description: The word function followed by the name that you want to give to the function. Function names must start with a letter or underscore ( _ ) character and cannot contain spaces.
expression
Syntax: return <expression>
Description: The word return followed by the expression that you want returned from the function. Expressions can be composed of literals, functions, fields, parameters, comparisons, and other expressions. See Types of expressions in the SPL2 Search Manual.

Optional arguments

parameter-name
Syntax: $<parameter-name>
Description: The name that you want to give to a parameter that you want to use with a custom function. You can specify zero or more parameters. Separate multiple parameters with commas. Parameter names must start with a dollar sign ( $ ) followed by a letter or an underscore ( _ ) character and cannot contain spaces. When you specify a parameter name, you have the option to include a parameter type. The default parameter type is any.
Example: ($firstname, $surname: string)
Default: None
parameter-type
Syntax: <parameter-type>
Description: The data type that the parameter accepts. This is the input data type. The default data type is any. See Built-in data types. If you specify a parameter type, you must separate the <parameter-name> and the <parameter-type> with a colon ( : ).
Example: ($ipaddress: string, $kbps: int)
Default: any
default-value
Syntax: <default-value>
Description: A default value for the parameter. The value must be a constant, either a literal or a string. The value can't be a field name. Users can override the default value by specifying the parameter with a value.
Example: ($count: int=5)
Default: None
function-type
Syntax: <function-type>
Description: The data type that the function returns. This is the output data type. The default data type is any. See Built-in data types.
Default: any
SPL-statement
Syntax: <SPL-statement>...
Description: One or more SPL2 statements to include in your custom function. See Examples.
Default: None

Using custom eval functions

Consider this custom eval function example:

function hello ($fullname: string): string { 
    return  "Howdy" + " " + $fullname 
}

The following table describes each part of this function example:

Syntax Example Description
function <function_name> function hello The name of the function is hello.
$<parameter-name>: <parameter-type> $fullname: string One parameter is defined, with the name fullname.

The value that you specify for the parameter must be an expression that resolves to a string, such as a field that contains string values or a string literal.

<function-type> string The function returns a string.
{

<SPL-statements> return <expression>
}

{

return "Howdy" + " " + $fullname
}

There is no SPL-statement. The expression returned is the string Howdy , a space, and the value specified for the parameter $fullname.

Using functions in modules

You create custom eval functions in an SPL2 module. You can use a custom function multiple times within that module. Custom functions can also be imported into other modules.

Using functions in the API

You can also create custom functions using the Search Service API.

Supported function types

When you create a custom eval function, you have the option to specify the data type for the function or the function parameters. The built-in data types include strings, numbers, Booleans, arrays, objects, and times.

If you don't specify a data type, the default data type any is used.

The dataset data type isn't applicable to custom eval functions. You use the dataset data type with a custom command function. See Custom command functions.

To learn more about the supported data types, see Built-in data types in the SPL2 Search Reference.


Custom function limitations

An SPL2 custom function cannot reference a search statement that is defined outside of the SPL2 function.

In the following example, the search $aws_security_cloudtrail_sourcetype is referenced in the function aws_security_cloudtrail.

$aws_security_cloudtrail_sourcetype = 
from $aws_security_cloudtrail_index 
where sourcetype="aws:cloudtrail"

function aws_security_cloudtrail($accountId, $region) {
    return from $aws_security_cloudtrail_sourcetype 
   | search $accountId $region
}

The following is an example of the error message that is returned when a function references a search that is outside of the function.

Error: Invalid function declaration: Unknown variable 
'$aws_security_cloudtrail_sourcetype' referenced 
in the function 'aws_security_cloudtrail'.

Testing custom functions

Testing custom functions makes it easier to verify that the function works as you intend.

You can test custom functions in isolation, without impacting other SPL2 statements, by using dataset literals. There are multiple sample dataset literals that you can use to test your functions. See Sample dataset literals in the SPL2 Search Manual.

Consider the following dataset:

name age city
Wei Zhang 39 Seattle
Rutherford Sullivan 57 Dublin
Vanya Patel 47 Bangalore

This dataset will be used to test the following function. This function, called hello, returns the string "Howdy", followed by a space and the values from the expression specified for the fullname parameter.

function hello ($fullname: string): string { 
    return  "Howdy" + " " + $fullname 
}

The number of events in the dataset literal that you use for testing depends on how complex your function is. In simple examples, you could use one event. This example uses three.

This example invokes the function by using the eval command. This example creates a new field called greeting to store the results of the function:

$search = | from [ {name: "Wei Zhang", age: 39, city: "Seattle"}, {name: "Rutherford Sullivan", age:57, city: "Dublin"}, {name: "Vanya Patel", age: 47, city: "Bangalore"}] | eval greeting = hello(name)


These are results of invoking this function:

name age city greeting
Wei Zhang 39 Seattle Howdy Wei Zhang
Rutherford Sullivan 57 Dublin Howdy Rutherford Sullivan
Vanya Patel 47 Bangalore Howdy Vanya Patel

Examples

1. A function with a simple return expression

This example shows how to use a custom function with a simple expression.

This example returns error codes that are greater than or equal to 400. The custom function is called isError and returns a Boolean value. A parameter is defined, called $code, which has an input data type of number. There is no SPL statement in this example. The expression for this function returns results only when the value of the $code parameter is greater than or equal to 400.

function isError($code : number) : boolean {
  return $code >= 400 
}

This example invokes the function in the WHERE clause of the from command:

| FROM jsondata WHERE method="GET" AND isError(status_code)

In this example, the isError function is used as a filter in the WHERE clause of a from command. The status_code field is the value used for the $code parameter.

As the events from the jsondata dataset are read, the events are filtered by the WHERE clause. Only the events that have a method field with a value of GET and have an error status code of 400 or greater are returned.

Suppose the following events are in the jsondata dataset:

_time method status_code
22 Mar 2022 12:00:00 PM PUT 200
22 Mar 2022 11:45:00 AM GET 400
22 Mar 2022 11:13:00 AM GET 200
22 Mar 2022 10:59:00 AM POST 408
22 Mar 2022 10:38:00 AM GET 404

When the search is run with the custom eval function, the following results are returned:

_time method status_code
22 Mar 2022 11:45:00 AM GET 400
22 Mar 2022 10:38:00 AM GET 404

2. Using and overriding a default value

This example shows how to specify a default value in a custom function and override that default value.

Suppose you want to create a custom function that combines the built-in if and round functions. You want to take the values in a field and round the values to a specific number of decimal points, but only if the number is greater than 1.

Start by creating some sample data. You can use a dataset literal like this:

$sample = FROM [{score: 2.345678},{score: 0.1234},{score: 1.0076543}] 

Next, combine the functions that you want to use explicitly. For example, if you want to apply the function to the score field, this would be the function expression:

if(score>1, round(score, 2), score) 

Then test your explicit function expression against the sample data:

$function_test1 = FROM $sample SELECT score, if(score>1, round(score, 2), score)  AS newscore

You can convert the explicit function expression into a custom function, which includes a default value for $precision:

function roundIf($field:int, $precision:number=2): int {
  return if($field>1, round($field, $precision), $field) 
}

Now you're ready to test the function. Notice this search doesn't specify a precision. It uses the default $precision in the function.

$function_test2 = FROM $sample SELECT score, roundIf(score) AS newscore

You can override the default $precision by specifying a different precision in your search. For example:

$function_test2 = FROM $sample SELECT score, roundIf(score, 4) AS newscore

3. Reusing a custom function

You can use your custom eval functions in multiple searches within the same SPL module. To use a custom function in another SPL module, you must export the custom function.

This custom function, isError, is identical to the custom function described in the previous example.

This custom function is used in three different searches:

function isError($code : number) : boolean {
  return $code >= 400 
}

| FROM jsondata WHERE method="GET" AND isError(status_code)

| FROM jsondata WHERE isError(status_code)
| stats count(method) BY status_code, method

| FROM main WHERE isError(status_code)
| stats (earliest_time(_time)) AS 'First Instance'
| eval 'First Instance'=strftime('First Instance', "%Y-%m-%d %H:%M:%S")

First search

This search returns events where the method is GET and the values in the status_code field are equal to or greater than 400:

| FROM jsondata WHERE method="GET" AND isError(status_code)

Second search

This search returns events where the values in the status_code field are equal to or greater than 400. The search then counts the values in the method field and organizes the results by the values in the status_code field and the method field.

| FROM jsondata WHERE isError(status_code) | stats count(method) BY status_code, method

The results look something like this:

status_code method count(method)
400 GET 1
404 GET 1
408 POST 1

Third search

This search returns events from a different dataset where the values in the status_code field are equal to or greater than 400. The search returns the time from the earliest event in the search results, which is the first occurrence of the 4xx status codes for the time range specified. The field returned is renamed First Instance. Because the earliest_time function returns a UNIX time, the strftime eval function is used to change the time into a human-readable time format.

| FROM main WHERE isError(status_code) |stats (earliest_time(_time)) AS 'First Instance' |eval 'First Instance'=strftime('First Instance', "%Y-%m-%d %H:%M:%S")

The results look something like this:

First instance
2022/03/22 10:38


See also

Functions
Custom command functions
Quick Reference for SPL2 eval functions
Documenting custom functions
Naming function arguments in the SPL2 Search Manual
Related information
Dataset literals in the SPL2 Search Manual
Last modified on 19 November, 2024
repeat dataset function   Custom command functions

This documentation applies to the following versions of Splunk® Cloud Services: current


Was this topic useful?







You must be logged into splunk.com in order to post comments. Log in now.

Please try to keep this discussion focused on the content covered in this documentation topic. If you have a more general question about Splunk functionality or are experiencing a difficulty with Splunk, consider posting a question to Splunkbase Answers.

0 out of 1000 Characters