eval
eval
Create or modify fields using expressions and functions. Calculate new values, transform data, and perform mathematical operations.
Description
The eval command creates new fields or modifies existing ones by evaluating expressions. It operates on each event individually, allowing you to perform calculations, string manipulations, type conversions, and conditional logic.
Unlike aggregation commands, eval preserves all events and adds or updates fields without reducing the result set.
Syntax
... | eval <field>=<expression> [, <field>=<expression> ...]Required Arguments
field
Name of the field to create or modify.
expression
An expression that produces a value. Can include fields, literals, operators, and functions.
Operators
Arithmetic Operators
| Operator | Description | Example |
|---|---|---|
+ | Addition | bytes_in + bytes_out |
- | Subtraction | end_time - start_time |
* | Multiplication | price * quantity |
/ | Division | total / count |
% | Modulo | value % 10 |
String Operators
| Operator | Description | Example |
|---|---|---|
+ | Concatenation | first_name + " " + last_name |
Comparison Operators
| Operator | Description | Example |
|---|---|---|
= | Equal | status = 200 |
!= | Not equal | user != "admin" |
> | Greater than | bytes > 1000 |
< | Less than | response_time < 100 |
>= | Greater or equal | count >= 10 |
<= | Less or equal | failures <= 5 |
CONTAINS | Substring match | command_line CONTAINS "-enc" |
LIKE | Pattern match (% wildcard) | url LIKE "%.php%" |
Logical Operators
| Operator | Description | Example |
|---|---|---|
AND | Logical AND | status = 200 AND bytes > 1000 |
OR | Logical OR | status = 500 OR status = 503 |
NOT | Logical NOT | NOT (status = 200) |
Functions
String Functions
lower(str)
Convert string to lowercase.
* | eval user_lower = lower(user)upper(str)
Convert string to uppercase.
* | eval method_upper = upper(http_method)substr(str, start, length)
Extract substring. Start is 0-indexed.
* | eval first_octet = substr(src_ip, 0, 3)replace(str, pattern, replacement)
Replace pattern with replacement string.
* | eval clean_url = replace(url, "/api/v[0-9]+/", "/api/")trim(str)
Remove leading and trailing whitespace.
* | eval clean_user = trim(user)len(str)
Return string length.
* | eval url_length = len(url)split(str, delimiter)
Split string into array.
* | eval path_parts = split(file_path, "/")concat(str1, str2, ...)
Concatenate multiple strings.
* | eval full_name = concat(first_name, " ", last_name)Mathematical Functions
abs(num)
Absolute value.
* | eval abs_diff = abs(expected - actual)ceil(num)
Round up to nearest integer.
* | eval rounded_up = ceil(response_time)floor(num)
Round down to nearest integer.
* | eval rounded_down = floor(bytes / 1024)round(num, decimals)
Round to specified decimal places.
* | eval rounded_time = round(response_time, 2)sqrt(num)
Square root.
* | eval std_dev = sqrt(variance)pow(base, exponent)
Raise to power.
* | eval squared = pow(value, 2)log(num)
Natural logarithm.
* | eval log_bytes = log(bytes)exp(num)
Exponential (e^x).
* | eval exp_value = exp(rate * time)Type Conversion Functions
tonumber(str)
Convert string to number.
* | eval status_num = tonumber(status_code)tostring(num)
Convert number to string.
* | eval port_str = tostring(dest_port)tobool(value)
Convert to boolean.
* | eval is_error = tobool(status >= 400)Conditional Functions
if(condition, true_value, false_value)
Conditional expression.
* | eval severity = if(status >= 500, "critical", "normal")case(condition1, value1, condition2, value2, ..., default)
Multiple conditions.
* | eval category = case(
status < 300, "success",
status < 400, "redirect",
status < 500, "client_error",
status >= 500, "server_error",
"unknown"
)coalesce(field1, field2, ..., default)
Return first non-null value.
* | eval ip = coalesce(src_ip, client_ip, "unknown")nullif(field, value)
Return null if field equals value.
* | eval clean_user = nullif(user, "")Date/Time Functions
now()
Current timestamp.
* | eval current_time = now()strftime(timestamp, format)
Format timestamp as string.
* | eval date_str = strftime(timestamp, "%Y-%m-%d")strptime(str, format)
Parse string to timestamp.
* | eval parsed_time = strptime(date_field, "%Y-%m-%d %H:%M:%S")time()
Current Unix timestamp in seconds.
* | eval current_epoch = time()Network Functions
cidrmatch(cidr, ip)
Check if IP is in CIDR range.
* | eval is_internal = cidrmatch("192.168.0.0/16", src_ip)iplocation(ip)
Get IP geolocation (requires enrichment).
* | eval geo = iplocation(src_ip)Cryptographic Functions
md5(str)
Calculate MD5 hash.
* | eval hash = md5(user + password)sha1(str)
Calculate SHA1 hash.
* | eval hash = sha1(message)sha256(str)
Calculate SHA256 hash.
* | eval hash = sha256(file_content)Examples
Calculate total bytes
* | eval total_bytes = bytes_in + bytes_outConvert bytes to megabytes
* | eval mb = round(bytes / 1048576, 2)Calculate duration
* | eval duration_seconds = end_time - start_time
| eval duration_minutes = round(duration_seconds / 60, 1)Categorize response times
* | eval performance = case(
response_time < 100, "excellent",
response_time < 500, "good",
response_time < 1000, "acceptable",
response_time >= 1000, "poor",
"unknown"
)Extract domain from email
* | eval domain = replace(email, "^[^@]+@", "")Create full name
* | eval full_name = first_name + " " + last_nameDetect encoded commands
* | eval is_encoded = if(command_line CONTAINS "-enc", 1, 0)Uses CONTAINS as an infix operator inside a conditional.
Flag suspicious URLs
* | eval is_php = if(url LIKE "%.php?%", "yes", "no")Uses LIKE pattern matching inside eval.
Detect suspicious activity
* | eval is_suspicious = if(
(bytes_out > 1000000 AND hour >= 22) OR
(failed_logins > 5),
true,
false
)Calculate percentage
* | eval success_rate = round((successful / total) * 100, 2)Normalize user names
* | eval normalized_user = lower(trim(user))Check IP range
* | eval is_private = cidrmatch("10.0.0.0/8", src_ip) OR
cidrmatch("172.16.0.0/12", src_ip) OR
cidrmatch("192.168.0.0/16", src_ip)Flag external IPs
* | eval is_external = if(cidr_match(src_ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"), 0, 1) | where is_external = 1Create risk score
* | eval risk_score =
if(failed_logins > 10, 30, 0) +
if(bytes_out > 10000000, 40, 0) +
if(hour < 6 OR hour > 22, 20, 0) +
if(is_admin = true, 10, 0)Format timestamp
* | eval date = strftime(timestamp, "%Y-%m-%d")
| eval time = strftime(timestamp, "%H:%M:%S")Calculate age
* | eval age_seconds = now() - first_seen
| eval age_days = floor(age_seconds / 86400)Multiple assignments
* | eval
total = bytes_in + bytes_out,
ratio = bytes_out / bytes_in,
category = if(ratio > 2, "upload", "download")Usage Notes
Order matters: Assignments are evaluated left to right. Later assignments can reference earlier ones in the same eval command.
Field creation: If a field doesn't exist, eval creates it. If it exists, eval overwrites it.
Type handling: nano performs automatic type conversion when possible. Be explicit with conversion functions for clarity.
Null values: Operations with null typically produce null. Use coalesce() to provide defaults.
Performance: Eval is efficient but avoid complex calculations on millions of events. Consider filtering first.
Multiple evals: You can chain multiple eval commands, but combining assignments in one command is more efficient.