Skip to content

Logchef CLI

A Rust CLI for querying logs from the terminal. Supports LogchefQL across supported sources, raw native queries (SQL for ClickHouse, LogsQL for VictoriaLogs), syntax highlighting (via tailspin), multi-context management (dev/staging/prod), and OIDC PKCE authentication.

Terminal window
# 1. Build the CLI
cd logchef/cli && cargo build --release
# 2. Add to PATH (or copy to /usr/local/bin)
export PATH="$PATH:$(pwd)/target/release"
# 3. Authenticate (auto-creates context from hostname)
logchef auth --server https://logs.example.com
# 4. Rename context to something friendly
logchef config rename logs.example.com prod
# 5. Set defaults so you don't need --team/--source every time
logchef config set team "my-team"
logchef config set source "nginx-logs"
# 6. Query logs
logchef query 'level="error"' --since 1h

Tip: Discover teams and sources with:

Terminal window
logchef teams
logchef sources --team "production"
logchef schema --team "production" --source "nginx-logs"

Download the latest CLI release for your platform from GitHub Releases.

Platform File
Linux x86_64 logchef-cli_<version>_linux-x86_64-musl.tar.gz
Linux ARM64 logchef-cli_<version>_linux-aarch64-musl.tar.gz
macOS Apple Silicon logchef-cli_<version>_macos-aarch64.tar.gz
macOS Intel logchef-cli_<version>_macos-x86_64.tar.gz
Windows x86_64 logchef-cli_<version>_windows-x86_64.zip

Grab the latest version tag from the CLI releases page (e.g. 0.2.0), set it once, then download:

Terminal window
# Set to the latest version from the releases page above
CLI_VERSION="0.2.0"
# Linux x86_64
curl -LO "https://github.com/mr-karan/logchef/releases/download/cli-v${CLI_VERSION}/logchef-cli_${CLI_VERSION}_linux-x86_64-musl.tar.gz"
tar xzf logchef-cli_${CLI_VERSION}_linux-x86_64-musl.tar.gz
sudo mv logchef /usr/local/bin/
# macOS Apple Silicon
curl -LO "https://github.com/mr-karan/logchef/releases/download/cli-v${CLI_VERSION}/logchef-cli_${CLI_VERSION}_macos-aarch64.tar.gz"
tar xzf logchef-cli_${CLI_VERSION}_macos-aarch64.tar.gz
sudo mv logchef /usr/local/bin/

If you prefer to build from source (requires Rust):

Terminal window
# Clone the repository
git clone https://github.com/mr-karan/logchef.git
cd logchef/cli
# Build the release binary
cargo build --release
# The binary is at cli/target/release/logchef
# Copy to your PATH:
sudo cp target/release/logchef /usr/local/bin/

If you have just installed:

Terminal window
# Build release binary
just build-cli
# Build debug binary (faster compilation for testing)
just build-cli-debug
# Install to ~/.cargo/bin (must be in PATH)
just install-cli
Terminal window
logchef --version
logchef --help

The CLI supports two authentication methods: browser-based OIDC and API tokens.

To use browser-based auth, configure a public OIDC client for the CLI and set it in the server config:

[oidc]
cli_client_id = "logchef-cli"

Your OIDC provider must allow loopback redirects for the CLI: http://127.0.0.1:19876/callback through http://127.0.0.1:19878/callback.

For interactive use, authenticate via your browser:

Terminal window
logchef auth

This opens your browser to complete the OIDC login flow. The token is automatically saved to your config file.

Terminal window
# Check authentication status (hits the server)
logchef auth --status
# Print the active context, server URL, and token source (offline — no API call)
logchef auth current
# Log out (clear stored token)
logchef auth --logout

auth current is the offline counterpart to auth --status and whoami. It tells you which server + token a subsequent command will use, without making a network call:

context: prod
server: https://logs.example.com
token: set (from config, expires 2026-06-03T07:00:00Z)

When the token comes from --token / LOGCHEF_AUTH_TOKEN, the line reports the source but omits an expiry (the CLI doesn’t validate or parse externally-supplied tokens). Useful for CI / bot debugging when an API call fails and you want to verify the credential is actually picked up before troubleshooting further.

