Script Variables¶
Which built-in variables a Rhai script can use, by stage. Language syntax and field-access idioms: Rhai Cheatsheet.
| Variable | --begin |
--filter, --exec, --exec-file |
--span-close |
--end |
|---|---|---|---|---|
e |
empty | current event, writable | empty | empty |
meta, line |
empty | current event | empty | empty |
conf |
writable | read-only | read-only | read-only |
state |
yes | yes | yes | yes |
window |
– | yes (use --window N) |
– | – |
metrics |
– | – | read-only | read-only |
span |
– | – | yes | – |
– means the name is undefined there and using it is a script error. state exists only in sequential mode: any access with --parallel is a script error in every stage. track_*() can be called in every stage.
Each --filter/--exec is a separate script: let variables and fn definitions do not carry to the next stage, changes to e, state, and tracked metrics do. See Stages and their scope.
e¶
The current event as a map. Assigning a field sets it, assigning () removes it, e = () drops the event. In --exec the changes are passed on to later stages and the output; if the stage fails, they are rolled back.
line¶
The input text of the current event as a string: one line, or the assembled block with --multiline. The line terminator is stripped. Assigning to line changes only the script's local copy.
meta¶
Per-event metadata, filled in by Kelora. Assignments are visible only within the same script.
| Key | Type | Value |
|---|---|---|
line |
string | same as line |
line_num |
int | 1-based input line number |
filename |
string or () |
input file; () for stdin |
parsed_ts |
datetime or () |
the event's timestamp as parsed by Kelora, in UTC; () if none was found. Unlike the original string field (e.g. e.timestamp), it supports date arithmetic directly: meta.parsed_ts.round_to("1h"), (meta.parsed_ts - other).as_seconds() |
span_id |
string | with --span/--span-idle: id of the event's span (see span.id) |
span_start, span_end |
datetime or () |
bounds of the event's span; () for count and field spans |
span_status |
string | with spans: "included", "late" (time span already closed), "unassigned", or "filtered" |
Missing keys read as ().
conf¶
A map for settings and lookup tables. Fill it in --begin; in all later stages it is read-only.
kelora -j app.log \
--begin 'conf.env = get_env("ENVIRONMENT", "dev"); conf.slow_ms = 500' \
--filter 'e.duration_ms > conf.slow_ms'
More: Lookups.
state¶
A map that persists across all events and input files of one run, from --begin through --end. Use it when a decision about the current event depends on earlier events (deduplication, request/response pairing, sessions). For counts and totals, track_*() is simpler and also works with --parallel.
| Operation | Syntax |
|---|---|
| read, write | state[key] (() if absent), state[key] = value |
| read with default | state.get(key, default), state.get(key) |
| test, remove | state.contains(key), state.remove(key) (returns the value) |
| size, contents | state.len(), state.is_empty(), state.keys(), state.values() |
| merge | state += map, state.mixin(map) (overwrite existing keys) |
| replace all | state.fill_with(map) |
| reset | state.clear() |
| anything else | state.to_map() returns a plain map copy: state.to_map().to_json() |
Keys must be strings: state[e.id] fails if e.id is a number; use state[e.id.to_string()]. Values can be anything. To change a nested value, read it, modify it, store it back:
state keeps everything until the run ends; remove entries you no longer need. Patterns: Cross-Event Logic.
window¶
With --window N, an array of the current event and up to N previous ones: window[0] is the current event, window[1] the one before. Entries are events as parsed, before any script changed them, and they include events that later filters drop. Each entry also carries line, line_num, and filename (if known) as fields.
if window.len() > 1 { e.delta = e.value - window[1].value }
window.pluck("latency") // that field from every entry
window.pluck_as_nums("latency") // as numbers, skipping missing/invalid
Without --window, window contains only the current event.
metrics¶
The values recorded by track_*() calls so far, as a read-only map keyed by metric name. In --end these are the final totals; in --span-close they are the running totals since the start of the run (per-span values are in span.metrics).
kelora -j app.log -q \
-e 'track_freq("level", e.level); track_inc("total")' \
--end 'print(`${metrics.level.get("ERROR") ?? 0} errors in ${metrics.total} events`)'
span¶
Only in --span-close, which runs once when a span (--span, --span-idle) closes. Read-only.
| Property | Type | Value |
|---|---|---|
span.id |
string | #0, #1, … for count spans; 2024-01-15T10:00:00Z/5m for time spans; the field value for field spans; idle-#0-<start> for idle spans |
span.label |
string | the window start for time and idle spans, otherwise span.id (what --span-summary prints) |
span.start, span.end |
datetime or () |
window bounds; () for count and field spans |
span.first_ts, span.last_ts |
datetime or () |
timestamps of the first and last events in the span, any mode; () if none had one |
span.size |
int | number of events that passed the filters and entered the span |
span.events |
array of maps | those events, each with line, line_num, filename, span_id, span_start, span_end, span_status added as fields |
span.metrics |
map | what track_*() recorded while the span was open; zero values are omitted |
span.metric(name) |
value | one entry of span.metrics, 0 if absent, () for an omitted non-additive tracker or an unrecorded min/max; dotted names reach into track_freq maps: span.metric("level.ERROR") |
kelora -j app.log --span 5m -q \
-e 'track_inc("events"); if e.level == "ERROR" { track_inc("errors") }' \
--span-close 'print(`${span.label} ${span.metric("errors")}/${span.size}`)'
span.metrics contains the additive trackers (track_freq, track_sum, track_inc, track_avg, track_unique) and the span's own track_min/track_max extremes. Trackers that cannot be split per window (track_percentiles, track_cardinality, track_top/track_bottom, track_top_by/track_bottom_by, and the percentile parts of track_stats) are omitted with a one-time warning, and span.metric() returns () for them, as for a min/max the span never recorded. Compute those from span.events:
let rts = span.events.pluck_as_nums("rt");
let max_rt = if rts.is_empty() { () } else { rts.max() };
span.events holds every event of the span in memory. More: Group into Spans.