Skip to content

Add logs command to show and follow bridge log files#209

Open
jancurn wants to merge 3 commits intomainfrom
claude/design-logs-command-6C7CW
Open

Add logs command to show and follow bridge log files#209
jancurn wants to merge 3 commits intomainfrom
claude/design-logs-command-6C7CW

Conversation

@jancurn
Copy link
Copy Markdown
Member

@jancurn jancurn commented Apr 28, 2026

Summary

Fixes #205

Adds a new mcpc @<session> logs command that allows users to view and follow bridge log files for MCP sessions. The implementation includes a log reader library with support for log file rotation, timestamp filtering, and live tailing.

Key Changes

  • New log reader library (src/lib/log-reader.ts):

    • parseLogLine(): Parses structured log records from raw lines with ISO timestamps, log levels, and optional context tags
    • listLogFiles(): Discovers and orders rotated log files (.log.5.log.1.log)
    • readRecentLogLines(): Reads recent logs with support for --tail (limit lines) and --since (timestamp filtering)
    • followLog(): Live-follows the current log file with rotation detection and belt-and-suspenders polling for filesystem reliability
    • parseDuration() and resolveSince(): Parse duration shorthand (30s, 5m, 2h, 1d, 1w) and ISO timestamps for the --since option
  • New logs command (src/cli/commands/logs.ts):

    • Implements mcpc @<session> logs with options:
      • -n/--tail <n>: Show last N lines (default: 100)
      • --follow: Stream new lines as they arrive (Ctrl+C to stop)
      • --since <value>: Filter by duration or ISO timestamp
    • Supports both human-readable and JSON output modes
    • JSON mode uses NDJSON (one record per line) when streaming with --follow
    • Displays informative headers with file count, size, and filtering details
  • Integration:

    • Wired into CLI parser and shell command executor
    • Updated help text and README with usage examples
    • Added unit tests covering parsing, duration resolution, file listing, and filtering

Notable Implementation Details

  • Log file rotation is detected by inode changes or size shrinkage, with automatic reset to the start of the new file
  • Unparseable lines (banners, stack traces) are preserved when filtering by --since
  • The followLog() function uses both fs.watch() and a 1-second polling interval for robustness across different filesystems (NFS, network mounts)
  • Backlog is read from disk before following begins, allowing callers to control history depth
  • Signal handlers (SIGINT/SIGTERM) gracefully drain pending data before exit

https://claude.ai/code/session_01C8o7VrBnDQfQ3QywPe5tMm

claude added 3 commits April 28, 2026 22:40
Wraps the bridge log file (~/.mcpc/logs/bridge-<session>.log) so users
no longer need to know the raw path or hand-tail it. Defaults to last
100 lines; supports -n/--tail, --follow, --since (duration shorthand
or ISO timestamp), and --json. Transparently spans rotated files
(.log.1 … .log.5) when more lines are needed. With --json, lines are
parsed into structured records; with --follow + --json, output is
NDJSON. Adds _mcpc.logPath and _mcpc.logSize to `mcpc @<session>
--json` output, and replaces "For details, check logs at <path>"
hints with the more actionable "For details, run: mcpc @<session>
logs".
CI fix:
  unauthorized-persist.test.sh asserted the old "check logs at <path>"
  hint, which the previous commit replaced with "run: mcpc <session>
  logs". Updated the assertions to match the new hint.

New test coverage:
  - test/e2e/suites/sessions/logs.test.sh: 14 end-to-end cases driving
    the actual CLI (errors, --json shape, -n/--tail, --since with
    duration + ISO, rotation spanning across .log.1/.log.2,
    chronological ordering, --since across rotations, _mcpc.logPath /
    _mcpc.logSize on session JSON, and the new "mcpc <session> logs"
    error hint).
  - test/unit/cli/logs.test.ts: 10 unit tests for the showLogs handler
    covering @-target validation, missing-session error, invalid
    --since, human stderr/stdout split, "no logs yet" header, JSON
    structured/raw shape, --tail, --since, rotation file count, and
    default tail of 100.
  - test/unit/lib/log-reader.test.ts expanded from 14 → 28 cases:
    parseLogLine edges (empty body, stack frames, every level),
    parseDuration (long forms, case/whitespace, garbage), getBridge-
    LogPath, listLogFiles edge cases (missing dir, non-numeric
    suffixes, prefix-collision sessions), readRecentLogLines edges
    (no trailing newline, blank lines, multi-rotation tail, tail = 0,
    --since drops everything, --since across rotations, tail + since
    combined), and 8 followLog cases (append detection, no backlog
    replay, partial-line buffering, rotation re-open, startAtBeginning,
    file-doesn't-exist-yet, stop() flushes partial trailing line,
    idempotent stop()).

To make followLog deterministically testable I added a FollowOptions
parameter (pollIntervalMs, startAtBeginning) — the production caller
keeps the 1s default.

627 unit tests pass (up from 591).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add mcpc @session logs command

3 participants