For scripts and automation, use an API token directly:

Terminal window
# Set token via environment variable
export LOGCHEF_AUTH_TOKEN="logchef_1_abc123..."
logchef query ""
# Or pass token as argument
logchef --token "logchef_1_abc123..." query ""
# Or save to config file
logchef config set auth.token "logchef_1_abc123..."

Generate API tokens from the Logchef web UI under your profile settings, or see Service Tokens for non-login automation accounts.

The query command allows you to execute LogchefQL queries directly from your terminal.

LogchefQL compiles to the selected source’s native query language:

  • ClickHouse sources compile to SQL
  • VictoriaLogs sources compile to LogsQL
Terminal window
logchef query 'level="error" and service="api"' --since 1h
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, source ID, or ClickHouse database.table_name (from config)
--since -s Time range (e.g., “15m”, “1h”, “24h”) “15m”
--from Absolute start time (ISO 8601)
--to Absolute end time (ISO 8601)
--limit -l Maximum number of results 100
--output Output format (text, json, jsonl, json-flat, table, msg) text
--no-highlight Disable syntax highlighting (auto-disabled when piped) false
--no-timestamp Hide timestamp from text output false
--show-sql, --explain Trace the server-generated backend query on stderr (continues executing) false
--dry-run Print the server-generated backend query to stdout and exit false

When you run logchef query without specifying team, source, or query, and you’re in a terminal, the CLI enters interactive mode:

Terminal window
# Launch interactive mode
logchef query
# Prompts:
# ? Select team: [production, staging, dev]
# ? Select source: [nginx-logs, app-logs, api-logs]
# ? LogChefQL query: level="error"

This is useful for quick exploration without remembering exact team/source names.

Terminal window
# Get all logs from the last 15 minutes
logchef query "" --team "production" --source "nginx-logs"
# Use database.table_name format for ClickHouse sources (copy from UI)
logchef query "" --team "production" --source "logs.app"
# Filter by field value
logchef query 'status=500' --team "production" --source "nginx-logs"
# Multiple conditions (AND)
logchef query 'method="POST" and status=403' --team "production" --source "nginx-logs"
# Search within a time range
logchef query 'level="error"' --since 1h --limit 50
# Print only the message column
logchef query 'level="error"' --output msg --limit 5
# Hoist JSON-shaped msg fields to top-level JSON rows
logchef query 'level="error"' --output json-flat --limit 5
# Hide timestamp from output
logchef query 'level="error"' --no-timestamp
# Output as JSON (returns object with logs, stats, columns)
logchef query 'status=500' --output json | jq '.logs[] | .host'
# Output as JSON Lines (one JSON object per line, great for jq)
logchef query "" --output jsonl | jq '.msg'
# JSON output is jq-friendly - stats are included in the object
logchef query "" --output json | jq '{count: .count, time_ms: .stats.execution_time_ms}'
# Trace the generated backend query on stderr while still running
logchef query 'method="GET"' --show-sql # or: --explain
# Print the generated backend query to stdout and exit (no results returned)
logchef query 'method="GET"' --dry-run
# Use absolute time range
logchef query "" --from "2026-01-14T00:00:00Z" --to "2026-01-14T12:00:00Z"

The sql command lets you execute the selected source’s native query language directly. Use SQL for ClickHouse sources and LogsQL for VictoriaLogs sources. Unlike query, you have full control over the backend query.

Terminal window
logchef sql "SELECT * FROM logs.app WHERE level='error' LIMIT 10"
logchef sql 'level:="error" | fields _time, _msg, service'
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, native target (database.table_name or VictoriaLogs base URL), or ID (from config)
--since -s Apply a relative time range (e.g., “15m”, “1h”, “24h”)
--from Apply an absolute start time (YYYY-MM-DD HH:MM:SS)
--to Apply an absolute end time (YYYY-MM-DD HH:MM:SS)
--timeout Query timeout in seconds 30
--output Output format (text, json, jsonl, json-flat, table, csv, msg) text
--no-highlight Disable syntax highlighting (auto-disabled when piped) false
--no-timestamp Hide timestamp from text output false
--show-sql, --explain Trace the resolved SQL on stderr (continues executing) false
--dry-run Print the resolved SQL to stdout and exit without running it false

