Back to lessons

Hosting Operations

Summarize HTTP Status Codes

You need a quick count of HTTP response codes in a web access log.

Command

awk '{count[$9]++} END {for (code in count) print count[code], code}' ./fixtures/nginx/access.log | sort -nr

What changed

Nothing changes. The command counts response codes across the log.

Danger

safe

When to use it

Use this as the first pass when deciding whether a log problem is mostly redirects, client errors, or server errors.

When not to use it

Do not stop at the summary; follow up by grouping suspicious code families by IP, path, and time.

Undo or recovery

No undo needed because the command is read-only.

Expected output

Counts followed by HTTP status codes.

demo script

Disposable terminal steps

  1. head -5 ./fixtures/nginx/access.log
  2. awk '{count[$9]++} END {for (code in count) print count[code], code}' ./fixtures/nginx/access.log | sort -nr
  3. awk '$9 ~ /^5/ {print $1, $7, $9}' ./fixtures/nginx/access.log

simulated output

What it looks like

disposable vessel
::fixture-ready::
$ head -5 ./fixtures/nginx/access.log
198.51.100.10 - - [25/Jun/2026:10:00:01 +0000] "GET / HTTP/1.1" 200 512 "-" "Mozilla/5.0"
198.51.100.11 - - [25/Jun/2026:10:00:03 +0000] "GET /docs HTTP/1.1" 200 2048 "https://example.test/" "Mozilla/5.0"
198.51.100.12 - - [25/Jun/2026:10:00:08 +0000] "POST /api/search HTTP/1.1" 200 900 "-" "Mozilla/5.0"
203.0.113.44 - - [25/Jun/2026:10:01:01 +0000] "GET /missing HTTP/1.1" 404 120 "-" "ScannerBot/1.0"
203.0.113.44 - - [25/Jun/2026:10:01:03 +0000] "GET /missing HTTP/1.1" 404 120 "-" "ScannerBot/1.0"
::exit-code::0
$ awk '{count[$9]++} END {for (code in count) print count[code], code}' ./fixtures/nginx/access.log | sort -nr
13 200
5 404
2 405
2 403
1 503
1 502
1 500
::exit-code::0
$ awk '$9 ~ /^5/ {print $1, $7, $9}' ./fixtures/nginx/access.log
198.51.100.21 /api/report 500
198.51.100.22 /api/report 502
198.51.100.23 /api/report 503
::exit-code::0

YouTube Short

Start with status codes.

A status-code summary gives you the shape of the log before you dive into details. It is the fast way to see whether the problem is mostly 4xx, 5xx, or something else.

LinkedIn hook

Before chasing individual lines, get the shape of the whole log.

Question: What is your first command when opening a web access log?

experiments

A/B tests to run

Metric: youtube_retention_15s

A: Get the shape of the log first.

B: Start triage with status-code counts.