Updated:

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

SignalPossible cause
permission deniedfile, directory, or socket permissions
bind() failedport is occupied or permission is missing
connect() failedupstream unavailable
no such filewrong path or file not deployed
timeoutupstream, network, slow response
certificateTLS or certificate path
rewrite or internal redirection cyclerewrite/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:

  1. what exactly broke;
  2. when it started;
  3. which service responds;
  4. which HTTP code is visible;
  5. which error appears in logs.

After that, the fix is usually much clearer.