Reading the Logs
nginx writes a line to /var/log/nginx/access.log for every request, and to error.log when something goes wrong. They belong to the group adm — and you're in it, so no sudo needed.
tail -n 5 /var/log/nginx/access.log
One line, field by field
203.0.113.42 - - [17/Oct/2026:14:02:11 +0200] "GET /about.html HTTP/1.1" 200 2348 "-" "Mozilla/5.0 …"
| Field (awk) | Here | Meaning |
|---|---|---|
$1 | 203.0.113.42 | who asked (the visitor's IP) |
$4 | [17/Oct/2026:14:02:11 | when |
$6 $7 | "GET /about.html | what they asked for |
$9 | 200 | the answer's status |
$10 | 2348 | bytes sent |
| last part | "Mozilla/5.0 …" | the browser or bot |
Questions the log answers
# Who visits the most?
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -3
# How did the server answer?
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c
# Which pages are missing?
awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# Which search engines came by?
grep -i bot /var/log/nginx/access.log
Requests for /wp-login.php, /.env or /phpmyadmin/ on a site that has none of them are scanners looking for weak spots — every public server sees them.
The error log
tail /var/log/nginx/error.log
It says why: No such file or directory behind a 404, Permission denied behind a 403, connect() failed when a backend is down.
💡
tail -f /var/log/nginx/access.logfollows the log live (Ctrl+C to stop). Old logs are rotated daily by logrotate:access.log.1, then compressedaccess.log.2.gz— read those withzcat.