When debugging an application in production, I often want a quick overview of requests that didn't result in a "normal" HTTP response. If your web server writes JSON logs, jq makes this incredibly easy.
Here's a command I regularly use:
cat access_*.log \
| jq -r '
select(
.status != 200 and
.status != 206 and
.status != 302 and
.status != 304 and
.status != 308 and
.status != 101
)
| [.status, .request.uri]
| @csv
' \
| uniq
The output looks something like this:
404,"/api/v1/users/..."
403,"/admin/..."
429,"/api/v1/search"
500,"/api/v1/orders/..."
What this does
The command performs three simple steps:
- Reads all matching access log files.
- Filters out the expected HTTP status codes (
200,206,302,304,308, and101). - Outputs the remaining status code together with the requested URI as CSV.
Finally, uniq removes duplicate entries so you get a concise overview instead of thousands of repeated requests.
Why this is useful
This is an easy way to spot things like:
- Missing routes (
404) - Authorization issues (
401/403) - Rate limiting (
429) - Unexpected server errors (
500) - Any other response that deserves investigation
Instead of searching through millions of log lines, you immediately get a list of unique problem endpoints.
A small improvement
If your logs aren't already grouped, consider sorting before calling uniq:
cat access_*.log \
| jq -r '
select(
.status != 200 and
.status != 206 and
.status != 302 and
.status != 304 and
.status != 308 and
.status != 101
)
| [.status, .request.uri]
| @csv
' \
| sort \
| uniq
Or, even shorter:
...
| sort -u
It's a simple one-liner, but it's become one of my favourite ways to quickly identify unexpected responses in production logs.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.