Make JSON / structured logs readable in your terminal. Pretty-prints JSON log lines, passes plain lines through untouched (unlike jq). Zero dependencies.
Project description
logtidy
Make JSON / structured logs readable in your terminal. Pipe a noisy stream of
JSON log lines in, get a clean, colorized, one-line-per-event view out — while
every non-JSON line (your print(), stack traces, framework banners) passes
through untouched.
Zero dependencies (pure standard library). Zero config. No daemon, no account.
python app.py 2>&1 | pipx run logtidy
08:15:30.123 INFO server started port=3000 env=dev
08:15:31.044 WARN slow query db.ms=1200 table=users
08:15:31.910 ERROR request failed method=POST path=/api/pay status=500
Traceback (most recent call last): ← plain lines pass straight through
File "app.py", line 42, in handler
Why not just jq?
jq is great until your stream isn't pure JSON. Feed it one plain line — a
startup banner, a traceback, a stray print() — and it aborts the whole
pipe. Real dev logs are always a mix. logtidy humanizes the JSON lines and
lets everything else flow by, so you never lose context.
It also speaks the common logger dialects out of the box: it finds your
timestamp (time / ts / timestamp / @timestamp), your level (level /
lvl / severity / levelname, as a word or a pino/bunyan number), and your
message (msg / message / text / event) — then lays the rest out as tidy
key=value pairs with nested objects flattened (req.headers.host).
Install
pipx run logtidy # no install, run on demand
pip install logtidy # or install the `logtidy` command
There's an identical Node build too: npx logtidy / npm i -g logtidy
(see logtidy). Both ports are tested against
the same vectors, so they format byte-for-byte the same.
Usage
<command> | logtidy [options]
logtidy [options] < app.log
| Option | Description |
|---|---|
-l, --level <lvl> |
Drop lines below this level (trace/debug/info/warn/error/fatal). Lines with no recognizable level are always kept. |
-f, --fields <list> |
Show only these comma-separated dot-path fields, e.g. -f level,msg,req.url. |
--filter level=<lvl> |
Alias for --level. |
--color / --no-color |
Force color on/off. Default: auto (on when stdout is a TTY; respects NO_COLOR). |
-h, --help |
Show help. |
-v, --version |
Print version. |
Examples
# only show warnings and worse
docker logs -f app | logtidy --level warn
# focus on the fields you care about
cat requests.log | logtidy --fields level,msg,req.method,req.url,res.status
# structlog / python-json-logger output just works
python -m myapp | logtidy
Design notes
- One pure function at the core.
format_line(raw_line, opts)has no I/O, no clock, no globals — it's a string→string (orNonewhen filtered). The CLI is a thin stdin→stdout wrapper around it. That's what makes the Node and Python ports verifiably identical. - Timestamps never go through a
datetime. ISO strings have their time portion sliced out as-is; epoch numbers are reduced to UTC time-of-day with integer math. Deterministic, timezone-free, identical across languages. - It won't break your pipe. Non-JSON in → same line out.
BrokenPipeError(e.g.| head) exits cleanly.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file logtidy-0.1.0.tar.gz.
File metadata
- Download URL: logtidy-0.1.0.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b8e70cebaf047982ff4a67438e08b32ac1e2bda4b34b29e4cc2287b2ed9c6c5
|
|
| MD5 |
9e8342b294a3f194bf1667141794f5f6
|
|
| BLAKE2b-256 |
79275e987709777d2372ff1e60a90ec758710d3faf6cdd7322bd628046be364e
|
File details
Details for the file logtidy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: logtidy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8eaaaad05b1e7d5e8bd6a5aa6bf5526133f30b14c59a4d0bd6041256b23d17d4
|
|
| MD5 |
0159743039fa2951a0716dfc10d3c84b
|
|
| BLAKE2b-256 |
524fbc0de46b0e1e388ba581ddf39c7b92f7ba3dcccbec4e976d964512e0bc30
|