Similar to query, the sql command supports interactive mode:

Terminal window
# Launch interactive mode
logchef sql
# Prompts:
# ? Select team: [production, staging, dev]
# ? Select source: [nginx-logs, app-logs, api-logs]
# ? Raw query: SELECT * FROM logs.app LIMIT 10
Terminal window
# ClickHouse SQL with time filter
logchef sql "SELECT * FROM logs.app WHERE _timestamp > now() - INTERVAL 1 HOUR LIMIT 100"
# ClickHouse aggregation query
logchef sql "SELECT level, count() as cnt FROM logs.app WHERE _timestamp > now() - INTERVAL 1 DAY GROUP BY level"
# VictoriaLogs LogsQL query
logchef sql 'level:="error" | fields _time, _msg, service'
# Let the CLI add the source timestamp range
logchef sql "SELECT level, count() AS count FROM logs.app GROUP BY level" --since 1h
# Place the time expressions explicitly
logchef sql "SELECT * FROM logs.app WHERE _timestamp BETWEEN __START__ AND __END__" --since 1h
# Read a native query from stdin (useful for complex queries)
cat query.sql | logchef sql -
# Or use heredoc
logchef sql - <<'EOF'
SELECT
toStartOfHour(_timestamp) as hour,
count() as requests,
countIf(status >= 500) as errors
FROM logs.nginx
WHERE _timestamp > now() - INTERVAL 24 HOUR
GROUP BY hour
ORDER BY hour
EOF
# Output as JSON
logchef sql "SELECT * FROM logs.app LIMIT 5" --output json
# Print only msg, or the first selected column when msg is absent
logchef sql "SELECT msg FROM logs.app LIMIT 5" --output msg
# Trace the resolved SQL on stderr while still running the query
logchef sql "SELECT count() FROM logs.app WHERE level='error'" --since 1h --explain
# Print the resolved SQL and exit (useful for piping to another tool)
logchef sql "SELECT count() FROM logs.app WHERE level='error'" --since 1h --dry-run
# Pipe to jq for processing
logchef sql "SELECT host, count() as cnt FROM logs.app GROUP BY host" --output jsonl | jq -s 'sort_by(.cnt) | reverse'

The explain command translates a LogchefQL filter into the source’s native query language and validates it without running anything. It’s the go-to for “what will this actually run?” and “is this filter valid?” — the translation happens server-side, but no logs are read.

For ClickHouse sources it prints the generated SQL; for VictoriaLogs sources it prints the generated LogsQL.

Terminal window
logchef explain 'level="error" and service="api"' -t production -S app-logs
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, database.table_name, or ID (from config)
--output Output format (text, json, jsonl) text
Terminal window
# See the ClickHouse SQL / LogsQL a filter compiles to
logchef explain 'status>=500'
# Validate a filter's syntax in a script (exit stays 0; check the JSON)
logchef explain 'status>=500' --output json | jq '.valid'

The fields command is for field discovery. With no argument it lists the source’s fields and types; pass a field name to list its observed values (with counts) over a lookback window.

Terminal window
# List every field in a source
logchef fields -t production -S app-logs
# Top observed values for `service` in the last hour
logchef fields service --since 1h
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, database.table_name, or ID (from config)
--since -s Lookback window for value enumeration (e.g. “15m”, “1h”, “24h”) (from config, 15m)
--limit Max number of values to return (when a field is given) 20
--output Output format (text, json, jsonl, table) text
Terminal window
# List fields and types
logchef fields
# Top 50 values for `status`, machine-readable
logchef fields status --limit 50 --output jsonl
# What levels have we seen in the last 24h?
logchef fields level --since 24h

The histogram command buckets log counts over time. In text mode it renders a terminal bar chart; in json/jsonl/table mode it emits the raw buckets for plotting elsewhere. Works against both ClickHouse and VictoriaLogs sources. Pass an optional LogchefQL query to bucket only matching logs, and --group-by to break each bucket into the top series.

