Features
What you get with agent-tail
Readable, greppable logs
Logs are plain text files written to tmp/logs/latest/ relative to your project root, with a consistent format. Timestamps, levels, source locations, and stack traces are all there — easy for you to scan and easy for an AI to parse.
[10:30:00.123] [LOG ] User clicked button[10:30:00.456] [WARN ] Deprecated API call[10:30:01.789] [ERROR ] Failed to fetch data (http://localhost:5173/src/api.ts:42:10)Error: Network errorat fetchData (http://localhost:5173/src/api.ts:42:10)at handleClick (http://localhost:5173/src/app.ts:15:5)
Levels are padded to 7 characters for alignment. Stack traces are indented. Source URLs are included for errors.
Log filtering
Not every log line is useful — HMR updates, noisy debug output, and framework internals add clutter that wastes AI context. The excludes option lets you filter them out before they hit disk.
The CLI supports it too, with repeatable --exclude flags:
agent-tail run --exclude "[HMR]" --exclude "/^DEBUG/" 'fe: npm run dev'
Plain strings are substring matches. Patterns starting with / are parsed as regex (e.g. /^HMR/i).
Muting services
Different from --exclude which filters log content, --mute silences entire services from your terminal and combined.log. Muted services still run and their output is still captured to individual log files — they just don’t clutter your terminal while you’re debugging something else.
agent-tail run --mute fe --mute worker 'fe: npm run dev' 'api: uv run server' 'worker: uv run worker'
In this example, only api output appears in your terminal. All three services still log to fe.log, api.log, and worker.log — so agents can still read everything.
--exclude filters noisy log lines by content (e.g. HMR messages). --mute hides entire services by name. Use --exclude to clean up what gets written to disk. Use --mute to focus your terminal on one service while debugging.
Multi-server log aggregation
Most projects run more than one process — a frontend, an API, maybe a worker. agent-tail can aggregate all of them into one session directory.
1. Use agent-tail run (recommended)
Run everything from one command. All output goes to the same session automatically.
2. Wrap services independently
Run each service in its own terminal. The wrap command detects the existing session:
# Terminal 1: Start the frontend (creates the session)npm run dev# Terminal 2: Wrap the API server (reuses the session)npx agent-tail wrap api -- uv run fastapi-server# Terminal 3: Tail everythingtail -f tmp/logs/latest/*.log
3. Direct file writes (no CLI needed)
Point your server's logging at the latest symlink. Works with any language:
# Pythonlog_dir = os.path.join(os.getcwd(), "tmp", "logs", "latest")handler = logging.FileHandler(os.path.join(log_dir, "api.log"))# Node.jsconst log_stream = fs.createWriteStream(path.join("tmp/logs/latest", "server.log"),{ flags: "a" })
Searching and tailing logs
Because logs are plain files, every standard Unix tool works out of the box. Here are the most useful patterns:
# Follow all logs in real timetail -f tmp/logs/latest/*.log# Follow a specific servicetail -f tmp/logs/latest/browser.log# Find all errors across every servicegrep -r "ERROR" tmp/logs/latest/# Case-insensitive searchgrep -ri "failed\|timeout\|exception" tmp/logs/latest/# Show context around each matchgrep -r -C 5 "ERROR" tmp/logs/latest/# Only ERROR and WARN linesawk '/\[ERROR|\[WARN/' tmp/logs/latest/browser.log# Count errors per servicegrep -rc "ERROR" tmp/logs/latest/# Use ripgrep for faster searchesrg "ERROR|WARN" tmp/logs/latest/
Captured browser events
The framework plugins capture more than just console.* calls:
- Unhandled errors (
window.onerror) — logged asUNCAUGHT_ERRORwith full stack traces - Unhandled promise rejections — logged as
UNHANDLED_REJECTION
These are the errors that silently break your app in the browser. Disable with captureErrors: false and captureRejections: false.
Session management
Each agent-tail run (or dev server start with a framework plugin) creates a new session — a timestamped directory under tmp/logs/ that holds all log files for that run. A latest symlink always points to the most recent session, so tmp/logs/latest/ is always the right path to give your agent.
- Timestamped directories — e.g.
2024-01-15T10-30-00-123Z/ - Latest symlink — updated on every new session, always points to the newest one
- Auto-pruning — old sessions beyond the limit are removed (default: keep 10)
- Gitignore detection — warns if your log directory isn't in
.gitignore