Skip to Content
CLI

CLI

Logdesk ships with a command-line interface that lets you query logs from a running Logdesk instance. All output is line-delimited JSON (NDJSON), which makes it straightforward to pipe into jq, shell scripts, or AI agents like Claude Code.

Requirements

The Logdesk app must be running. The CLI communicates with it over a Unix socket at ~/.logdesk/cli.sock. If the app is not open, commands will fail immediately.

The CLI binary is the same executable as the app — run it with a subcommand to enter CLI mode instead of opening the GUI.

Commands

CommandDescription
logdesk sourcesList all open log sources
logdesk tailStream the last N lines from a source
logdesk querySearch logs and stream matching entries
logdesk histogramShow time distribution of log levels

logdesk sources

List all log sources currently open in the app.

logdesk sources

Output is a single JSON object with a sources array:

{"sources":[{"id":"550e8400-e29b-41d4-a716-446655440000","name":"api.log","source_type":"file","status":"active","entry_count":42381}]}
FieldDescription
idUUID identifying the source — used by tail and query
nameHuman-readable label (usually the filename)
source_typeOne of file, stdin, pipe, command, docker
statusactive while the source is being read, stopped otherwise
entry_countNumber of entries indexed so far

logdesk tail

Stream the last N log lines from a source as NDJSON.

logdesk tail --source <ID> [--last <N>]
FlagRequiredDefaultDescription
--sourceYesSource UUID from logdesk sources
--lastNo100Number of lines to return

Each line in the output is a log entry, followed by a done message:

{"type":"entry","seq":1,"timestamp_ms":1718000000000,"level":"error","message":"connection refused","source_id":"550e8400-..."} {"type":"done","total_matches":100,"lines_scanned":100}

logdesk query

Search logs using text or a field query and stream matching entries. Uses the same Query Language as the app.

logdesk query <QUERY> [--context <N>] [--limit <N>] [--offset <N>]
ArgumentRequiredDefaultDescription
queryYesPlain text or field query (e.g. level=error, "connection refused")
--contextNo0Lines of context to include before and after each match
--limitNounlimitedMaximum number of results
--offsetNo0Skip the first N results (for pagination)

Output contains entry lines for each match. When --context is set, each match is followed by a context object:

{"type":"entry","seq":41,"timestamp_ms":1718000001234,"level":"error","message":"auth token expired","source_id":"550e8400-..."} {"type":"context","match_seq":41,"before":[...],"after":[...]} {"type":"done","total_matches":3,"lines_scanned":42381}

The done line is always the last line and includes total match count and lines scanned.


logdesk histogram

Show the time distribution of log levels across all open sources.

logdesk histogram [--buckets <N>]
FlagRequiredDefaultDescription
--bucketsNo50Number of time buckets to divide the range into

Output is a single histogram object followed by done:

{"type":"histogram","buckets":[{"start_ms":1718000000000,"end_ms":1718000060000,"level":"error","count":4},{"start_ms":1718000000000,"end_ms":1718000060000,"level":"info","count":112},...]} {"type":"done","total_matches":0,"lines_scanned":0}

Each bucket covers one time segment and one log level. Multiple buckets can share the same time range — one per level.


Output format

All responses are line-delimited JSON (NDJSON). Each line is a self-contained JSON object with a type field:

TypeKey fieldsWhen it appears
sourcessources[]Response to sources command
entryseq, timestamp_ms, level, message, source_idEach matching log line
contextmatch_seq, before[], after[]After each entry when --context > 0
histogrambuckets[]Response to histogram command
donetotal_matches, lines_scannedLast line of every response
errormessageWhen something goes wrong

Examples

List sources and tail the first one:

SOURCE=$(logdesk sources | jq -r '.sources[0].id') logdesk tail --source "$SOURCE" --last 50

Find errors with surrounding context, extract messages:

logdesk query "level=error" --context 2 --limit 20 | jq -r 'select(.type == "entry") | .message'

Paginate through results in batches of 25:

logdesk query "timeout" --limit 25 --offset 0 logdesk query "timeout" --limit 25 --offset 25 logdesk query "timeout" --limit 25 --offset 50
Last updated on