Terminal window
logchef histogram 'level="error"' --since 24h -t production -S app-logs
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, database.table_name, or ID (from config)
--since -s Relative lookback window (e.g. “15m”, “1h”, “24h”) (from config, 15m)
--from Absolute start (YYYY-MM-DD HH:MM:SS, effective timezone). Requires --to
--to Absolute end (YYYY-MM-DD HH:MM:SS, effective timezone). Requires --from
--interval Bucket size (e.g. “1m”, “5m”, “1h”). auto sizes it from the range auto
--group-by Field to break each bucket down by (top 10 series)
--output Output format (text, json, jsonl, table) text
--timeout Query timeout in seconds 30
Terminal window
# Error rate over 24h, auto-sized buckets
logchef histogram 'level="error"' --since 24h
# Total volume in 5-minute buckets, broken down by service (top 10)
logchef histogram --since 6h --interval 5m --group-by service
# Machine-readable buckets for plotting elsewhere
logchef histogram 'status>=500' --since 1h --output jsonl

Text output looks like:

span 07-15 00:00:00 → 07-16 00:00:00 · bucket 30m
07-15 00:00:00 │████████▍ 1,204
07-15 00:30:00 │██████████████████████████████ 4,417
07-15 01:00:00 │███████▏ 998
...
48 buckets · 82,341 logs · peak 4,417

The find command searches accessible sources (ClickHouse and VictoriaLogs) for a service, job, host, or message pattern and prints the sources with recent matches.

Terminal window
logchef find payments-api
logchef find payments-api --team production --since 6h
Option Shorthand Description Default
--team -t Restrict discovery to one team All accessible teams
--source -S Restrict discovery to one source All sources
--since -s Lookback window 24h
--column Candidate column to search; repeatable Common service/job/host/message columns
--limit Maximum matching sources to print 10
--timeout Per-source query timeout in seconds 30
--no-samples Skip the per-column sample fetch false
--output Output format (text, json, jsonl) text

For each matched source, find fires a small follow-up query per matching column to surface sample values:

team=8 source=11 (logs.app) matches=1401245 in 30m columns=job_name,msg
↳ job_name: "payments-api" (1400128), "payments-api-uat" (1117)
↳ msg: "payments-api handled request 0a3f9b…" (sample)

Label-shaped columns (service, host, job_name, …) get the top 3 values with counts; free-form text columns (msg, message, body) get a single truncated sample row. Pass --no-samples to suppress and get just the summary line. In JSON / JSONL output, samples are included as a samples: [{column, values: [{value, count?}]}] field.

Sources that fail to inspect (permissions, schema fetch, or query errors) are silently skipped. The text output reports the skip count on stderr; pass the global --debug flag to see per-source diagnostics. If a source consistently times out (e.g. very wide table over a long lookback), raise --timeout or narrow with --since / --column.

The tail command follows matching LogchefQL results live until Ctrl-C or --max-lines is reached. It streams natively over Server-Sent Events (SSE): the server handles the live push for both backends (polling under the hood for ClickHouse, VictoriaLogs’ native tail for VL), so the ClickHouse-vs-VictoriaLogs difference is invisible to you.

Terminal window
logchef tail 'service="payments-api" and msg~"error"' -t production -S app-logs
logchef tail 'level="error"' --output jsonl --max-lines 20

For environments where the streaming endpoint is unavailable (e.g. a proxy that buffers SSE), pass --poll to fall back to the legacy client-side polling loop. Under --poll, the CLI repeatedly queries newest-first on --interval; --since, --interval, and --limit only apply in this mode (the SSE stream is push-based and always follows from now).

Option Shorthand Description Default
--team -t Team name or ID (from env/config)
--source -S Source name, database.table_name, or ID (from env/config)
--poll Use the legacy client-side polling loop instead of the native SSE stream false
--since -s Initial lookback window (--poll only) 30s
--interval Poll interval in seconds (--poll only) 2
--limit Maximum rows fetched per poll (--poll only) 100
--max-lines Stop after printing this many rows
--timeout Query timeout in seconds. Bounds each poll under --poll; acts as an idle read timeout (reconnect) on the SSE stream 30
--output Output format (text, jsonl, msg) text
--no-highlight Disable syntax highlighting (auto-disabled when piped) false
--no-timestamp Hide timestamp from text output false

