close
Skip to content
dubeyKartikayPublic

About

A fast, interactive terminal JSON log viewer (tail -f replacement) built with Go and Bubble Tea.

Topics

Resources

Stars

13 stars

Watchers

0 watching

Forks

Repository files navigation

Peacock logo

Peacock

A charming, high-throughput tail -f replacement for JSON logs

Go version Latest release License Go Report Card Built with Bubble Tea

Pipe your JSON log output into peacock and get colorized, readable, interactively filterable log streams in the terminal.

tail vs peacock demo

go run . | peacock
kubectl logs -f my-pod | peacock
peacock -f app.log

Why Peacock?

  • Zero-config JSON formatting — Automatically highlights levels (ERROR, WARN, INFO, DEBUG), timestamps, callers, and key=value context while passing non-JSON lines through untouched.
  • Scroll up to auto-pause — Use your mouse wheel, Up, or PageUp to inspect log history while new entries continue buffering in the background. Press Space to resume live tailing.
  • Live stacked filtering — Press / to filter logs on the fly, stack multiple filters to drill into noisy streams, and hit Backspace to pop the last filter.
  • Built for fast streams — Decoupled 30fps batched rendering ingests 70,000+ JSON lines/sec in a real terminal without freezing your UI.

Installation

Homebrew (macOS & Linux):

brew install dubeyKartikay/peacock/peacock
Troubleshooting Homebrew tap trust

If Homebrew reports an untrusted tap, trust the formula and retry:

brew tap dubeyKartikay/peacock
brew trust --formula dubeykartikay/peacock/peacock
brew install peacock

One-liner (macOS & Linux) — installs the latest release to ~/.local/bin:

curl -fsSL https://raw.githubusercontent.com/dubeyKartikay/peacock/main/install.sh | bash

With Go:

go install github.com/dubeyKartikay/peacock/cmd/peacock@latest
Manual binary install (Linux, macOS, Windows)

Pre-built binaries are available on the releases page.

# Extract the archive (replace filename with your platform's download)
tar -xzf peacock_Linux_x86_64.tar.gz

# Copy the binary to a directory on your PATH (e.g. /usr/local/bin)
sudo cp peacock /usr/local/bin/

# Verify the install
peacock --help

Features in Action

Follow Logs

BERJAYA

Pause / Resume

BERJAYA

Filter Logs

BERJAYA

Multiple Filters

BERJAYA

Remove Last Filter

BERJAYA


Usage

# Read a file
peacock app.log

# Tail a file (follow mode)
peacock -f app.log

# Tail the last 50 lines of a file
peacock -f -n 50 app.log

# Pipe stdin
your-app | peacock

CLI Flags

Flag Default Description
-f, --follow false Follow appended lines (like tail -f)
-n, --lines 10 Number of lines to read from end of file on startup
--config Platform default Path to a custom config file

Keybindings

Key Action
Space Pause / resume live tail
/ Enter filter mode (press Enter to apply)
Esc Cancel filter entry and keep active filters
Backspace Remove last active filter
Mouse wheel Scroll logs; scrolling up pauses live output
Up Scroll up one line and pause live output
g Jump to top and pause live output
G Jump to bottom
PageUp / Ctrl+B Scroll up one page and pause live output
PageDown / Ctrl+F Scroll down one page
Ctrl+C Quit

Scrolling down or pressing G keeps the view paused. Press Space to resume live output. New logs continue to arrive in the bounded queue while paused.


JSON Log Highlighting

peacock parses each line as JSON and renders it with structured formatting and color:

  • Level: color-coded: ERROR/FATAL in red, WARN in yellow, INFO in green, DEBUG in cyan
  • Timestamp: dimmed, pulled from time or timestamp fields
  • Message: bright white, pulled from msg or message fields
  • Caller: pulled from caller or file fields
  • Context: all remaining fields rendered as dimmed key=value pairs

Non-JSON lines are printed as-is without any transformation.


Configuration

The config file location depends on your platform:

Platform Path
Linux $XDG_CONFIG_HOME/peacock/config.yaml (falls back to ~/.config/peacock/config.yaml)
macOS ~/Library/Application Support/peacock/config.yaml
Windows %AppData%\peacock\config.yaml

The directory and file are created automatically on first run if they don't exist.

