Log reading basics
Logs are useful only when read systematically.
The main mistake is opening a huge file and looking for “something weird”. Narrow the scope first: service, time window, error type, request path, or port.
Last lines of a file
sudo tail -n 100 /var/log/nginx/error.log
Follow in real time:
sudo tail -f /var/log/nginx/error.log
systemd service journal
sudo journalctl -u nginx --no-pager -n 100
Last hour:
sudo journalctl -u nginx --since "1 hour ago" --no-pager
Follow in real time:
sudo journalctl -u nginx -f
Filter errors
sudo journalctl -u nginx --since "1 hour ago" --no-pager \
| grep -Ei 'error|failed|denied|timeout|refused|permission'
For a file:
sudo grep -Ei 'error|failed|denied|timeout|refused|permission' /var/log/nginx/error.log | tail -n 80
Access log
If access log is enabled:
sudo tail -n 100 /var/log/nginx/access.log
Find 4xx/5xx:
sudo awk '$9 ~ /^4|^5/ {print}' /var/log/nginx/access.log | tail -n 80
Find 404
sudo awk '$9 == 404 {print}' /var/log/nginx/access.log | tail -n 50
Find 500+
sudo awk '$9 >= 500 {print}' /var/log/nginx/access.log | tail -n 50
Limit by time
For journal:
sudo journalctl -u nginx --since "2026-05-19 10:00" --until "2026-05-19 11:00" --no-pager
For plain log files, use grep by date if the log format includes timestamps.
What to look for first
| Signal | Possible cause |
|---|---|
permission denied | file, directory, or socket permissions |
bind() failed | port is occupied or permission is missing |
connect() failed | upstream unavailable |
no such file | wrong path or file not deployed |
timeout | upstream, network, slow response |
certificate | TLS or certificate path |
rewrite or internal redirection cycle | rewrite/try_files issue |
Logs and HTTP checks together
Logs are easier to read while running curl.
In one terminal:
sudo journalctl -u nginx -f
In another:
curl -kI https://getsrv.app/no-such-page
curl -kI https://getsrv.app/en/docs/
This helps connect a request with the matching error.
Not all errors are equally important
One-off 404s for random paths are normal.
More important:
- many 500s;
- repeated permission denied;
- service restarts continuously;
- same endpoint fails consistently;
- identical errors appeared right after deploy.
Minimal set
sudo systemctl status nginx --no-pager
sudo journalctl -u nginx --since "30 minutes ago" --no-pager
sudo tail -n 100 /var/log/nginx/error.log
curl -kI https://getsrv.app/
curl -kI https://getsrv.app/no-such-page
Rule
First record:
- what exactly broke;
- when it started;
- which service responds;
- which HTTP code is visible;
- which error appears in logs.
After that, the fix is usually much clearer.