Under --poll, if a single poll returns at --limit, tail prints a one-shot stderr warning: between polls, more rows may have arrived than fit in one fetch. Raise --limit or shrink --interval to keep up. The native SSE stream doesn’t have this limit.

Highlighting is auto-disabled when stdout is not a TTY, so logchef tail '...' | jq and ... > log.txt produce clean output without --no-highlight. The flag still works as an explicit override.

When running a query, you’ll see highlighted output with colors:

2026-01-14T07:16:06.149Z host=172.100.86.236 method=PATCH status=410 bytes=45112
2026-01-14T07:16:06.049Z host=156.89.90.123 method=PATCH status=200 bytes=42092
2026-01-14T07:16:05.949Z host=217.33.68.177 method=POST status=403 bytes=10709

The highlighting includes:

  • Timestamps in magenta
  • IP addresses in cyan
  • URLs with protocol highlighting
  • Key=value pairs with dimmed keys
  • Numbers in cyan
  • Log levels color-coded (ERROR=red, WARN=yellow, INFO=green, DEBUG=blue)

The open command builds a web explorer URL for the current team/source (and optional query) and opens it in your browser — the reverse of the “copy CLI command” button in the UI. Handy when a terminal investigation is easier to keep digging into visually. Pass --print to print the URL instead of launching a browser.

Terminal window
# Open a filter in the explorer with a relative window
logchef open 'status>=500' -t production -S app-logs --since 1h
# Print the URL instead of opening it
logchef open 'level="error"' --since 15m --print
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, database.table_name, or ID (from config)
--sql Treat the query as a raw native query (ClickHouse SQL / VictoriaLogs LogsQL) false
--since -s Relative time range to preselect (ignored if --from/--to given)
--from Absolute start (YYYY-MM-DD HH:MM:SS, effective timezone). Requires --to
--to Absolute end (YYYY-MM-DD HH:MM:SS, effective timezone). Requires --from
--limit -l Row limit to preselect
--print Print the URL instead of opening a browser false
Terminal window
# Hand off a native query to the explorer
logchef open 'SELECT * FROM logs.app WHERE level=' --sql -t production -S app-logs
# Open an absolute-range investigation
logchef open 'recipient~"user@example.com"' \
--from '2026-06-30 00:00:00' --to '2026-06-30 23:59:59'

The saved-queries command lists and runs saved queries from the Logchef web UI. You can pass a saved-query ID, exact name, or an explorer URL copied from the browser.

Terminal window
# List all saved queries visible to your account
logchef saved-queries
# Run by numeric ID
logchef saved-queries 14
# Run by pasted explorer URL
logchef saved-queries "https://logs.example.com/logs/explore?team=8&source=11&id=14"
Option Shorthand Description Default
--team -t Team name or ID Query’s resolved team
--source -S Source name, database.table_name, or ID Query’s source
--limit -l Override maximum number of results From saved query
--var -V Set variable value (format: name=value)
--show-sql Print the resolved query without running it false
--output Output format (text, json, jsonl, json-flat, table, msg) text
--no-highlight Disable syntax highlighting false
--no-timestamp Hide timestamp from text output false
Terminal window
# List as JSON
logchef saved-queries --output json | jq '.[] | {id, name, source_name}'
# Run by name
logchef saved-queries "Error Dashboard"
# Substitute variables from the saved query envelope
logchef saved-queries 14 --var service=api --var level=error
# Print only message text
logchef saved-queries 14 --output msg
# Dry-run the stored query text
logchef saved-queries 14 --show-sql

The collections command lets you list and run saved collections (saved queries) from the Logchef web UI.