Full Config Reference

buffer:
  max_entries: 5000              # Max log entries to keep in memory

input:
  batch_max_entries: 256
  batch_interval: 33ms
  filter_prompt: "/ "            # Prompt shown in filter mode
  filter_placeholder: "filter logs"
  filter_char_limit: 256
  scanner_initial_buffer_bytes: 65536   # 64KB
  scanner_max_buffer_bytes: 1048576     # 1MB

source:
  file_tail_lines: 10            # Lines to read from end of file (-n default)
  file_poll: true                # Use polling instead of inotify
  file_reopen: false             # Reopen file if rotated/replaced

theme:
  level_error: "9"               # Color for ERROR/FATAL (256-color ANSI)
  level_warn: "11"               # Color for WARN
  level_info: "10"               # Color for INFO
  level_debug: "14"              # Color for DEBUG
  level_other: "7"               # Color for unrecognized levels
  level_bold: true
  timestamp_fg: "7"
  timestamp_faint: true
  message_fg: "15"
  caller_fg: "4"
  context_fg: "5"
  raw_fg: "7"
  panel_border: "8"
  status_fg: "7"
  filter_fg: "15"
  filter_bg: "8"

Theme colors accept either a 256-color ANSI code (e.g. "9") or a hex color string (e.g. "#ff5f5f").

Priority

Config values are resolved in this order (highest to lowest):

  1. Environment variables: overrides everything
  2. config.yaml: your config file
  3. Defaults: built-in fallback values

Environment Variables

Any config key can be set via an environment variable using the PEACOCK_ prefix. Nested keys are joined with _:

PEACOCK_BUFFER_MAX_ENTRIES=10000       # buffer.max_entries
PEACOCK_INPUT_BATCH_INTERVAL=50ms
PEACOCK_THEME_LEVEL_ERROR="#ff0000"    # theme.level_error
PEACOCK_SOURCE_FILE_POLL=false         # source.file_poll

Development

go test ./...
go test ./testdata/stress-test/...
go test -race ./...

The VHS UI suite generates deterministic logs and checks static files, stdin pipes, and followed files against recorded terminal snapshots:

brew install vhs ffmpeg
make test-ui
python3 scripts/test-ui-vhs.py run --rate 2000

Recordings, screenshots, generated tapes, and the JSON/Markdown reports are written to results/vhs-ui/. Static file mode renders and exits at EOF; the live modes exercise filtering, arriving logs, pause/resume, history navigation, and quitting.

Bubble Tea commands read up to input.batch_max_entries available entries at a time. Pending entries are flushed into the view by tea.Tick after input.batch_interval (33 ms by default, roughly 30 frames per second). Empty reads retry after the same interval. Filter changes, pause/resume, resizing, and input completion flush immediately; ordinary typing and downward navigation keep pending input queued until the tick. Upward navigation pauses on the currently displayed logs. History and pending entries stay bounded by buffer.max_entries, including while paused. Both batch settings must be positive; the interval accepts durations such as 16ms or 50ms. Ctrl+C quits immediately without flushing pending entries or rebuilding the view.

To compare two built binaries on macOS or Linux:

make build
python3 scripts/benchmark-throughput.py /path/to/baseline/peacock ./target/peacock --lines 5000 --runs 3

The benchmark pipes a finite, deterministic JSON stream into each viewer in a 70×240 pseudo-terminal and waits until its final entry appears in terminal output. It reports JSON results and median throughput, including process startup and rendering. This measures burst ingestion with rolling history, rather than a sustained generator rate. Use --rows, --cols, and --timeout to vary the setup.

Future Scope

The following items are planned but not yet implemented.

  • Logfmt support: v0 only parses JSON; logfmt auto-detection is deferred
  • Multi-file multiplexing: tail multiple files simultaneously with per-source tagging
  • Complex log rotation handling: re-attaching to rotated/moved files without restarting
  • In-message syntax highlighting: highlight IPs, UUIDs, durations, and other patterns inside log messages
  • Stack trace parsing: multi-line stack traces currently print as raw strings
  • Custom JSON key mapping: CLI flags or config to define which keys map to level/message/timestamp/caller

About

A fast, interactive terminal JSON log viewer (tail -f replacement) built with Go and Bubble Tea.

Topics

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages