Skip to content

Explore a Log File

The first few minutes with a log you've never seen: what's in it, what it looks like, and what stands out. Every command on this page works on any file Kelora can parse; the examples use a gzipped web server log from the examples/ directory.

What fields are there?

--discover (-d) profiles every field: how often it appears, its type, how many distinct values it has, and a few samples.

kelora examples/web_access_large.log.gz -d
Field       Type    Seen  Miss   Uniq  Examples
ip          string  1200    0%  ~1200  "71.193.113.161", "224.86.239.106", "79.…
ts          string  1200    0%  ~1168  "04/Oct/2025:11:39:49 +0200", "04/Oct/20…
request     string  1200    0%  ~1200  "GET /reintermediate/e-commerce/cross-pl…
method      string  1200    0%      6  "GET", "PUT", "POST", "PATCH", "HEAD", "…
path        string  1200    0%  ~1050  "/strategic/24%2f365/ubiquitous/paradigm…
protocol    string  1200    0%      3  "HTTP/1.0", "HTTP/1.1", "HTTP/2.0"
status      int     1200    0%     21  205, 500, 405, 302, 203, 406, 100, 200, …
bytes       int     1200    0%  ~1175  4257, 84118, 17269, 48124, 58636, 30376,…
referer     string  1200    0%  ~1200  "http://www.regionalseize.io/synergize/r…
user_agent  string  1200    0%  ~1200  "Opera/10.21 (Macintosh; PPC Mac OS X 10…
user        string   580   52%   ~564  "kreiger1178", "gerhold6800", "kihn8808"…

1200 events scanned · format: combined (auto-detected) · timestamp: ts → meta.parsed_ts

Kelora decompressed the file, recognized the Apache/Nginx combined format, and found the timestamp in ts. The field names in the first column are what you use in every later command. If you see a single line field instead, the format wasn't recognized — see Get Logs into Shape.

A ~ in Uniq marks an estimate (within about 1%), which keeps memory low on large files.

How much, and over what period?

--stats (-s) summarizes the run: event counts, parse errors, time span, levels, and keys.

kelora examples/web_access_large.log.gz -s
Detected format: combined
Lines processed: 1200 total, 0 filtered (0.0%), 0 errors (0.0%)
Events created: 1200 total, 1200 output, 0 filtered (0.0%)
Throughput: 91566 lines/s in 13ms
Timestamp: ts (auto-detected) - 1200/1200 parsed (100.0%) — access via meta.parsed_ts.
Time span: 2025-10-04T08:00:00+00:00 to 2025-10-04T10:00:41+00:00 (2h)
Keys seen: bytes,ip,method,path,protocol,referer,request,status,ts,user,user_agent

Read some events

-n (--take) stops after N events. -k (--keys) picks fields, in the order you give:

kelora examples/web_access_large.log.gz -k ts,status,method,path -n 3
ts='04/Oct/2025:10:00:00 +0200' status=403 method='GET'
  path='/reintermediate/e-commerce/cross-platform'
ts='04/Oct/2025:10:00:12 +0200' status=500 method='PUT'
  path='/infrastructures/customized/portals/enhance'
ts='04/Oct/2025:10:00:13 +0200' status=301 method='PUT'
  path='/enterprise/iterate/integrate/exploit'

The default output is key='value' with the timestamp, level, and message first. In a terminal, long events wrap onto indented lines; piped output keeps one event per line. For JSON or CSV, see Export the results.

Choose what each event shows:

Option Shows
-k a,b,c only these fields, in this order
-K a,b everything except these fields
-c only the core fields: timestamp, level, message
-b values without field names

What's common, what's rare?

--freq FIELD counts events per value, most frequent first:

kelora examples/web_access_large.log.gz --freq method
method       (6 values):
  value   count
  HEAD      220
  GET       205
  PATCH     202
  PUT       195
  DELETE    189
  POST      189

--describe FIELD summarizes a numeric field (min, max, average, percentiles):