Terminal window
# List all collections for a source
logchef collections --team "production" --source "nginx-logs"
# Run a collection by name
logchef collections "Error Dashboard" --team "production" --source "nginx-logs"
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, database.table_name, or ID (from config)
--since -s Override time range (e.g., “15m”, “1h”, “24h”) (from collection)
--from Override absolute start time (ISO 8601)
--to Override absolute end time (ISO 8601)
--limit -l Override maximum number of results (from collection)
--var Set variable value (format: name=value)
--output Output format (text, json, jsonl, json-flat, table, msg) text
--no-highlight Disable syntax highlighting false
--no-timestamp Hide timestamp from text output false
--show-sql Display the generated SQL query false

When run without arguments, enters interactive mode to select team, source, and collection:

Terminal window
# Launch interactive mode
logchef collections
# Prompts:
# ? Select team: [production, staging, dev]
# ? Select source: [nginx-logs, app-logs, api-logs]
# ? Select collection: [Error Dashboard, Slow Requests, Daily Summary]
Terminal window
# List all collections
logchef collections -t "production" -S "nginx-logs"
# ID NAME TYPE DESCRIPTION
# 1 Error Dashboard logchefql Track 5xx errors
# 2 Slow Requests logchefql Requests > 1s
# Run a collection with default settings
logchef collections "Error Dashboard" -t "production" -S "nginx-logs"
# Override time range
logchef collections "Error Dashboard" -t 1 -S 1 --since 1h
# Set variables defined in the collection
logchef collections "Service Logs" --var service=api --var level=error
# Output as JSON
logchef collections "Error Dashboard" --output json | jq '.count'

List teams available to your account:

Terminal window
logchef teams
Option Description Default
--output Output format (text, json, jsonl, table) text

Show the authenticated user and accessible teams:

Terminal window
logchef whoami
logchef whoami --output json

List sources for a team:

Terminal window
logchef sources --team "production"
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--output Output format (text, json, jsonl, table) text

Show the schema for a source. If the ClickHouse table has column comments, Logchef exposes them as description in JSON output and shows them in the text table.

Terminal window
logchef schema --team "production" --source "nginx-logs"
Option Shorthand Description Default
--team -t Team name (or ID) (from config)
--source -S Source name, database.table_name, or ID (from config)
--output Output format (text, json, jsonl, table) text

The doctor command runs a one-shot health check of your setup, so it’s a good first step when something isn’t working. It checks: the config file, current context, server reachability, CLI auth availability, the token and its expiry, whether the CLI and server versions match, and whether your default team/source actually resolve. Each line is (ok), (warning), or (problem); every warning or problem prints an actionable fix. It exits 0 when there are no problems (warnings are fine) and 1 otherwise.

Terminal window
logchef doctor
Option Description Default
--json Emit the checks as a JSON array of {check, status, detail, hint} false
Terminal window
# Human-readable health report
logchef doctor
# Machine-readable — surface only failures in CI
logchef doctor --json | jq '.[] | select(.status == "fail")'
# Diagnose a specific server without switching contexts
logchef doctor --server https://logs.example.com

The CLI bundles its own usage skill, embedded at build time so its content always matches your installed binary. skills list shows what’s available; skills get core prints the guide. This is the best way to get usage instructions that match your version — point an agent (or yourself) at it instead of guessing at flags.

Terminal window
# List the bundled skills
logchef skills list
# Print the core usage guide (LogchefQL / SQL / LogsQL, workflows)
logchef skills get core
# Include every reference file (full syntax reference)
logchef skills get core --full
# Feed the guide to an agent as JSON
logchef skills get core --json

Generate a shell completion script for bash, zsh, fish, or powershell:

Terminal window
# Bash (add to ~/.bashrc)
logchef completions bash > /etc/bash_completion.d/logchef
# Zsh (place on your $fpath)
logchef completions zsh > ~/.zfunc/_logchef
# Fish
logchef completions fish > ~/.config/fish/completions/logchef.fish

Manage your CLI settings using the config command.

Terminal window
# List all contexts
logchef config list
# Switch to a different context
logchef config use prod
# Show current context configuration
logchef config show
# Set configuration values for current context
logchef config set team 2
logchef config set source 2
logchef config set limit 50
logchef config set since "1h"
# Rename a context
logchef config rename logs.example.com prod
# Delete a context
logchef config delete old-server

