Function Reference¶
Complete reference for all 40+ built-in Rhai functions available in Kelora. Functions are organized by category for easy lookup.
Function Call Syntax
Rhai allows two styles: value.method(args) or function(value, args). Use whichever feels more natural.
Quick Navigation¶
- String Functions - Text manipulation, parsing, encoding
- Array Functions - Array operations, sorting, filtering
- Map/Object Functions - Field access, manipulation, conversion
- DateTime Functions - Time parsing, formatting, arithmetic
- Math Functions - Numeric operations
- Type Conversion - Safe type conversions
- Utility Functions - Environment, files, pseudonyms
- Tracking/Metrics - Counters, aggregations
- File Output - Writing data to files
- Event Manipulation - Field removal, fan-out
- Span Context - Per-span metadata & rollups
String Functions¶
Extraction and Searching¶
text.extract_re(pattern [, group])¶
Extract first regex match or capture group.
e.error_code = e.message.extract_re(r"ERR-(\d+)", 1) // "ERR-404" → "404"
e.full_match = e.line.extract_re(r"\d{3}") // First 3-digit number
text.extract_all_re(pattern [, group])¶
Extract all regex matches as array.
e.numbers = e.line.extract_all_re(r"\d+") // All numbers
e.codes = e.message.extract_all_re(r"ERR-(\d+)", 1) // All error codes
text.extract_re_maps(pattern, field)¶
Extract regex matches as array of maps for fan-out with emit_each().
// Extract all error codes with context
let errors = e.log.extract_re_maps(r"(?P<code>ERR-\d+): (?P<msg>[^\n]+)", "error");
emit_each(errors) // Each match becomes an event with 'code' and 'msg' fields
text.extract_ip([nth])¶
Extract IP address from text (nth: 1=first, -1=last).
e.client_ip = e.headers.extract_ip() // First IP
e.origin_ip = e.forwarded.extract_ip(-1) // Last IP
text.extract_ips()¶
Extract all IP addresses as array.
text.extract_url([nth])¶
Extract URL from text (nth: 1=first, -1=last).
text.extract_domain()¶
Extract domain from URL or email address.
e.domain = "https://api.example.com/path".extract_domain() // "example.com"
e.mail_domain = "user@corp.example.com".extract_domain() // "corp.example.com"
String Slicing and Position¶
text.before(delimiter [, nth])¶
Text before occurrence of delimiter (nth: 1=first, -1=last).
e.user = e.email.before("@") // "user@host.com" → "user"
e.path = e.url.before("?") // Strip query string
text.after(delimiter [, nth])¶
Text after occurrence of delimiter (nth: 1=first, -1=last).
e.extension = e.filename.after(".") // "file.txt" → "txt"
e.domain = e.email.after("@") // "user@host.com" → "host.com"
text.between(start, end)¶
Text between start and end delimiters.
text.starting_with(prefix [, nth])¶
Return substring from prefix to end (nth: 1=first, -1=last).
text.ending_with(suffix [, nth])¶
Return substring from start to end of suffix (nth: 1=first, -1=last).
text.slice(spec)¶
Slice text using Python notation (e.g., "1:5", ":3", "-2:").
e.first_three = e.code.slice(":3") // "ABCDEF" → "ABC"
e.last_two = e.code.slice("-2:") // "ABCDEF" → "EF"
e.middle = e.code.slice("2:5") // "ABCDEF" → "CDE"
Column Extraction¶
text.col(spec [, separator])¶
Extract columns by index/range/list (e.g., '1', '1,3,5', '1:4').
e.first = e.line.col("1") // First column (1-indexed)
e.cols = e.line.col("1,3,5") // Columns 1, 3, 5
e.range = e.line.col("2:5", "\t") // Columns 2-5, tab-separated
Parsing Functions¶
text.parse_json()¶
Parse JSON string into map/array.
text.parse_logfmt()¶
Parse logfmt line into structured fields.
text.parse_syslog()¶
Parse syslog line into structured fields.
text.parse_combined()¶
Parse Apache/Nginx combined log line.
text.parse_cef()¶
Parse Common Event Format line into fields.
text.parse_kv([sep [, kv_sep]])¶
Parse key-value pairs from text.
text.parse_url()¶
Parse URL into structured components.
text.parse_query_params()¶
Parse URL query string into map.
text.parse_email()¶
Parse email address into parts.
let email = "User Name <user@example.com>".parse_email()
e.name = email["name"] // "User Name"
e.address = email["address"] // "user@example.com"
text.parse_user_agent()¶
Parse common user-agent strings into components.
text.parse_jwt()¶
Parse JWT header/payload without verification.
text.parse_path()¶
Parse filesystem path into components.
let path = "/var/log/app.log".parse_path()
e.dir = path["dir"] // "/var/log"
e.file = path["file"] // "app.log"
text.parse_media_type()¶
Parse media type tokens and parameters.
let mt = "text/html; charset=utf-8".parse_media_type()
e.type = mt["type"] // "text"
e.subtype = mt["subtype"] // "html"
text.parse_content_disposition()¶
Parse Content-Disposition header parameters.
Encoding and Hashing¶
text.encode_b64() / text.decode_b64()¶
Base64 encoding/decoding.
text.encode_hex() / text.decode_hex()¶
Hexadecimal encoding/decoding.
text.encode_url() / text.decode_url()¶
URL percent encoding/decoding.
e.encoded = e.param.encode_url() // "hello world" → "hello%20world"
e.decoded = e.url_param.decode_url()
text.escape_json() / text.unescape_json()¶
JSON escape sequence handling.
text.escape_html() / text.unescape_html()¶
HTML entity escaping/unescaping.
e.safe = e.user_input.escape_html() // "<script>" → "<script>"
e.text = e.html_entity.unescape_html()
text.hash([algo])¶
Hash with algorithm (default: sha256, also: sha1, md5, xxh3, blake3).
e.checksum = e.content.hash() // SHA-256
e.md5 = e.file.hash("md5")
e.fast = e.data.hash("xxh3") // Fast non-crypto hash
text.bucket()¶
Fast hash for sampling/grouping (returns INT for modulo operations).
IP Address Functions¶
text.is_ipv4() / text.is_ipv6()¶
Check if text is a valid IP address.
text.is_private_ip()¶
Check if IP is in private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
text.is_in_cidr(cidr)¶
Check if IP address is in CIDR network.
text.mask_ip([octets])¶
Mask IP address (default: last octet).
e.masked_ip = e.client_ip.mask_ip() // "192.168.1.100" → "192.168.1.0"
e.partial = e.ip.mask_ip(2) // Mask last 2 octets
Pattern Normalization¶
text.normalized([patterns])¶
Replace variable patterns with placeholders (e.g., <ipv4>, <email>).
Useful for identifying unique log patterns by normalizing variable data like IP addresses, UUIDs, and email addresses to fixed placeholders.
// Default patterns (IPs, emails, UUIDs, hashes, etc.)
e.pattern = e.message.normalized()
// "User user@test.com from 192.168.1.5" → "User <email> from <ipv4>"
// CSV-style pattern list
e.simple = e.message.normalized("ipv4,email")
// Array-style pattern list
e.custom = e.message.normalized(["uuid", "sha256", "url"])
Default patterns (when no argument provided):
ipv4_port, ipv4, ipv6, email, url, fqdn, uuid, mac, md5, sha1, sha256, path, oauth, function, hexcolor, version
Available patterns (opt-in):
hexnum, duration, num
Common use case - Pattern discovery:
# Recommended alias for easy pattern discovery
kelora --save-alias patterns \
--exec 'track_unique("patterns", e.message.normalized())' \
--metrics -qq
# Usage
kelora -a patterns app.log
Output with many patterns:
patterns (127 unique):
User <email> from <ipv4>
Request to <url> failed
Error <uuid> occurred
Connection <ipv4_port> established
Processing <fqdn> with <sha256>
[+122 more. Use --metrics-file or --end script for full list]
For custom analysis, access full data in --end scripts or --metrics-file.
String Manipulation¶
text.strip([chars]) / text.lstrip([chars]) / text.rstrip([chars])¶
Remove whitespace or specified characters.
e.clean = e.text.strip() // Remove leading/trailing whitespace
e.trimmed = e.line.lstrip("# ") // Remove "# " from left
e.path = e.filename.rstrip("/") // Remove trailing slashes
text.clip() / text.lclip() / text.rclip()¶
Remove non-alphanumeric characters from edges.
e.word = "'hello!'".clip() // → "hello"
e.left = "...start".lclip() // → "start"
e.right = "end...".rclip() // → "end"
text.upper() / text.lower()¶
Case conversion.
text.replace(pattern, replacement)¶
Replace all occurrences of pattern.
text.split(separator) / text.split_re(pattern)¶
Split string into array.
String Testing¶
text.contains(pattern)¶
Check if text contains pattern.
text.has_matches(pattern)¶
Check if text matches regex pattern.
text.is_digit()¶
Check if text contains only digits.
text.count(pattern)¶
Count occurrences of pattern in text.
text.edit_distance(other)¶
Compute Levenshtein edit distance between two strings.
text.index_of(pattern)¶
Find position of substring (-1 if not found).
Array Functions¶
Sorting and Filtering¶
array.sorted()¶
Return new sorted array (numeric/lexicographic).
e.sorted_scores = sorted(e.scores) // [3, 1, 2] → [1, 2, 3]
e.sorted_names = sorted(e.names) // Alphabetical
array.sorted_by(field)¶
Sort array of objects by field name.
array.reversed()¶
Return new array in reverse order.
array.unique()¶
Remove all duplicate elements (preserves first occurrence).
array.filter(|item| condition)¶
Keep elements matching condition.
Aggregation¶
array.max() / array.min()¶
Find maximum/minimum value in array.
array.percentile(pct)¶
Calculate percentile of numeric array.
array.reduce(|acc, item| expr, init)¶
Aggregate array into single value.
Transformation¶
array.map(|item| expression)¶
Transform each element.
array.flatten([style [, max_depth]])¶
Flatten nested arrays/objects.
e.flat = [[1, 2], [3, 4]].flatten() // [1, 2, 3, 4]
e.fields = e.nested.flatten("dot", 2) // Flatten to dot notation
Testing¶
array.contains(value)¶
Check if array contains value.
array.contains_any(search_array)¶
Check if array contains any search values.
array.starts_with_any(search_array)¶
Check if array starts with any search values.
array.all(|item| condition) / array.some(|item| condition)¶
Check if all/any elements match condition.
Other Operations¶
array.join(separator)¶
Join array elements with separator.
array.push(item) / array.pop()¶
Add/remove items from array.
Map/Object Functions¶
Field Access¶
map.get_path("field.path" [, default])¶
Safe nested field access with fallback.
map.has_path("field.path")¶
Check if nested field path exists.
map.path_equals("path", value)¶
Safe nested field comparison.
map.has_field("key")¶
Check if map contains key with non-unit value.
Field Manipulation¶
map.rename_field("old", "new")¶
Rename a field, returns true if successful.
map.merge(other_map)¶
Merge another map into this one.
map.flatten([separator [, style]])¶
Flatten nested object to dot notation.
map.unflatten([separator])¶
Reconstruct nested object from flat keys.
Format Conversion¶
map.to_json([pretty])¶
Convert map to JSON string.
map.to_logfmt()¶
Convert map to logfmt format string.
map.to_kv([sep [, kv_sep]])¶
Convert map to key-value string with separators.
map.to_syslog() / map.to_cef() / map.to_combined()¶
Convert map to specific log format.
e.syslog_line = e.fields.to_syslog()
e.cef_line = e.security_event.to_cef()
e.access_log = e.request.to_combined()
DateTime Functions¶
Creation¶
now_utc() / now_local()¶
Current timestamp.
to_datetime(text [, fmt [, tz]])¶
Convert string into DateTimeWrapper with optional hints.
e.parsed = to_datetime("2024-01-15 10:30:00", "%Y-%m-%d %H:%M:%S", "UTC")
e.auto = to_datetime("2024-01-15T10:30:00Z") // Auto-detect format
to_duration("1h30m")¶
Convert duration string into DurationWrapper.
duration_from_seconds(n), duration_from_minutes(n), etc.¶
Create duration from specific units.
Formatting¶
dt.to_iso()¶
Convert datetime to ISO 8601 string.
dt.format("format_string")¶
Format datetime using custom format string (see --help-time).
e.date = e.timestamp.format("%Y-%m-%d") // "2024-01-15"
e.time = e.timestamp.format("%H:%M:%S") // "10:30:00"
Component Extraction¶
dt.year(), dt.month(), dt.day()¶
Extract date components.
dt.hour(), dt.minute(), dt.second()¶
Extract time components.
Timezone Conversion¶
dt.to_utc() / dt.to_local()¶
Convert timezone.
dt.to_timezone("tz_name")¶
Convert to named timezone.
dt.timezone_name()¶
Get timezone name as string.
Arithmetic and Comparison¶
dt + duration, dt - duration¶
Add/subtract duration from datetime.
dt1 - dt2¶
Get duration between datetimes.
dt1 == dt2, dt1 > dt2, etc.¶
Compare datetimes.
Duration Operations¶
duration.as_seconds(), duration.as_milliseconds(), etc.¶
Convert duration to specific units.
duration.to_string() / humanize_duration(ms)¶
Format duration as human-readable string.
Math Functions¶
abs(x)¶
Absolute value of number.
clamp(value, min, max)¶
Constrain value to be within min/max range.
floor(x) / round(x)¶
Rounding operations.
mod(a, b) / a % b¶
Modulo operation with division-by-zero protection.
rand() / rand_int(min, max)¶
Random number generation.
Type Conversion Functions¶
to_int(value) / to_float(value) / to_bool(value)¶
Convert value to type (returns () on error).
to_int_or(value, default) / to_float_or(value, default) / to_bool_or(value, default)¶
Convert value to type with fallback.
Utility Functions¶
get_env(var [, default])¶
Get environment variable with optional default.
pseudonym(value, domain)¶
Generate domain-separated pseudonym (requires KELORA_SECRET).
read_file(path) / read_lines(path)¶
Read file contents.
print(message) / eprint(message)¶
Print to stdout/stderr (suppressed with -qqq).
exit(code)¶
Exit kelora with given exit code.
type_of(value)¶
Get type name as string.
window_values(field) / window_numbers(field)¶
Get field values from current window (requires --window).
let recent_statuses = window_values("status")
let recent_times = window_numbers("response_time")
e.avg_time = recent_times.reduce(|s, x| s + x, 0) / recent_times.len()
Tracking/Metrics Functions¶
All tracking functions require the --metrics flag.
Tracking Functions¶
track_count(key)¶
Increment counter for key by 1.
track_sum(key, value)¶
Accumulate numeric values for key.
track_min(key, value) / track_max(key, value)¶
Track minimum/maximum value for key.
track_unique(key, value)¶
Track unique values for key.
track_bucket(key, bucket)¶
Track values in buckets for histograms.
File Output Functions¶
All file output functions require the --allow-fs-writes flag.
append_file(path, text_or_array)¶
Append line(s) to file; arrays append one line per element.
truncate_file(path)¶
Create or zero-length a file for fresh output.
mkdir(path [, recursive])¶
Create directory (set recursive=true to create parents).
Event Manipulation¶
emit_each(array [, base_map])¶
Fan out array elements as separate events (returns emitted count).
emit_each(e.users) // Each user becomes an event
emit_each(e.items, #{batch_id: e.batch_id}) // Add batch_id to each
e = ()¶
Clear entire event (remove all fields).
e.field = ()¶
Remove individual field from event.
Span Context – --span-close Only¶
A read-only span object is injected into scope whenever a --span-close script runs. Use it to emit per-span rollups after Kelora closes a count- or time-based window.
Span Identity¶
span.id returns the current span identifier. Count-based spans use #<index> (zero-based). Time-based spans use ISO_START/DURATION (e.g. 2024-05-19T12:00:00Z/5m).
Span Boundaries¶
span.start and span.end expose the half-open window bounds as DateTime values. Count-based spans return () for both fields.
Span Size and Events¶
span.size reports how many events survived filters and were buffered in the span. span.events returns those events in arrival order. Each map includes span metadata fields (span_status, span_id, span_start, span_end) alongside the original event data.
Metrics Snapshot¶
span.metrics contains per-span deltas from track_* calls. Values reset automatically after each span closes, so you can emit per-span summaries without manual bookkeeping.
let metrics = span.metrics;
let hits = metrics["events"]; // from track_count("events")
let failures = metrics["failures"]; // from track_count("failures")
let ratio = if hits > 0 { failures * 100 / hits } else { 0 };
print(span.id + ": " + ratio.to_string() + "% failure rate");
Quick Reference by Use Case¶
Error Extraction:
IP Anonymization:
Time Filtering:
Metrics Tracking:
Array Fan-Out:
Safe Field Access:
e.user_name = e.get_path("user.profile.name", "unknown")
if e.has_path("error.details.code") {
e.detailed = true
}
See Also¶
- CLI Reference - Command-line flags and options
- Rhai Cheatsheet - Rhai language syntax
- Scripting Transforms Tutorial - Learn advanced scripting
- How-To: Extract and Mask Sensitive Data - Practical examples
For more details, run: