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
Metadata
Release files for logtidy 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| logtidy-0.1.0.tar.gz | 11.9 kB | Without provenance | Details for logtidy-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| logtidy-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for logtidy-0.1.0-py3-none-any.whl |
Total release size: 22.1 kB
Release files / logtidy-0.1.0.tar.gz
| Download URL | logtidy-0.1.0.tar.gz |
|---|---|
| Size | 11.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b8e70cebaf047982ff4a67438e08b32ac1e2bda4b34b29e4cc2287b2ed9c6c5
|
|
BLAKE2b-256 checksum How to use checksums |
79275e987709777d2372ff1e60a90ec758710d3faf6cdd7322bd628046be364e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Release files / logtidy-0.1.0-py3-none-any.whl
| Download URL | logtidy-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8eaaaad05b1e7d5e8bd6a5aa6bf5526133f30b14c59a4d0bd6041256b23d17d4
|
|
BLAKE2b-256 checksum How to use checksums |
524fbc0de46b0e1e388ba581ddf39c7b92f7ba3dcccbec4e976d964512e0bc30
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Security for logtidy 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.