Format and filter structured JSON logs
Paste NDJSON application logs and turn them into aligned readable lines, Markdown tables, JSON arrays, or CSV. Filter by level, search any field, flatten nested context, and keep invalid lines visible when you need them.
About this tool
json-log-formatter is for NDJSON or JSON Lines logs: one JSON object per line. It turns dense structured logs into an aligned view such as [time] LEVEL message key=value, or exports the same filtered records as a Markdown table, JSON array, or CSV.
It auto-detects common timestamp, level and message keys (time, ts, @timestamp, level, severity, msg, message) and can flatten nested context into dotted fields like req.method and user.id. Use the field filter to keep only records where a path contains or exactly equals a value, or leave the field blank to search the whole record.
The level filter understands words (info, warning, error, critical) plus common numeric conventions: bunyan/pino-style 10 through 60, and syslog priorities 7 through 0. Unknown custom level words still render; they sort like info for minimum-level filtering.
Limits and edge cases
- Input must be line-delimited JSON objects. A JSON array line is invalid for this tool.
- Blank lines and lines starting with
#or//are skipped. limitrenders at most 5,000 records after filtering; the default is 200.- Invalid JSON lines can be skipped, kept as raw message lines, or treated as errors with line numbers.
- This is not a full jq expression engine; use
field,filter,match, andfieldsfor focused log triage.
FAQ
What log formats does this accept?
It accepts NDJSON/JSONL: one JSON object per line. That is the common output from structured loggers. It does not parse syslog text, logfmt, Apache logs, or a single JSON array document.
How do I filter for only errors?
Set level to error. The tool keeps records whose detected level is error or fatal. Numeric levels are mapped automatically for common bunyan/pino and syslog conventions.
Can I filter a nested field?
Yes. Keep flatten enabled and set field to a dotted path such as req.method, user.id, or items.0.status. Use match=contains for case-insensitive substring search or match=exact for an exact value.
What happens to bad lines in a mixed log file?
The default on_invalid=skip skips them and adds a count notice to text outputs. Choose keep when you want raw non-JSON lines to remain visible, or error when a malformed line should fail the run and report its line number.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool json-log-formatter '{"time":"2026-08-08T12:00:00Z","level":"info","msg":"server started","port":8080}
{"time":"2026-08-08T12:00:09Z","level":"error","msg":"db timeout","req":{"method":"GET","url":"/api"}}'New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/json-log-formatter/?input=%7B%22time%22%3A%222026-08-08T12%3A00%3A00Z%22%2C%22level%22%3A%22info%22%2C%22msg%22%3A%22server%20started%22%2C%22port%22%3A8080%7D%0A%7B%22time%22%3A%222026-08-08T12%3A00%3A09Z%22%2C%22level%22%3A%22error%22%2C%22msg%22%3A%22db%20timeout%22%2C%22req%22%3A%7B%22method%22%3A%22GET%22%2C%22url%22%3A%22%2Fapi%22%7D%7D&level=all&field=req.method&filter=timeout&match=contains&fields=time%2Clevel%2Cmsg%2Creq.method%2Creq.url&level_field=severity&time_field=%40timestamp&message_field=message&flatten=true&on_invalid=skip&limit=200&output=prettyMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
