VRL expression reference
Syntax
VRL programs can be constructed with the following syntax rules.
Comment
#
. Each line must be preceeded with a
#
character. VRL currently does not allow for block comments.Examples
# comment
# multi-line
# comment
Expressions
Examples
# newline delimited expressions
del(.user_info)
.timestamp = now()
.message = "hello world"
# semicolon delimited expressions
del(.user_info); .timestamp = now()
.message = "hello world"
Keywords
Keywords are reserved words that are used for primitive language features, such as if
, and cannot be used as
variable assignments or other custom directives. The following words are reserved:
abort
as
break
continue
else
false
for
if
impl
in
let
loop
null
return
self
std
then
this
true
type
until
use
while
Whitespace
Whitespace is any non-empty string as defined by the Unicode White_Space
property.
VRL is a “free-form” language, meaning that all forms of whitespace serve only to separate tokens in the grammar, and have no semantic significance.
Literal expressions
As in most other languages, literals in VRL are values written exactly as they are meant to be interpreted. Literals include things like strings, Booleans, and integers.
Array
Examples
[]
["first", "second", "third"]
["mixed", 1, 1.0, true, false, {"foo": "bar"}]
["first-level", ["second-level", ["third-level"]]
[.field1, .field2, to_int!("2"), variable_1]
[
"expressions",
1 + 2,
2 == 5,
true || false
]
Boolean
true
or false
.Examples
true
false
Float
A float literal is a decimal representation of a 64-bit floating-point type (specifically, the “binary64” type defined in IEEE 754-2008).
A decimal floating-point literal consists of an integer part (decimal digits), a decimal point, a fractional part (decimal digits).
Examples
1_000_000.01
1000000.01
1.001
Characteristics
Limits
-1.7976931348623157E+308f64
to 1.7976931348623157E+308f64
. Floats outside that
range are wrapped.Underscores
_
) characters instead of ,
to make them human readable. For
example, 1_000_000
.Integer
Examples
1_000_000
1000000
Characteristics
Limits
-9223372036854775807
to 9223372036854775807
. Integers outside that range are
wrapped.Underscore
_
) characters instead of ,
to make them human readable. For
example, 1_000_000
.Null
Examples
null
Object
An object literal is a growable key/value structure that is syntactically equivalent to a JSON object.
A well-formed JSON document is a valid VRL object.
Examples
{
"field1": "value1",
"field2": [ "value2", "value3", "value4" ],
"field3": { "field4": "value5" }
}
{
"field1": .some_path,
"field2": some_variable,
"field3": { "subfield": "some value" }
}
Characteristics
Ordering
Regular Expression
A regular expression literal represents a Regular Expression used for string matching and parsing.
Regular expressions are defined by the r
sigil and wrapped with single quotes (r'...'
). The value between
the quotes uses the Rust regex syntax.
Examples
r'^Hello, World!$'
r'(?i)^Hello, World!$'
r'^\d{4}-\d{2}-\d{2}$'
r'(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})'
Characteristics
Flags
Regular expressions allow for flags. Flags can be combined, as in r'(?ixm)pattern'
,
r'(?im)pattern'
, etc.
To learn more about regular expressions in Rust—and by extension in VRL—we strongly recommend the in-browser Rustexp expression editor and tester.
Option | Description |
---|---|
U | Swap the meaning of x* and x*? |
i | Case insensitive |
m | Multi-line mode |
s | Allow . to match |
u | Unicode support (enabled by default) |
x | Ignore whitespace |
Named Captures
Regular expressions support named capture groups, allowing extractions to be associated with keys.
Named captures should be preceded with a ?P<name>
declaration. This regex, for example…
r'(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})'
…extracts captures with the y
, m
, and d
keys.
String
A string literal is a UTF-8–encoded string. String literals can be raw or interpreted.
Raw string literals are composed of the uninterpreted (implicitly UTF-8-encoded) characters between single
quotes identified with the s
sigil and wrapped with single quotes (s'...'
); in particular, backslashes have
no special meaning and the string may contain newlines.
Interpreted string literals are character sequences between double quotes ("..."
). Within the quotes,
any character may appear except unescaped newline and unescaped double quote. The text between the quotes forms the result
of the literal, with backslash escapes interpreted as defined below. Strings can be templated by enclosing
variables in {{..}}
. The value of the variables are inserted into the string at that position.
Examples
"Hello, world! 🌎"
"Hello, world! \u1F30E"
"Hello, \
world!"
"Hello, {{ planet }}!"
s'Hello, world!'
s'{ "foo": "bar" }'
Characteristics
Backslash escapes
Option | Description |
---|---|
\" | Double quote |
\' | Single quote |
\0 | Null |
\\ | Backslash |
\n | Newline |
\r | Carriage return |
\t | Tab |
\u{7FFF} | 24-bit Unicode character code (up to 6 digits) |
\{ | Brace |
Concatenation
+
operator.Invalid Characters
�
character.Multiline strings
Templates
{{..}}
. The
value of the variable is inserted into the string at this position at runtime.
Currently, the variable has to be a string. Only variables are supported, if
you want to insert a path from the event you must assign it to a variable
first. To insert a {{
into the string it can be escaped with a \
escape: \{{..\}}
. We plan to expand this in future to allow paths and
format strings to enable non string variables.Timestamp
A timestamp literal defines a native timestamp expressed in the RFC 3339 format with a nanosecond precision.
Timestamp literals are defined by the t
sigil and wrapped with single quotes (t'2021-02-11T10:32:50.553955473Z'
).
Examples
t'2021-02-11T10:32:50.553955473Z'
t'2021-02-11T10:32:50.553Z'
t'2021-02-11T10:32:50.553-04:00'
Characteristics
Timezones
Dynamic expressions
VRL is an expression-oriented language. A VRL program consists entirely of expressions and every expression returns a value.
Abort
abort
expression causes the VRL program to terminate, aborting any
modifications made to the event.Grammar
abort ~ message?
Argument | Meaning |
---|---|
message | message is an optional debug message that can be used for diagnostic purposes and is included in a remap transform’s dropped event metadata. |
Examples
Ignoring invalid events
{
"log": {
"message": "hello world"
}
}
if contains(string!(.message), "hello") {
abort
}
.message = "not hello world"
{
"message": "hello world"
}
Arithmetic
An arithmetic expression performs an operation on two expressions (operands) as defined by the operator.
Although arithmetic is commonly applied to numbers, you can use it with other types as well, such as strings.
Grammar
expression ~ operator ~ expression
Argument | Meaning |
---|---|
expression | The expression can be any expression that returns a valid type as defined by the operator . |
operator | The operator defines the operation performed on the left-hand- and right-hand-side operands. |
Examples
Sum (int)
1 + 1
2
Sum (float)
1.0 + 1.0
2
Sum (numeric)
1 + 1.0
2
Sum (string)
"Hello" + ", " + "World!"
Hello, World!
Difference (int)
2 - 1
1
Difference (float)
2.0 - 1.0
1
Difference (numeric)
2.0 - 1
1
Multiplication (int)
2 * 1
2
Multiplication (float)
2.0 * 1.0
2
Multiplication (numeric)
2.0 * 1
2
Float division (int)
2 / 1
2
Float division (float)
2.0 / 1.0
2
Float division (numeric)
2.0 / 1
2
Remainder
mod(3, 2)
1
Assignment
Grammar
target ~ ("," ~ error)? ~ operator ~ expression
Argument | Meaning |
---|---|
error | The error allows for optional assignment to errors when the right-hand-side expression is
fallible. This is commonly used when invoking fallible functions. |
expression | If the If the |
operator | The operator delimits the target and expression and defines assignment conditions. |
target | The target must be a path,
with an optional second variable for error handling if the right-hand side is fallible. |
Examples
Path assignment
.message = "Hello, World!"
Nested path assignment
.parent.child = "Hello, World!"
Double assignment
.first = .second = "Hello, World!"
Array element assignment
.array[1] = "Hello, World!"
Variable assignment
my_variable = "Hello, World!"
.my_field = my_variable
Hello, World!
Object merge assignment
my_variable = {"message": "Hello, World!"}
my_variable |= {"level": "info"}
{
"level": "info",
"message": "Hello, World!"
}
Fallible assignment (success)
.parsed, .err = parse_json("{\"Hello\": \"World!\"}")
Fallible assignment (error)
.parsed, .err = parse_json("malformed")
Block
A block expression is a sequence of one or more expressions within matching brace brackets.
Blocks can’t be empty. Instead, empty blocks ({}
) are treated as blank objects.
Grammar
"{" ~ NEWLINE* ~ expressions ~ NEWLINE* ~ "}"
Argument | Meaning |
---|---|
expressions | One or more expressions. |
Examples
Simple block
{
message = "{\"Hello\": \"World!\"}"
parse_json!(message)
}
{
"Hello": "World!"
}
Assignment block
.structured = {
message = "{\"Hello\": \"World!\"}"
parse_json!(message)
}
Coalesce
Grammar
expression ~ (operator ~ expression)+
Argument | Meaning |
---|---|
expression | The expression (operand) can be any expression. |
operator | The operator delimits two or more expression s. |
Examples
Error coalescing
parse_syslog("not syslog") ?? parse_common_log("not common") ?? "malformed"
malformed
Comparison
Grammar
expression ~ operator ~ expression
Argument | Meaning |
---|---|
expression | The expression (operand) can be any expression that returns a valid type as defined by the
operator . |
operator | The operator defines the operation performed on the left-hand and right-hand side operations. |
Examples
Equal integers
1 == 1
true
Equal integer and float
1 == 1.0
true
Not equal
1 != 2
true
Equal string
x = "foo"
x == "foo"
true
Not equal strings
"foo" != "bar"
true
Greater than or equal
2 >= 2
true
Greater than
2 > 1
true
Less than or equal
2 <= 2
true
Less than
1 < 2
true
Less than timestamps
t'2024-04-04T22:22:22.234142+01:00' < t'2024-04-04T22:22:22.234142+04:00'
Function call
Grammar
function ~ abort? ~ "(" ~ arguments? ~ ")" ~ closure?
Argument | Meaning |
---|---|
abort |
Otherwise, errors must be handled:
Failure to handle errors from fallible functions results in compile-time errors. See the error reference for more info. |
arguments | The arguments are comma-delimited expressions that can optionally be prefixed with the
documented name. |
closure | The
|
function | function represents the name of the built-in function. |
Examples
Positional function invocation
split("hello, world!", ", ")
["hello","world!"]
Named function invocation (ordered)
split("hello, world!", pattern: ", ")
["hello","world!"]
Named function invocation (unordered)
split(pattern: ", ", value: "hello, world!")
["hello","world!"]
Infallible function invocation
split("apples and pears and bananas", " and ")
["apples","pears","bananas"]
Fallible function invocation
{
"log": {
"message": "apples and pears and bananas"
}
}
# The compiler cannot determine the argument type thus we need to do error handling.
split!(.message, " and ")
["apples","pears","bananas"]
Characteristics
Deprecation
VRL functions can be marked as “deprecated”. When a function is deprecated, a warning will be shown at runtime.
Suggestions on how to update the VRL program can usually be found in the actual warning and the function documentation.
Function Fallibility
VRL functions can be marked as “fallible” or “infallible”. When a function is defined as fallible, it can fail at runtime, requiring the error to be handled before the program can be compiled.
If a function is defined as infallible, it means that given the correct function arguments, the function can never fail at runtime, and thus no error handling is needed.
Note that even if a function is defined as infallible, if any of its arguments can fail at runtime, the function is considered to be fallible, and thus the error case needs to be handled in this case.
The VRL compiler ensures all potential errors in a program are handled, so there’s no need to worry about missing any potential runtime failures.
Purity
If
true
, the “if” branch is executed, otherwise the “else”
branch is executed (if present).Grammar
"if" ~ predicate ~ block ~ ("else if" ~ predicate ~ block)* ~ ("else" ~ block)?
Argument | Meaning |
---|---|
predicate | The predicate must be an expression that resolves to a Boolean. If a Boolean isn’t returned, a
compile-time error is raised.
The predicate can contain multiple expressions. Multiple expression predicates must be wrapped in
parentheses. The expressions need to be separated by either a semicolon (; ) or a new line. |
Examples
True if expression
if true {
"Hello, World!"
}
Hello, World!
False if expression
if false {
# not evaluated
null
}
If/else expression
if false {
# not evaluated
null
} else {
"Hello, World!"
}
Hello, World!
If/else if/else expression
if false {
# not evaluated
null
} else if false {
# not evaluated
null
} else {
"Hello, World!"
}
Hello, World!
Multiline expression
x = 3
if (x = x + 1; x == 5) {
# not evaluated
null
} else if (
x = x + 1
x == 5
) {
"Hello, World!"
}
Hello, World!
Index
Grammar
"[" ~ index ~ "]"
Argument | Meaning |
---|---|
index | The index represents the zero-based position of the element. |
Examples
Array index expression
{
"log": {
"array": [
"first",
"second"
]
}
}
.array[0]
first
Logical
Grammar
expression ~ operator ~ expression
Argument | Meaning |
---|---|
expression | The expression (operand) can be any expression that returns a valid type as defined by the
operator . |
operator | The operator defines the operation performed on the left-hand- and right-hand-side operations. |
Examples
AND
true && true
true
OR (boolean)
false || "foo"
foo
OR (null)
null || "foo"
foo
NOT
!false
true
Path
Grammar
"." ~ path_segments
Argument | Meaning |
---|---|
"%" | The % character represents the root of the event metadata. |
"." | The . character represents the root of the event. All paths must begin with . or % |
path_segments | path_segments denote a segment of a nested path. Each segment must be delimited by a . character
and only contain alpha-numeric characters and _ (a-zA-Z0-9_ ). Segments that contain
characters outside of this range must be quoted. |
Examples
Root event path
{
"log": {
"message": "Hello, World!"
}
}
.
{
"message": "Hello, World!"
}
Root metadata path
{
"log": {
"message": "Hello, World!"
}
}
%
Top-level path
{
"log": {
"message": "Hello, World!"
}
}
.message
Hello, World!
Nested path
{
"log": {
"parent": {
"child": "Hello, World!"
}
}
}
.parent.child
Hello, World!
Array element path (first)
{
"log": {
"array": [
"first",
"second"
]
}
}
.array[0]
first
Array element path (second)
{
"log": {
"array": [
"first",
"second"
]
}
}
.array[1]
second
Quoted path
{
"log": {
"parent.key.with.special characters": {
"child": "Hello, World!"
}
}
}
."parent.key.with.special characters".child
Hello, World!
Variable
Grammar
first ~ (trailing)*
Argument | Meaning |
---|---|
first | The first character can only be an alpha-numeric character (a-zA-Z0-9 ). |
trailing | The trailing characters must only contain ASCII alpha-numeric and underscore characters
(a-zA-Z0-9_ ). |
Examples
Simple variable
my_variable = 1
my_variable == 1
true
Variable with path
my_object = { "one": 1 }
my_object.one
1