CLI Options¶
Every command-line option, grouped as in kelora --help. This page is
generated from the help text of the Kelora version it documents, so the two
always agree. In the terminal, kelora --help KEYWORD shows only the options
matching a keyword, and kelora -h prints a one-screen summary.
Topic references in the terminal: --help-formats, --help-time,
--help-multiline, --help-regex, --help-rhai, --help-functions,
--help-examples.
Arguments¶
[FILES]...- Input files (stdin if not specified, or use "-" to explicitly specify stdin)
General¶
-h, --help- Print help (see a summary with
-h) -V, --version- Print version
Input Options¶
--no-input- Run without reading input (useful for scripts that only use
--begin/--endstages) -f, --input-format <FORMAT>-
Input format. Available formats:
auto(default),auto-per-file,json,line,raw,logfmt,syslog,cef,csv,tsv,csvnh,tsvnh,combined,cri,apache-error,glog,haproxy,iso8601-level,log4j,nginx-error,postgres,python-logging,redis,s3,cols:<spec>,regex:<pattern>. Fields of each:--help-formats.With
auto, the format is detected from the first non-empty line (stdin) or a sample of the file (files: the head plus, for larger plain files, a few probe windows deeper in); a file that mixes formats is parsed with a cascade of the detected formats automatically. For mixed stdin streams pass a cascade (below) explicitly.Use
cols:<spec>for column parsing,regex:<pattern>for regex parsing with named groups, and csv/tsv with optional type annotations.Cascade mode: pass a comma-separated list (e.g.
json,logfmt,line) to try each parser in order; the first success wins, so put catch-all fallbacks likelineorrawlast. Adds an_formatfield to each event, unless the record already has one of its own (that value is kept).Repeat
-fto build a cascade that includes spec-based parsers:-fjson-f 'cols:ts(2) level *msg'. Each-fis tried in order; put catch-alls (line,raw,cols:) last (regex declines non-matching lines, so it can sit earlier).Examples:
-f json-f json,line-f json -f 'cols:ts level *msg'-f 'regex:(?P<code:int>\\d+) (?P<msg>.*)'-f 'csv status:int bytes:int'
Default:
auto -j- Shortcut for
-fjson --file-order <ORDER>-
File processing order
Default:
cliยท Values:clinamemtime --merge-sorted- Merge already-sorted input files by timestamp; aborts on missing timestamps, parse failures, or per-file disorder
--skip-lines <N>- Skip the first N input lines
--head <N>- Read only the first N input lines (stops I/O early, complementing
--takewhich limits output events) --section-from <REGEX>- Start emitting sections from the line matching this regex (inclusive start). All
--section-*regexes are unanchored; use ^...$ to match a whole line --section-after <REGEX>- Start emitting sections after the line matching this regex (exclusive start)
--section-before <REGEX>- Stop before the line matching this regex (exclusive end)
--section-through <REGEX>- Stop after emitting the line matching this regex (inclusive end)
--max-sections <N>-
Maximum number of sections to process (default: -1 for unlimited)
Default:
-1 --keep-lines <REGEX>- Keep only input lines matching this regex pattern (applied before ignore-lines)
--ignore-lines <REGEX>- Ignore input lines matching this regex pattern
--ts-field <FIELD>- Custom timestamp field name for parsing
--ts-format <FORMAT>- Custom timestamp format for parsing (uses chrono format strings)
--input-tz <TZ>-
Assume timezone for input timestamps without timezone info (default: the TZ environment variable if set, else UTC). Use
localfor system local time.Examples:
Europe/BerlinlocalUTC
--input-year <YEAR>-
Supply the year for year-less timestamps (syslog, glog, ...) instead of guessing it from the wall clock. Use
autofor the ยฑ1yr heuristic (default).Examples:
2005auto
-M, --multiline <STRATEGY>- Multi-line event detection strategy. Supply values like
timestamp,timestamp:format=%Y-%m-%d %H-%M-%S,indent,blank,regex:match=^START,regex:match=^START:end=^END$, or a language stack-trace preset (java,python,go) for logs without timestamped headers. Seekelora --help-multilinefor details --multiline-join <JOIN>-
Join multiline lines with: space, newline, or empty. Default: space (newline for
--multiline all)Values:
spacenewlineempty --multiline-timeout <DURATION>- Flush a buffered multiline event after this much input inactivity (e.g.
400ms,2s;0= never). Default: off when reading regular files, 400ms when reading a stream (stdin, FIFO) --multiline-max-lines <N>- Split a multiline event after this many buffered lines (safety cap;
0= unlimited). Default: 10000. Ignored by--multiline all --extract-prefix <FIELD>- Extract text before separator to specified field (runs before parsing)
--prefix-sep <SEP>-
Separator string for prefix extraction (default: pipe
|)Default:
| --cols-sep <SEP>- Column separator for
cols:<spec>format (default: whitespace) --max-line-bytes <SIZE>-
Cap the number of bytes a single input line may consume in memory (default 64MiB).
This is a safety circuit breaker against runaway memory: a newline-free stream โ including a tiny gzip/zstd payload that decompresses into one enormous line โ would otherwise grow without bound and exhaust RAM. No real log line approaches the default, so it normally never triggers.
When a line exceeds the cap it is truncated to the cap and a warning (๐ธ) reports how many lines were clipped; the run still succeeds (exit 0). With
--strictan over-limit line is a hard error (exit 1) instead. Accepts a byte count or an IEC/SI suffix (64MiB, 1GiB, 1048576); 0/off/unlimited disables the cap.Reading is streamed, so a large multi-line compressed file is unaffected โ only a single over-long line trips this.
Processing Options¶
--begin <EXPR>-
Pre-run a Rhai script before any other stage runs.
Typical use: seed the global
confmap with lookup tables or shared context.Helpers available only here:
read_lines(path) -> Array<String> # UTF-8, one entry per line read_file(path) -> String # UTF-8, entire file contentsData stored in
confbecomes read-only afterwards. See--help-rhaifor stage order. --filter <EXPR>-
Boolean filter expression; events where it evaluates to true are kept.
Can be combined with
--include(-I) to call helper functions defined in an include file. Include files used with--filtermust contain only function definitions โ top-level statements are rejected with an error.Example:
See
--help-rhaifor expression syntax. -e, --exec <EXPR>- Transform/process exec scripts evaluated on each event. See
--help-rhaifor stage semantics -E, --exec-file <FILE>- Execute script from file (contents run in the exec stage)
--assert <EXPR>- Assertion expressions that must evaluate to true. Violations are reported to stderr; processing continues unless
--strictis enabled. See--help-rhaifor expression syntax -I, --include <FILE>-
Include a Rhai file of helper functions, loaded into the adjacent script stage.
Command-line position selects which stage the file applies to:
--include before a --filter/--exec โ that filter/exec stage --include before the first stage โ the --begin stage (if present) --include after the last stage โ the --end stage (if present)Each stage has its own scope: an include's functions are only visible to the stage it is attached to. Repeat
--includeto share helpers across several stages. An include that attaches to begin/end has no effect unless that--begin/--endstage exists.When used with
--filter, the include file must contain only function definitions. Top-level statements (side effects) are rejected with an error.Example:
--end <EXPR>- Run once after processing completes (post-processing stage). Ideal for summarising metrics or emitting reports. The global
metricsmap from track_*() calls is accessible here --allow-fs-writes- Allow Rhai scripts to create directories and write files on disk (required for file helpers like append_file or mkdir)
--window <N>- Keep the current event and the N before it in the
windowarray for scripts (window[0] is the current event) --span <N|DURATION|FIELD>-
Aggregate events into consecutive spans.
--span <N> Close after every N events that pass filters. --span <DURATION> Close on aligned time windows (e.g. 30s, 5m, 1h, 1d). Units: ms, s, m, h, d, w. Windows are fixed-length and aligned to the Unix epoch in UTC, so weeks run Thursday to Wednesday. --span <FIELD> Close when the specified field value changes.Use with
--span-closeto run a Rhai snippet when each span finishes. --span-idle <DURATION>- Close span after this duration of inactivity (e.g.
--span-idle5m). Requires timestamps and cannot be combined with--span. --span-close <EXPR>-
Run a Rhai snippet when each span closes. For a plain per-window rollup, use
--span-summaryinstead โ no script, and its rows survive-m/--freq(a hook's print does not).Within the hook, read span.start, span.end, span.first_ts, span.last_ts, span.id, span.label, span.events, span.size, and span.metrics for span context. span.start/span.end are the window bounds (() for count and field spans); span.first_ts/span.last_ts are the timestamps of the first and last events in the span, in every mode. span.metric("name") returns one metric's per-window value or 0 when the window produced none (() for an omitted non-additive metric), and takes a dotted path (span.metric("level.ERROR")); prefer it over indexing span.metrics, which yields () for an omitted zero delta. span.label is span.start as RFC3339 when the mode has one, else span.id, so a hook need not branch on the span mode.
span.metrics carries per-window values for additive aggregators (count, sum, avg, unique, bucket) and the window's own min and max; non-additive ones (percentiles, cardinality, top, bottom) are omitted with a warning, so use span.events for those. Events are only retained for span.events when this hook is present.
--span-summary[=<FORMAT>]-
One rollup row per closed span (implies
-q/--quiet). Requires--spanor--span-idle.Each row carries the span label, the event count, and every per-window metric from additive track_* calls and track_min/track_max (including those synthesized by
--freq/--describe).Formats: text (key=value lines), tsv (label
<TAB>metric<TAB>key<TAB>value records), json (one object per line). Bare--span-summaryauto-selects: text on a terminal, tsv when piped or redirected (like-m).Rows are data on stdout, so
--no-script-outputand-mdo not suppress them. A window that received no input produces no row, so a time series has gaps where nothing was logged; a window whose events were all removed by--filter/--levelsstill produces a row, with events=0. Windows outside--since/--untilnever appear.Examples:
--span 1m --span-summary Events per minute -l error --span 5m --span-summary Errors per 5 minutes --span 1m --freq level --span-summary Per-minute level breakdown --span-idle 5m --span-summary Session sizes --span 1m --span-summary=tsv > series.tsv Time series for a database or plotNote the
=:--span-summary=tsv(a space is read as a filename).Values:
text: Onekey=valueline per span; nested metrics flatten with a dottsv: Long/tidylabel<TAB>metric<TAB>key<TAB>valuerecords, one per valuejson: One JSON object per span, preserving nested metrics
--normalize-ts- Normalize the primary timestamp field to RFC3339 (ISO 8601 compatible). Modifies event data - affects all output formats
Error Handling¶
--strict- Exit on first error (fail-fast behavior). Use
--no-strictto force resilient mode, overriding a config default --strict-utf8-
Abort on the first non-UTF-8 byte instead of the default lossy decoding.
By default, kelora tolerates non-UTF-8 input the way grep does: invalid byte sequences are replaced with U+FFFD (๏ฟฝ) and a diagnostic reports how many lines were affected, so a single bad byte no longer truncates the rest of the stream. Pass
--strict-utf8to restore hard failure (exit 1) on invalid UTF-8. -v, --verbose...- Show detailed error information (use multiple times for more verbosity:
-v, -vv, -vvv)
Filtering Options¶
-l, --levels <LEVELS>-
Include only events with these log levels (comma-separated, case-insensitive).
Use comma-separated values for OR logic:
--levelsERROR,WARN Multiple flags create sequential AND filters (advanced).On json and logfmt input, lines whose text contains none of the levels are skipped before parsing, so their parse errors go uncounted: the parse-error summary can report fewer errors than a run without
-l. A run in which no line parses still fails with exit 1. Run without-l, or with-s/--stats, to count every parse error. -L, --exclude-levels <EXCLUDE_LEVELS>- Exclude events with these log levels (comma-separated, case-insensitive).
-k, --keys <KEYS>-
Output only these fields, in the order given (comma-separated list).
Acts on whole top-level fields. Nested values that
--discoverprints as dotted or bracketed paths (e.g. api.queries, tags[]) are NOT selectable here โ flatten them first, e.g.--exec 'e.val = e.get_path("api.queries")'then-kval. (A top-level field whose literal name contains a dot is matched as-is.) -K, --exclude-keys <EXCLUDE_KEYS>-
Exclude these fields from output (comma-separated list).
Acts on whole top-level fields; nested values (the dotted/bracketed paths shown by
--discover) cannot be dropped here โ remove them in an--execstage instead. --since <TIME>-
Keep only events at or after this time.
Accepts journalctl-style timestamps (e.g., 2024-01-15T12:00:00Z,
2024-01-15 12:00,1h,-30m,yesterday). Can also useuntil+DURATION,until-DURATION,now+DURATION, ornow-DURATIONanchors.Reads the timestamp the parser produced, before any script stage: use
--ts-field/--ts-formatto change what that is, and a--filterfor a timestamp you build in a script. See--help-time. --until <TIME>-
Keep only events at or before this time.
Accepts journalctl-style timestamps (e.g., 2024-01-15T12:00:00Z,
2024-01-15 12:00,1h,+30m,tomorrow). Can also usesince+DURATION,since-DURATION,now+DURATION, ornow-DURATIONanchors.Reads the timestamp the parser produced, before any script stage: use
--ts-field/--ts-formatto change what that is, and a--filterfor a timestamp you build in a script. See--help-time. -n, --take <N>- Limit output to the first N events
-B, --before-context <N>-
Show N events before each match (requires filtering).
See
-Cfor how context lines are marked and which filters define a match. -A, --after-context <N>-
Show N events after each match (requires filtering).
See
-Cfor how context lines are marked and which filters define a match. -C, --context <N>-
Show N events before and after each match, like grep
-C(requires filtering:--filter,--levels/-l,--exclude-levels/-L,--since/--until).In the default output format each event carries a marker naming its role. Every event appears exactly once, with the marker that describes it:
โ / * the match itself (โ on a color terminal, * otherwise) / before-context: run-up to a later match \ after-context: trails an earlier match | both at once, between two matches close enough to overlapMarkers appear only in the default format;
-Fjson/csv/logfmt emit the same events unmarked. They are part of the event line on stdout, so--no-warnings/--no-hints/--no-diagnosticsleave them alone;-qand--silentdrop the events entirely.A match is an event that passes every filter in the pipeline's leading run of filters, so
--filter A --filter B -C 2and--filter A -l error -C 2both mean "context around events passing both". The context lines that run selects are neighbours, not matches, so a later--filter(one placed behind an--execor--assert) does not re-judge them; kelora warns when a filter sits there, since it can drop matches and leave their context behind.--since/--untilstay outside that run: they define which events exist at all, so context is drawn from inside the time window rather than across its edges.Requires sequential mode;
--parallelis ignored with a warning.
Output Options¶
-F, --output-format <FORMAT>-
Output format.
Formats:
default Colored key-value output json JSON Lines (one object per line) logfmt Key=value pairs on one line inspect Debug view with type information levelmap Compact level timeline keymap First-character map for one selected field tailmap Percentile map for one numeric field csv Comma-separated with header row tsv Tab-separated with header row csvnh CSV without header row tsvnh TSV without header rowSee
--help-formatsfor requirements, extracted fields, and examples.Default:
defaultยท Values:defaultjsonlogfmtinspectlevelmapkeymaptailmapcsvtsvcsvnhtsvnh -J- Shortcut for
-Fjson -c, --core- Output only core fields
-o, --output-file <FILE>- Output file for formatted events
-q, --quiet- Suppress events (formatter output)
--warnings- Show warnings (๐ธ) โ problems that did not stop the run. Overrides a KELORA_NO_WARNINGS / config default and re-enables warnings in data-only modes like
--metrics/--drain/--discover --no-warnings- Suppress warnings (๐ธ). Errors still print; use
--silentto hide those too --hints- Show hints (๐ก) โ advisory suggestions (zero-result/typo/format tips). Overrides a KELORA_NO_HINTS / config default and re-enables hints in data-only modes like
--metrics/--drain/--discover --no-hints- Suppress hints (๐ก, zero-result hints, format/typo tips)
--diagnostics- Show both warnings and hints (shortcut for
--warnings--hints), even in data-only modes. Error summaries always show unless--silent --no-diagnostics- Suppress both warnings and hints (shortcut for
--no-warnings--no-hints), plus per-line verbose errors. Error and parse summaries still print; use--silentto hide those too --silent- Silence pipeline stdout/stderr emitters (events/diagnostics/stats/terminal metrics); script output still allowed. Metrics files still write. Use
--no-silentto override a config default --script-output- Enable Rhai print/eprint output
--legend- Append a legend to map outputs (levelmap/keymap/tailmap) even when piped. By default the legend shows only when stdout is a terminal
--no-legend- Suppress the legend on map outputs (levelmap/keymap/tailmap)
Default Format Options¶
-b, --brief- Output only field values (omit keys)
--expand-nested- Expand nested structures (maps/arrays) with indentation
--wrap- Always word-wrap wide events onto indented continuation lines, even when piped or redirected. By default wrapping is enabled only when stdout is a terminal, so piped output stays one line per event
--no-wrap- Never word-wrap; keep each event on a single line
-z, --show-ts-local- Display timestamps as local RFC3339 (ISO 8601 compatible). Display-only - only affects default formatter output
-Z, --show-ts-utc- Display timestamps as UTC RFC3339 (ISO 8601 compatible). Display-only - only affects default formatter output
Display Options¶
--force-color- Force colored output
--no-color- Disable colored output
--mark-gaps <DURATION>- Insert a centered marker when the time delta between events exceeds the given duration. Example:
--mark-gaps30s prints a divider when consecutive events are separated by >=30s. --force-emoji- Force emoji prefixes (override auto-detection)
--no-emoji- Disable emoji prefixes
Performance Options¶
-P, --parallel- Enable parallel processing (default: sequential processing). Use
--no-parallelto force sequential, overriding a config default --threads <N>-
Number of worker threads (0 = auto-detect, one per available core)
Default:
0 --batch-size <N>- Batch size (events per batch) for parallel processing
--batch-timeout <MS>-
Flush partially full parallel batches after this idle period (milliseconds). Lower values reduce latency; higher values improve throughput.
Default:
200 --unordered- Disable ordered output
Metrics and Stats¶
-s, --stats[=<FORMAT>]-
Show stats only (implies
-q/--quiet).Formats: table, json
Examples:
Use
--no-statsto override a config default. Note the=:--stats=json(a space, as in-s json, is read as a filename).Values:
tablejson --with-stats- Show stats alongside events (rare case)
-m, --metrics[=<FORMAT>]-
Show metrics only (implies
-q/--quiet).Formats: short (first 5), full, tsv, json. Bare
-mauto-selects: the human-readable table on a terminal, tsv when piped or redirected (like ls).tsv emits one tab-separated
metric<TAB>key<TAB>valuerecord per line, sorted by count descending, so | head is top-N and | tail is bottom-N.Examples:
-m Auto (table on a TTY, tsv when piped) --metrics=full Force the table even through a pipe --metrics=tsv Force the record stream even to a TTY --metrics=short Abbreviated (first 5 items) --metrics=json JSON outputUse
--no-metricsto override a config default. Note the=:--metrics=json(a space, as in-m json, is read as a filename).Values:
shortfulljsontsv: Tab-separated record stream (onemetric<TAB>key<TAB>valuerow per line, sorted by count/score descending) for piping to head/tail/sort/awk
--with-metrics- Show metrics alongside events (rare case)
--metrics-file <FILE>- Persist the metrics map (populated by track_*()) to disk as JSON.
--freq <FIELD>-
Frequency table: count occurrences per distinct value of FIELD.
Shorthand for track_freq("FIELD", e.FIELD). Runs after all filters/transforms and implies
-m. Repeatable or comma-separated (--freqlevel,service). Nested fields use dotted paths (e.g. user.id). Results are sorted by count descending, so piping the tsv output to head gives the top-N and tail gives the bottom-N (no--top/--bottomflags needed). Control output with--metrics=short|full|tsv|json or--metrics-file.Takes a field name, not an expression. To tally a derived value, call track_freq directly in a script stage โ it accepts any expression, names the metric itself, and needs no throwaway field:
-m --exec 'track_freq("hour", meta.parsed_ts.round_to("1h"))' # per hour -m --exec 'track_freq("class", e.status / 100)' # per 1xx/2xx/...By itself
--freqtallies the whole run: adding--spandoes NOT window it. For per-window tallies add--span-summary, which puts each window's deltas in a row:Examples:
--describe <FIELD>-
Summarize a numeric FIELD: count, min, max, avg, p50/p95/p99.
Shorthand for track_stats("FIELD", e.FIELD). Runs after all filters/transforms and implies
-m. Repeatable or comma-separated (--describea,b). Non-numeric/missing values are skipped. Control output with--metrics=short|full|tsv|json or--metrics-file.Takes a field name, not an expression. For a derived value, call track_stats directly in a script stage:
Example:
--card <FIELD>-
Estimate the number of distinct values of FIELD (HyperLogLog).
Shorthand for track_cardinality("FIELD", e.FIELD). Runs after all filters/transforms and implies
-m. Repeatable or comma-separated (--carduser_id,trace_id). Missing values are skipped. The count is approximate (~1% error) but uses constant memory, so it scales to high-cardinality fields where track_freq/track_unique would not. Control output with--metrics=short|full|tsv|json or--metrics-file.Takes a field name, not an expression. For a derived value, call track_cardinality directly in a script stage:
Examples:
Template Discovery¶
--drain[=<FORMAT>]-
Summarize log templates using Drain (summary-only; requires
--keyswith exactly one field; sequential mode only).Formats:
table (default) Clean output: count + template full Detailed: adds line ranges + sample + template ID id Stable output: template_id + template (sorted by ID) json JSON with all metadataExamples:
--drain Clean table (count + template) --drain=full With line numbers, samples, and IDs --drain=id Stable ID list for diffs --drain=json JSON output for scriptingValues:
tablefullidjson --drain-diff[=<FORMAT>]-
Compare template frequencies between a baseline and a target log (summary-only; requires
--keyswith exactly one field; sequential mode only).Three ways to define baseline and target:
kelora --drain-diff old.log new.log -k msg First input is baseline, second is target kelora --drain-diff --cut-at 2026-07-24T14:00Z incident.log -k msg One input split at a timestamp kelora --drain-diff --cut-before 'e.msg.contains("deploy")' incident.log -k msg One input split at the first matchDiffs *which message templates occur and how often*, not what the messages say. Output reads like a unified diff:
--- / +++ name the baseline and target, with each side's event count and observed span (in the form --cut-at accepts back) + a template only the target has, with its event count - a template only the baseline had, with its event count * a template both have, at a materially different rate, shown as a plain multiple ("14x more")A * row is reported when the change is bigger than sampling noise for the number of events on each side, and big enough to act on (>= 0.5pp of share, or a >= 1.5x change in rate). Templates that change less are this diff's context lines: tallied in the footer as unchanged, not printed. All comparisons use per-side shares, so sides of very different sizes compare fairly.
Rewording is invisible to it: "timeout after 5s" becoming "timed out after 5s" reads as one - plus one +, never as a modified template. Composes with the pipeline:
--filter/--execrun before diffing.A vacuous comparison is refused rather than reported (exit 1):
- No event carries the field named by -k: the error names the nearest field it did see, instead of printing an all-empty "nothing changed" report. - One side got every event and the other none (usually a splitter that missed): every template would be + or - by construction, so the error names the resolved cut and the span the input covers, or says the predicate never matched, instead.A field present on only some events warns with the excluded and compared counts.
Formats:
table Diff-style rows + footer. The default on a terminal. full The same rows, each followed by indented detail: template id, both counts and shares, and a sample of a real line it matched. tsv One 'change<TAB>template_id<TAB>counts<TAB>percents<TAB>template' record per changed template; no header, no report around it. The default when stdout is piped or redirected (like -m), so --drain-diff=table forces the report through a pipe. json One JSON object (new/gone/freq_changed, per-side totals, the unchanged tally, spans and exclusion counts; each freq_changed entry carries delta_pp and a signed z_score for your own filtering)Examples:
--drain-diff old.log new.log -k msg --drain-diff=json before.log after.log -k msg --drain-diff --cut-at 2026-07-24T14:00Z incident.log -k msg --drain-diff --cut-before 'e.msg.contains("deploy started")' incident.log -k msgValues:
tablefull: The same rows, each followed by indented detail: template id, the counts and shares the compact row leaves out, and a sample linejsontsv: One tab-separated record per changed template, no header and no surrounding report, for piping to awk/sort/duckdb
--cut-at <TIME>-
Timestamp splitting one
--drain-diffinput into baseline (before the cut) and target (at/after).Accepts the same timestamp formats as
--since/--until(e.g., 2026-07-24T14:00:00Z,2026-07-24 14:00,1h,yesterday). See--help-time. Events without a parseable timestamp are excluded from the comparison and counted in a warning.The cut resolves against the clock, not the log:
1hmeans an hour before now, and a bare14:00means today at 14:00. For a historical log, give an absolute timestamp โ a cut that lands outside the data leaves one side empty, which is refused (exit 1) with the span the input actually covers, so a missed first attempt tells you what to use. When you know what the change looks like but not when it happened,--cut-before/--cut-aftersplit on a predicate instead and need no clock.Every report states where the split landed (
baseline spans .. / target spans ..), in the same form--cut-ataccepts back.Example:
--cut-before <EXPR>-
Boolean Rhai expression whose first match splits one
--drain-diffinput, with the cut placed immediately BEFORE the match: the matching event is the first target event.Use this when the matching line is the start of the new regime โ a deploy marker, the first error of an incident. Use
--cut-afterinstead when the match is the end of the old one.Needs no timestamps and no clock: you say what the change looks like, not when it happened. The boundary latches on the first match, so a predicate that keeps matching still splits the log exactly once, and no events are buffered.
Same expression syntax as
--filter(see--help-rhai), and-I/--includehelpers are available. A predicate that never matches leaves the target side empty, and one matching the first event leaves the baseline empty; both are refused (exit 1) rather than reported as change. One matching the last event leaves a one-event target, which prints with a warning (๐ธ) rather than being refused.Examples:
--cut-after <EXPR>-
Boolean Rhai expression whose first match splits one
--drain-diffinput, with the cut placed immediately AFTER the match: the matching event is the last baseline event.Use this when the matching line closes out the old regime โ
deploy finished,migration complete, the last healthy heartbeat. Use--cut-beforewhen the match opens the new one.Otherwise identical to
--cut-before: same expression syntax as--filter(see--help-rhai),-I/--includehelpers available, boundary latches on the first match, nothing buffered. A predicate that never matches, or one matching the last event, leaves the target side empty and is refused (exit 1) rather than reported as change. One matching the first event leaves a one-event baseline, which is well-formed enough to report: it prints, with a warning (๐ธ) that the NEW section reflects that shortfall rather than a change.Examples:
Field Discovery¶
-d, --discover[=<FORMAT>]-
Profile fields: names, inferred types, cardinality estimates, and sample values. Nested maps and arrays are flattened to 3 levels (e.g. user.name, user.roles[]). Implies
-q/--quiet(events suppressed). Sequential mode only.Formats: table (default), json
Examples:
Values:
tablejson -D, --discover-final[=<FORMAT>]-
Profile final emitted fields after scripts and filters. Implies
-q/--quiet(events suppressed). Sequential mode only.Formats: table (default), json
Examples:
-D, --discover-final Table summary of final fields -D=json, --discover-final=json Machine-readable JSON of final fieldsValues:
tablejson --discover-depth <N>-
Maximum depth for flattening nested maps/arrays into dotted keys (default: 3). Depth counts descents from the event root: a.b.c is depth 3. Use a higher value to inspect deeply nested JSON; use 1 to see only top-level fields; use 0 for unlimited depth.
Examples:
Configuration Options¶
--config-file <FILE>- Specify custom configuration file path
--ignore-config- Ignore configuration file
-a, --alias <NAME>- Use alias from configuration file
--save-alias <NAME>- Save current command as alias to configuration file
--show-config- Show configuration file and exit
--edit-config- Edit configuration file in default editor and exit
Help Options¶
--help-rhai- Show Rhai scripting guide and exit
--help-functions [<KEYWORD>]- Show available Rhai functions and exit (optional KEYWORD filters by name/description; smartcase: lowercase matches any case, uppercase is exact)
--help-examples- Show practical Rhai examples and exit
--help-time- Show time format help and exit
--help-multiline- Show multiline strategy help and exit
--help-regex- Show regex format help and exit
--help-formats- Show format reference and exit
--completions <COMPLETIONS>-
Generate shell completion script and exit
Values:
bashzshfishpowershellelvish
Exit Codes¶
0 Success โ the run did its job. By default Kelora is resilient: malformed
lines in an otherwise-valid stream, and best-effort --exec transform
errors, are reported on stderr and counted but do NOT change the exit code
(use --strict to make the first such error fatal instead).
1 Error. Any of:
- a named input file could not be opened
- an --assert condition failed
- a gate stage saw input but never once succeeded (parsing failed on every
line, or a --filter errored on every event)
- a forbidden operation (e.g. mutating `conf` outside --begin)
- with --strict, ANY single parse/filter/exec error (also aborts early)
2 Invalid command-line usage (unknown flag, bad value, conflicting options, or a
malformed config file).
130 Interrupted (SIGINT / Ctrl-C).
134 Internal panic (SIGABRT) โ a bug; please report it.
141 Broken pipe (SIGPIPE).
143 Terminated (SIGTERM).