Skip to main content
Version: 6.1

Condition Language Functions

Overview

The correlator dialect provides about a hundred functions. Most of them match standard SML in both name and behavior. The remaining functions either exist only in the correlator or behave differently from the SML functions of the same name.

Functions Identical to Standard SML

Conditions and Comparison

FunctionDescription
casereturns the value of the first true condition in a list of pairs
validatethe inverse of case: returns the value of the first false condition
ifreturns one of two values depending on a condition
coalescereturns the first non-empty value from those listed
nullifreturns null if two values are equal, otherwise the first of them
inchecks whether a field value belongs to the listed set
likematches a value against an SQL-style pattern (%, _)
matchmatches a value against a regular expression
cidrmatchchecks whether an IP address belongs to a subnet

Value Type Checks

FunctionDescription
isnullthe value is absent
isnotnullthe value is present
isstrthe value is a string
isnumthe value is a number
isintthe value is an integer
isboolthe value is Boolean
typeofreturns the name of the value type

Type Conversion

FunctionDescription
tonumberconverts a value to a number; the second argument is a radix from 2 to 36
toboolconverts a value to Boolean

Text

FunctionDescription
lenstring length; for a multivalue field, the number of elements
lowerconverts a string to lowercase
upperconverts a string to uppercase
trimremoves the specified characters from both ends of a string; without a second argument, removes whitespace
ltrimthe same on the left
rtrimthe same on the right
replacereplaces occurrences of a pattern; capture groups $1, $2, ${name} are available in the replacement string
urlencodeencodes a string for use in a URL
urldecodethe reverse conversion

Mathematics

FunctionDescription
absabsolute value
ceilrounds up
floorrounds down
roundrounds to the specified number of digits; by default, to an integer
expexponent
lnnatural logarithm
loglogarithm to the specified base; with one argument, base 10
powexponentiation
sqrtsquare root
pithe number pi
maxthe largest of the listed values or array elements
minthe smallest of them

Multivalue Fields

FunctionDescription
mvcountnumber of elements
mvindexelement at an index; the third argument sets the end of a range
mvfindindex of the first element matching a regular expression
mvdedupremoves duplicate elements
mvsortsorts elements
mvappendcombines values into a single multivalue
mvjoinjoins elements into a string using a delimiter
mvrangebuilds a numeric series
mvzippairwise combines the elements of two fields
splitsplits a string by a delimiter

Hashing

FunctionDescription
md5MD5 hash
sha1SHA-1 hash
sha256SHA-256 hash
sha512SHA-512 hash
info

Hashes are returned in lowercase.

Time

FunctionDescription
nowcurrent time in Unix format
timethe same: time is a synonym for now
info

The correlator works with time in whole Unix seconds and in the UTC zone. If a time function is not given an explicit time zone, the calculation is performed in UTC.


Functions That Behave Differently

The functions below exist in both SML and the correlator but behave differently.

strftime

Formats a Unix time. Unlike SML, the pattern is not written in Joda Time format but as the reference date Mon Jan 2 15:04:05 MST 2006: each pattern element is the corresponding part of that reference date.

Syntax

strftime(<time>, <pattern>)
Pattern elementMeaningPattern elementMeaning
2006four-digit year15hours in 24-hour format
01two-digit month04minutes
02two-digit day05seconds
Janabbreviated monthZ07:00zone offset

Examples

Example 1
strftime(@timestamp, "2006-01-02") == "2026-08-06"

An empty pattern or a non-numeric time yields an empty string.

strptime

Parses a time string and returns a Unix time. The pattern is written the same way as in strftime

Syntax

strptime(<string>, <pattern>)

Examples

Example 1
now() - strptime(start_time, "2006-01-02T15:04:05Z07:00") > 300

If the string or the pattern cannot produce a moment in time, null is returned.

relative_time

Shifts a moment in time and rounds it down to a period boundary. It differs from SML in three ways: the offset is written as a quoted string, the shift may be followed by rounding through @, and there is a third optional argument, the time zone whose boundaries rounding uses.

Syntax

relative_time(<time>, "<offset>" [, <time zone>])

The offset has the form [(+|-)<integer><unit>][@<unit>], where the unit is one of s, m, h, d, w, M.

PartPurpose
(+|-)<integer><unit>the shift; the sign is required
@<unit>rounds down to a period boundary
Important

Unit case matters: m means minutes and M means months. The shift is applied first and the rounding second.

Examples

Example 1
relative_time(@timestamp, "-1h")
Example 2
relative_time(@timestamp, "@d")
Example 3
relative_time(@timestamp, "-1d@d", "Europe/Moscow")

The first expression yields the moment one hour earlier, the second the start of the day in UTC, and the third the start of yesterday in Moscow time. Without the third argument, day, week, and month boundaries are calculated in UTC.

to_timezone