The CLI supports managing multiple Logchef instances (dev/staging/prod):

Terminal window
# Authenticate with prod (context auto-created from hostname)
logchef auth --server https://logs.company.com
logchef config rename logs.company.com prod
# Authenticate with dev
logchef auth --server http://localhost:8125
logchef config rename localhost dev
# List contexts
logchef config list
# CONTEXT SERVER AUTH
# * prod https://logs.company.com yes
# dev http://localhost:8125 yes
# Switch contexts
logchef config use dev
logchef query 'level="debug"'
# One-off query to different context
logchef --context prod query 'level="error"'

After authenticating, set your defaults to avoid typing --team and --source every time:

Terminal window
# Set defaults using team and source names
logchef config set team "my-team"
logchef config set source "nginx-logs"
# Now you can just run:
logchef query 'level="error"'

The configuration is stored at ~/.config/logchef/logchef.json:

{
"current_context": "prod",
"contexts": {
"prod": {
"server_url": "https://logs.example.com",
"timeout_secs": 30,
"token": "logchef_1_...",
"token_expires_at": "2026-02-14T00:00:00Z",
"defaults": {
"team": "production",
"source": "nginx-logs",
"limit": 100,
"since": "15m"
}
},
"dev": {
"server_url": "http://localhost:8125",
"timeout_secs": 30,
"token": "logchef_1_...",
"defaults": {}
}
},
"highlights": {
"custom_keywords": ["MYAPP", "CRITICAL"],
"disable_builtin": false,
"disabled_groups": [],
"custom_regexes": [
{
"pattern": "trace_id=[a-f0-9]+",
"color": "cyan",
"bold": false,
"italic": false
}
]
}
}
Section Key Description
current_context Active context Name of the context to use by default
contexts.<name>.server_url Server URL Logchef server address for this context
contexts.<name>.timeout_secs Timeout HTTP request timeout in seconds
contexts.<name>.defaults.team Default team Team name (or ID) to use when --team is omitted
contexts.<name>.defaults.source Default source Source name (or ID) to use when --source is omitted
contexts.<name>.defaults.limit Default limit Number of results when --limit is omitted
contexts.<name>.defaults.since Default time range Time range when --since is omitted
highlights.custom_keywords Custom keywords Words to highlight in magenta
highlights.disable_builtin Disable defaults Turn off built-in log level highlighting
highlights.disabled_groups Disabled groups List of highlighter groups to disable
highlights.custom_regexes Custom patterns Regex patterns with custom colors

Logchef CLI provides automatic syntax highlighting for common log patterns, powered by tailspin.

Category What’s Highlighted Colors
Log Levels ERROR, FATAL, CRITICAL Red (bold)
WARN, WARNING Yellow
INFO Green
DEBUG, TRACE Blue
HTTP Methods GET Green (bold)
POST Yellow (bold)
PUT, PATCH Magenta (bold)
DELETE Red (bold)
Identifiers IPs, UUIDs, URLs Cyan/Blue
Temporal Dates, timestamps Magenta
Data Numbers, key=value pairs Cyan
Booleans true, false, null Cyan

Highlight specific words on-the-fly without changing your config:

Terminal window
# Highlight words in specific colors
logchef query "" --highlight red:ERROR,FAIL --highlight green:SUCCESS,OK
# Available colors: red, green, yellow, blue, magenta, cyan, white, black
# Also: bright_red, bright_green, bright_yellow, etc.

Turn off specific highlighting groups for cleaner output:

Terminal window
# Disable date/time and number highlighting
logchef query "" --disable-highlight dates --disable-highlight numbers
# Available groups: dates, numbers, uuids, ips, urls, paths,
# pointers, keyvalue, quotes, json, keywords

Add custom regex patterns in your config file:

{
"highlights": {
"custom_regexes": [
{
"pattern": "user_id=(\\d+)",
"color": "cyan",
"bold": true
},
{
"pattern": "request_id=[a-f0-9-]+",
"color": "magenta"
}
]
}
}

