No description
- Go 100%
Recursively scan records for values held under generic error-shape keys (error/err/exception/cause/fault) and render each as a compact "name: message" summary, so a real upstream cause shows even when the top-level message is generic. Heuristic-only; not tied to any producer's payload layout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| .gitignore | ||
| CLAUDE.md | ||
| go.mod | ||
| main.go | ||
| README.md | ||
logtail
A small, fast formatter for JSON logs. It reads from a pipe or follows a file
like tail -f, pulls the timestamp, level and message out of each JSON record
using heuristics, and prints them as clean, color-coded lines.
It is a single dependency-free Go binary, so it cross-compiles to any platform and drops in anywhere with no runtime requirements.
Features
- Pipe or follow. Reads JSON log lines from stdin, or follows a file
(
tail -fstyle) when given a path. - Rotation & truncation aware. When following a file it detects log rotation (a new file at the same path) and in-place truncation, and keeps going — using only portable, poll-based checks.
- Prefix detection. Many log shippers prepend things like a timestamp and a
stream id before the JSON (
2026-06-10T04:20:40.796000+00:00 splitter/… {…}). logtail detects that prefix, folds a timestamp into the record, and keeps the rest available. - Heuristic field extraction. Finds the timestamp (
timestamp,time,ts,@timestamp, …), level (level,severity,lvl, …) and message (message,msg,text, …) across common key names. - Timestamp normalization. Reformats timestamps — ISO 8601 variants or Unix epoch (s/ms/µs/ns) — to one canonical layout. Values it can't parse are left untouched.
- Never drops a line. Any line that isn't valid trailing JSON is passed through verbatim, so nothing silently disappears.
Install
With the Go toolchain:
go install . # from a clone; installs to $(go env GOPATH)/bin
Or build and place the binary on your PATH:
go build -o logtail .
install -m 755 logtail /usr/local/bin/logtail
Cross-compile for another machine (static, no dependencies — just copy the file over):
GOOS=linux GOARCH=amd64 go build -o logtail-linux-amd64 .
GOOS=linux GOARCH=arm64 go build -o logtail-linux-arm64 .
Usage
# follow a file (tail -f style, survives rotation/truncation)
logtail /var/log/app.log
# read from a pipe
my-service | logtail
kubectl logs -f pod | logtail
Options
| Flag | Description |
|---|---|
-from-start |
Read the file from the beginning instead of following from the end |
-x, -extra |
Also print the remaining JSON fields (dimmed) |
-local |
Render normalized timestamps in local time instead of UTC |
-no-color |
Disable ANSI colors (also auto-disabled when output is not a TTY) |
Example
Input:
2026-06-10T04:20:40.796000+00:00 splitter/splitter/3bed8ce3 {"accountId":"e8d3…","level":"info","message":"splitter: shard parsed","records":10000,"timestamp":"2026-06-10T04:20:40.795Z"}
this is a plain log line with no JSON
Output:
2026-06-10 04:20:40.795 INFO splitter: shard parsed
this is a plain log line with no JSON
Add -x to append the remaining fields (accountId=… records=10000 …) dimmed
after the message.