Returns a string containing the local time of the specified zone rather than a shifted Unix time as in SML. The time zone is required.

Syntax

to_timezone(<time>, <time zone>)

Examples

Example 1
to_timezone(@timestamp, "Europe/Moscow") != nil

from_timezone

The reverse operation: it reads a string containing the local time of the specified zone and returns a Unix time. In SML this function takes a Unix time rather than a string.

Syntax

from_timezone(<local time string>, <time zone>)

Examples

Example 1
from_timezone("2026-08-03 17:37:12", "Europe/Moscow")

A string that already carries its own zone offset is rejected; otherwise there would be two sources of the zone. An unparsable string or an unknown zone yields null.

tostring

Converts a value to a string. The additional HEX, COMMAS, DURATION, BYTES, and QUANTITY formats available in SML are not supported: the function takes exactly one argument.

Syntax

tostring(<value>)

Examples

Example 1
tostring(event.code) == "4625"

substr

Extracts a substring. One-based numbering and a negative start counted from the end of the string work as in SML, but the second numeric argument is a length, not an end position.

Syntax

substr(<value>, <start> [, <length>])

Examples

Example 1
substr(user.name, -4, 4) == "base"
Example 2
substr(host.name, 1, 3) == "web"

A start of 0 is invalid in one-based numbering and yields an empty string, as does a start outside the string. The function works on characters rather than bytes, so multi-byte text is never cut mid-character.

info

For zero-based numbering, the dialect provides the separate substring function.


Correlator Functions

Accessing the Event and the Context

exist

Checks whether the event contains a field at the specified path. It differs from isnotnull in that it reports the presence of the field itself rather than whether its value is meaningful.

exist(<field path>)
Example 1
not exist(process.name)
Example 2
exist("user.name") or exist(process.parent.name)

source

Checks whether the event came from a source whose alias matches the pattern. The pattern may contain the * wildcard, and matching is case-insensitive.

source(<alias pattern>)
Example 1
source("winlog*") and event.code == "4625"

ctx

Returns the value of a field saved by an imperative rule stage. It works only for stages with the Add to Context toggle enabled. See Imperative Rules.

ctx(<stage>, <field>)

Both arguments may be written either without quotes or in double quotes; quotes are needed if the name contains a space or other characters outside the usual set.

Example 1
ctx(stage1, user.name) == "admin"
Example 2
ctx("stage-1", "user@corp.local") != ""
Example 3
ctx(stage_a, destination.host.name) == ctx(stage_b, host.name)

Active Lists

alcontains

Checks whether the active list contains a record whose specified field equals the specified value. Several field and value pairs may be given, in which case the record must match all of them.

alcontains(<list>, <field> as <value> [, <field> as <value>]...)
Example 1
alcontains(ti_ip_blacklist, destination.ip as source.address)
Example 2
alcontains(geo, ip as source.ip, country as source.geo.country_iso_code)

alget

Finds a record in an active list by value and returns the value of one of its fields.

alget(<list>, <value>, <field>)
Example 1
alget(known_hosts, host.name, status) == "trusted"
Example 2
alget(known_hosts, lower(user.name), 'user name') != nil

String Comparison and Parsing

contains

Checks for a substring, case-sensitively. For a multivalue field, it reports a match if the substring is found in at least one element.

contains(<value>, <substring>)
Example 1
contains(process.command_line, "-enc")

startswith

Checks whether a value starts with the specified substring, case-sensitively.

startswith(<value>, <prefix>)
Example 1
startswith(file.path, "C:\\Windows\\Temp")

endswith

Checks whether a value ends with the specified substring, case-sensitively.

endswith(<value>, <suffix>)
Example 1
endswith(lower(file.name), ".ps1")
info

contains, startswith, and endswith are always case-sensitive. To compare without regard to case, wrap both sides in lower.

regex

Checks whether the value contains a match for a regular expression.

regex(<value>, <regular expression>)
Example 1
regex(process.command_line, "(?i)powershell\\s+-enc")

extract

Returns the text of the first match of a regular expression. Without a third argument, the whole match is returned; with it, the contents of the named group (?P<name>...).

extract(<value>, <regular expression> [, <group name>])
Example 1
extract(url.original, "session_id=(?P<sid>[a-z0-9]+)", "sid") != ""

If the expression is empty or invalid, there is no match, or the group captured nothing, an empty string is returned.

indexof

Returns the position of the first occurrence of a substring, or -1 if there is none.

indexof(<value>, <substring>)
Example 1
indexof(process.command_line, "--password") >= 0

substring

Extracts a substring using zero-based numbering; the second numeric argument is a length. Values outside the string bounds are not an error: they are clamped to valid ones.

substring(<value>, <start> [, <length>])
Example 1
substring(host.name, 0, 3) == "web"

String Similarity and Entropy

levenshtein

Returns the edit distance between two strings: the number of character insertions, deletions, and substitutions. Strings longer than 256 characters are truncated.