kelora examples/web_access_large.log.gz --describe bytes
bytes_avg    = 49164.7
bytes_count  = 1200
bytes_max    = 99902
bytes_min    = 41
bytes_p50    = 48295.3
bytes_p95    = 94002.5
bytes_p99    = 98343.3
bytes_sum    = 58997670

For a field with thousands of distinct values, --freq output is long; pipe it to head for the top values (piped output switches to one tab-separated row per value). Summarize has more ways to count.

Which messages repeat?

Free-text messages rarely repeat exactly — IDs, hostnames, and durations differ. --drain groups messages into templates and replaces the parts that vary with placeholders:

kelora examples/app_monitoring.jsonl --drain -k message
templates (13 items):
  6: Connection timeout to database host <fqdn>:<num>
  6: Failed login attempt for user <*> from <ipv4>
  5: Cache hit for key <*>
  4: Cache miss for key <*>
  4: Failed to upload file <*> to S3 bucket prod-documents: timeout after <duration>
  4: GET <path> completed in <duration> with status <num>
  4: Rate limit exceeded for API key <*> on endpoint <path>
  2: POST <path> completed in <duration> with status <num>
  2: Payment gateway returned error code <num>: Service Unavailable
  1: DELETE <path> completed in <duration> with status <num>
  1: PUT <path> completed in <duration> with status <num>
  1: Payment gateway returned error code <num>: Too Many Requests
  1: Payment gateway returned error code <num>: Unauthorized

How does it change over time?

-F levelmap prints one character per event, so bursts of errors stand out:

kelora examples/levelmap-demo.jsonl -F levelmap
2024-10-25T08:00:00.000Z IIDIDIDIDIDIWIDIDIIWDIDEWIDIWEWIDIDWIDIEWIDIWWEIDWIDIDI
2024-10-25T08:03:15.000Z DDWIDIDIIDWEIDWIDIDIDIDIIWDIEWIDIDIDIDIDIDIWDWIDIDIDWDD
2024-10-25T08:07:25.000Z DDDEWDDDDDIDIIDIDIDIDIDIDWDIDIIDICEWIDIIDIDIDWIDIDIWIDI
2024-10-25T08:11:31.000Z DIDIDIDIDIWECEWIDII

🔹 C = CRITICAL | D = DEBUG | E = ERROR | I = INFO | W = WARN

-F keymap -k FIELD does the same for any field (the first character of each value); -F tailmap -k FIELD marks slow outliers in a numeric field.

Narrow it down

kelora examples/web_access_large.log.gz --filter 'e.status >= 500' -k ts,status,path -n 3
ts='04/Oct/2025:10:00:12 +0200' status=500
  path='/infrastructures/customized/portals/enhance'
ts='04/Oct/2025:10:00:29 +0200' status=500
  path='/front-end/transition/partnerships/b2b'
ts='04/Oct/2025:10:00:46 +0200' status=500
  path='/clicks-and-mortar/synergistic/benchmark'

--filter keeps events for which a Rhai expression is true; e is the current event. Level filters (-l error,warn) and time ranges (--since, --until) need no expressions. Filter covers them all.

Export the results

kelora examples/web_access_large.log.gz --filter 'e.status >= 500' -k ts,status,path -n 3 -F csv
ts,status,path
04/Oct/2025:10:00:12 +0200,500,/infrastructures/customized/portals/enhance
04/Oct/2025:10:00:29 +0200,500,/front-end/transition/partnerships/b2b
04/Oct/2025:10:00:46 +0200,500,/clicks-and-mortar/synergistic/benchmark

-J (or -F json) writes JSON Lines, -F csv/-F tsv writes tables with a header, and -o FILE writes to a file. See Output and Integration.

Getting help in the terminal

Command Shows
kelora -h one-screen cheat sheet
kelora --help every option, grouped
kelora --help KEYWORD options matching a keyword, e.g. kelora --help time
kelora --help-functions KEYWORD built-in functions matching a keyword
kelora --help-formats, --help-time, --help-rhai topic references

Run kelora with no arguments to open an interactive prompt with history and proper quoting — handy on Windows, where nested quotes are painful.