> ## Documentation Index
> Fetch the complete documentation index at: https://docker-agent-tail.michaelscotello.com/llms.txt
> Use this file to discover all available pages before exploring further.

# lnav Integration

> View docker-agent-tail logs with lnav — a terminal-based log viewer with SQL queries, regex filtering, and color-coded levels.

## 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 lnav                                    | With 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 correlation                    | Timeline histogram view (press `t`)                       |
| No aggregation                                  | `;SELECT container, count(*) FROM log GROUP BY container` |

## Setup

### Install lnav

<Tabs>
  <Tab title="macOS">
    ```bash theme={null}
    brew install lnav
    ```
  </Tab>

  <Tab title="Linux">
    ```bash theme={null}
    # Debian/Ubuntu
    sudo apt install lnav

    # Or download from https://lnav.org/downloads
    ```
  </Tab>
</Tabs>

### 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:

```bash theme={null}
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:

```bash theme={null}
# 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:

```bash theme={null}
# 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:

```sql theme={null}
;SELECT container, count(*) as cnt FROM log GROUP BY container ORDER BY cnt DESC
```

```sql theme={null}
;SELECT container, level, count(*) FROM log GROUP BY container, level
```

```sql theme={null}
;SELECT * FROM log WHERE level = 'error' ORDER BY log_time DESC LIMIT 20
```

### Regex search

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:

```bash theme={null}
# 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
```

<Tip>
  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.
</Tip>

### Multiple commands

Chain multiple `-c` flags to build pipelines:

```bash theme={null}
# 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 format                             | Normalized level |
| ----------------------------------------- | ---------------- |
| `I`, `info`, `notice`                     | `info`           |
| `W`, `warn`, `warning`                    | `warning`        |
| `E`, `err`, `error`                       | `error`          |
| `F`, `fatal`, `critical`, `crit`, `emerg` | `fatal`          |
| `D`, `debug`                              | `debug`          |
| `T`, `trace`                              | `trace`          |

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

* [lnav documentation](https://docs.lnav.org)
* [lnav hotkeys reference](https://docs.lnav.org/en/latest/hotkeys.html)
* [CLI Reference](/cli-reference) for all docker-agent-tail options