levenshtein(<value>, <value>)
Example 1
levenshtein(lower(user.name), "administrator") <= 2

If both strings are empty - for example, both fields are absent from the event - null is returned rather than 0: there is nothing to compare.

similarity

Returns a normalized similarity measure from 0 to 1, where 1 means an exact match.

similarity(<value>, <value>)
Example 1
similarity(dns.question.name, "microsoft.com") > 0.85

Like levenshtein, it returns null when both strings are empty.

entropy

Returns the Shannon entropy of a string in bits per character, roughly from 0 to 8. High entropy is characteristic of random and encoded strings such as algorithmically generated domains and encoded payloads.

entropy(<value>)
Example 1
entropy(dns.question.name) > 3.5 and len(dns.question.name) > 12
Important

Entropy depends on string length, so short values produce inflated results. Use it together with a length check. An empty value yields null rather than 0, because 0 is the legitimate entropy of a string made of one repeated character.

Multivalue Fields

mvcontains

Checks whether a multivalue field contains an element that is exactly equal to the specified value. Unlike contains, it looks for a whole-element match rather than a substring.

mvcontains(<multivalue field>, <value>)
Example 1
mvcontains(host.ip, "10.0.0.1")

Type Conversion

tofloat

Converts a value to a floating-point number. A value that does not parse as a number, as well as infinity and not-a-number, yields null.

tofloat(<value>)
Example 1
round(tofloat(risk.score)) >= 10

Encoding and Decoding

FunctionSyntaxDescription
base64encodebase64encode(<value>)encodes a value in base64
base64decodebase64decode(<value>)decodes base64; both the standard and URL-safe alphabets are recognized, with and without padding
hexencodehexencode(<value>)encodes a value in hexadecimal
hexdecodehexdecode(<value>)decodes a hexadecimal string
Example 1
contains(lower(base64decode(process.args)), "invoke-expression")

If the value cannot be decoded, an empty string is returned.

Network Addresses

FunctionSyntaxDescription
isipisip(<value>)the value is a valid IPv4 or IPv6 address
isipv4isipv4(<value>)the value is a valid IPv4 address
isipv6isipv6(<value>)the value is a valid IPv6 address
isprivateipisprivateip(<value>)the address is private, loopback, or link-local: RFC 1918, ULA, 127.0.0.0/8, ::1, 169.254.0.0/16, fe80::/10
ispublicipispublicip(<value>)the address is globally routable
cidr_containscidr_contains(<subnet>, <address>)the address belongs to the subnet; a full synonym of cidrmatch
subnetsubnet(<address>, <prefix length>)returns the subnet of the specified length that the address belongs to
iptonumberiptonumber(<address>)returns the numeric value of an IPv4 address for range comparisons
Example 1
isprivateip(source.address) and cidr_contains("10.0.0.0/8", source.address)
Example 2
subnet(source.ip, 24) == "10.0.5.0/24"

Time

timediff

Returns the difference between two moments in time, in seconds.

timediff(<time>, <time>)
Example 1
timediff(event.end, event.start) > 3600

age

Returns how many seconds have passed from the specified moment until now. Equivalent to now() - <time>.

age(<time>)
Example 1
age(user.last_password_change) > 7776000

hourofday

Returns the hour of the day from 0 to 23. Without a second argument, the calculation is performed in UTC.

hourofday(<time> [, <time zone>])
Example 1
hourofday(@timestamp, "Europe/Moscow") < 6

dayofweek

Returns the day of the week as a number, where 0 is Sunday and 6 is Saturday. Without a second argument, the calculation is performed in UTC.

dayofweek(<time> [, <time zone>])
Example 1
dayofweek(@timestamp, "Europe/Moscow") == 1

isweekend

Checks whether a moment falls on a Saturday or Sunday.

isweekend(<time> [, <time zone>])
Example 1
isweekend(@timestamp, "Europe/Moscow") and event.code == "4624"

inbusinesshours

Checks whether the hour of a moment falls within the interval from <start hour> inclusive to <end hour> exclusive.

inbusinesshours(<time>, <start hour>, <end hour> [, <time zone>])
Example 1
not inbusinesshours(@timestamp, 9, 19, "Europe/Moscow")
info

All four functions take a time zone as an IANA database name, for example Europe/Moscow. If a zone is specified and cannot be resolved, the result is null for hourofday and dayofweek and false for isweekend and inbusinesshours. Omitting the argument means UTC and is not an error.

Collections

join

Joins the elements of a multivalue field into a string using a delimiter. A single value is treated as a one-element collection.

join(<multivalue field>, <delimiter>)
Example 1
join(user.roles, ",") != ""

sum

Adds the numeric elements of a collection. Elements that are not numbers are skipped; if there is nothing to add, null is returned.

sum(<collection>)
Example 1
sum(scores) / len(scores) > 5