Skip to main content

Why lnav?

Reading raw JSONL files with grep and jq works, but you lose context. lnav gives you a real-time, interactive view of your logs — color-coded levels, instant filtering, SQL queries, and a timeline view — all in your terminal. docker-agent-tail includes a built-in lnav format definition that’s auto-installed on first run. No configuration, no schema files to manage.
Without lnavWith lnav
grep error combined.jsonl:filter-in error with color-coded context
jq 'select(.container=="api")' combined.jsonl:filter-in api with live updates
Manual timestamp correlationTimeline histogram view (press t)
No aggregation;SELECT container, count(*) FROM log GROUP BY container

Setup

Install lnav

brew install lnav

Install the docker-agent-tail format

The lnav format is auto-installed the first time you run docker-agent-tail. No manual setup needed. To manually install or reinstall:
docker-agent-tail lnav-install
This installs a format definition that teaches lnav how to parse the JSONL fields (ts, container, stream, level, message).

Usage

The easiest way to view logs is with the lnav subcommand:
# Open latest session in lnav
docker-agent-tail lnav

# Open a specific session
docker-agent-tail lnav --session 2026-03-04-143700
You can also call lnav directly:
# View the latest combined log
lnav logs/latest/combined.jsonl

# View all per-container logs from the latest session
lnav logs/latest/*.jsonl

# View logs from a specific session
lnav logs/2026-03-04-103001/combined.jsonl

Key Features

Filter by log level

Use lnav’s built-in level filtering to focus on errors or warnings:
:set-min-log-level warning
Or filter to show only specific levels:
:filter-in error

Filter by container

Show logs from a specific container:
:filter-in api

SQL queries

lnav supports SQL queries against your log data:
;SELECT container, count(*) as cnt FROM log GROUP BY container ORDER BY cnt DESC
;SELECT container, level, count(*) FROM log GROUP BY container, level
;SELECT * FROM log WHERE level = 'error' ORDER BY log_time DESC LIMIT 20
Search across all logs with regex:
/timeout|connection refused
/status.*5\d{2}

Timeline view

Press t to switch to the timeline/histogram view, which shows log density over time — useful for spotting bursts of errors.

Non-interactive mode (for scripts and AI agents)

lnav’s interactive TUI doesn’t work in non-interactive shells (CI, scripts, AI agents). Use -n (non-interactive) with -c to run commands and get output to stdout:
# Count log lines per container
lnav -n -c ';SELECT container, count(*) AS cnt FROM log GROUP BY container ORDER BY cnt DESC' logs/latest/combined.jsonl

# Find all errors
lnav -n -c ';SELECT log_time, container, log_body FROM log WHERE level = "error"' logs/latest/combined.jsonl

# Errors in the last 5 minutes
lnav -n -c ';SELECT log_time, container, log_body FROM log WHERE level = "error" AND log_time > datetime("now", "-5 minutes")' logs/latest/combined.jsonl

# Log volume by container and level
lnav -n -c ';SELECT container, level, count(*) FROM log GROUP BY container, level' logs/latest/combined.jsonl

# Filter to a single container and write to stdout
lnav -n -c ':filter-in api' -c ':write-to -' logs/latest/combined.jsonl
AI coding agents (Claude Code, Cursor, etc.) should use lnav -n -c instead of the interactive TUI. This gives them full SQL access to structured log data without needing a terminal.

Multiple commands

Chain multiple -c flags to build pipelines:
# Filter to errors, then write to stdout
lnav -n -c ':filter-in error' -c ':write-to -' logs/latest/combined.jsonl

# Set minimum level, then query
lnav -n -c ':set-min-log-level warning' -c ';SELECT container, count(*) FROM log GROUP BY container' logs/latest/combined.jsonl

Level Normalization

docker-agent-tail normalizes log levels from various formats into canonical values that lnav understands:
Source formatNormalized level
I, info, noticeinfo
W, warn, warningwarning
E, err, errorerror
F, fatal, critical, crit, emergfatal
D, debugdebug
T, tracetrace
This means logs from MongoDB (s:"I"), Node.js (level:"info"), Python (levelname:"WARNING"), and other frameworks all get consistent color-coded levels in lnav.

Learn More