The CLI auto-disables ANSI highlighting when stdout is not a TTY, so piping or redirecting just works:

Terminal window
logchef query "" > logs.txt
logchef tail '...' --output jsonl | jq -r .msg

Use --no-highlight to opt out explicitly even on an interactive terminal:

Terminal window
logchef query "" --no-highlight | grep "ERROR"

Returns a single JSON object containing logs, stats, and metadata:

{
"logs": [
{ "_timestamp": "2026-01-20T10:30:00Z", "level": "error", "msg": "..." },
{ "_timestamp": "2026-01-20T10:29:59Z", "level": "info", "msg": "..." }
],
"count": 2,
"stats": {
"execution_time_ms": 45,
"rows_read": 2,
"bytes_read": 1024
},
"query_id": "abc123-...",
"generated_sql": "SELECT * FROM ...",
"columns": [
{ "name": "_timestamp", "type": "DateTime64(3)" },
{ "name": "level", "type": "String" }
]
}

Each log entry is output as a separate JSON object on its own line:

{"_timestamp":"2026-01-20T10:30:00Z","level":"error","msg":"Connection failed"}
{"_timestamp":"2026-01-20T10:29:59Z","level":"info","msg":"Request completed"}

The CLI automatically detects if output is going to a terminal (TTY) or being piped:

  • Terminal: Shows stats summary (3 logs | 45ms | 3 rows read)
  • Piped: Suppresses stats for clean output to grep, jq, etc.
Terminal window
# Stats shown (terminal)
logchef query ""
# Output: [logs...]
# 3 logs | 45ms | 3 rows read
# Stats suppressed (piped)
logchef query "" | grep "error"
# Output: [matching lines only, no stats]

The following options can be used with any command:

Option Environment Variable Description
--context / -c LOGCHEF_CONTEXT Use a specific context
--server LOGCHEF_SERVER_URL Override server URL (ephemeral)
--token LOGCHEF_AUTH_TOKEN Override API token
LOGCHEF_DEFAULT_TEAM Default team when --team is omitted
LOGCHEF_DEFAULT_SOURCE Default source when --source is omitted
--quiet / -q Suppress stats, highlighting, and spinners (data still goes to stdout)
--debug / -d Enable detailed debug output

--quiet is the flag to reach for in scripts and agents: it strips the stderr stats line, ANSI highlighting, and progress spinners, leaving just the data on stdout. Pair it with --output jsonl for clean, parseable output:

Terminal window
logchef query 'level="error"' --quiet --output jsonl | jq .msg

For CI/CD pipelines and automation, you can configure the CLI entirely via environment variables:

Terminal window
# Option 1: Use a saved context
export LOGCHEF_CONTEXT="prod"
logchef query 'level="error"' --team "production" --source "app-logs"
# Option 2: Ephemeral mode (no saved context needed)
export LOGCHEF_SERVER_URL="https://logs.example.com"
export LOGCHEF_AUTH_TOKEN="logchef_1_abc123..."
logchef query 'level="error"' --team "production" --source "app-logs"
# Optional defaults for stateless automation
export LOGCHEF_DEFAULT_TEAM="production"
export LOGCHEF_DEFAULT_SOURCE="app-logs"
logchef query 'level="error"'
Terminal window
logchef query 'status=500' --output jsonl > errors.jsonl
Terminal window
logchef query 'level="error"' --output json | jq '.count'
Terminal window
# Get all unique hosts from JSON output
logchef query 'status=500' --output json | jq -r '.logs[].host' | sort -u
# Get all unique hosts from JSONL output
logchef query 'status=500' --output jsonl | jq -r '.host' | sort -u
# Pretty print messages
logchef query 'level="error"' --output jsonl | jq '.msg'
# Get query stats
logchef query "" --output json | jq '.stats'
Terminal window
logchef query "" --no-highlight | grep -i "database"
Terminal window
logchef query 'level="error"' --no-timestamp --no-highlight > errors.txt
Terminal window
for source in "nginx-logs" "app-logs" "api-logs"; do
echo "=== Source: $source ==="
logchef query 'level="error"' --source "$source" --limit 5
done