Nginx/Apache Log Guide - access/error Log Location and Analysis

Nginx/Apache Log Guide - access/error Log Location and Analysis

What You'll Learn

  • Where Nginx/Apache log files are located in Ubuntu
  • How to isolate causes for "500/502/503/504", "403", "404" from logs
  • A systematic approach to log investigation (order, filtering, reproduce, verify)
  • Understanding that log bloat can cause disk issues

Quick Summary

When web is broken, follow this order:

  1. Check service status: systemctl status nginx|apache2
  2. Check error log: tail -n 200 .../error.log
  3. Find failing request in access log: grep " 500 " .../access.log
  4. Reproduce and watch logs in real-time (most powerful)
  5. 502/503 means check upstream (app side)

Prerequisites

  • OS: Ubuntu
  • Web Server: Nginx or Apache
  • sudo access
  • Fixed procedures for beginners to not get lost

1. Check Which Server Is Running (Nginx? Apache?)

Conclusion: Confirm which server is active with systemctl before opening any log files.

Skip if you already know.

1-1. Check by Service Status

$ sudo systemctl status nginx
$ sudo systemctl status apache2
  • nginx is active -> Check Nginx logs
  • apache2 is active -> Check Apache logs
  • Both active -> Probably reverse proxy setup (check front-end logs first)

1-2. Check by Port (Supplemental)

$ sudo ss -lntp | grep ':80 '
$ sudo ss -lntp | grep ':443 '

2. Log Locations (Ubuntu Typical Paths)

Conclusion: Nginx logs: /var/log/nginx/; Apache: /var/log/apache2/ by default on Ubuntu.

Usually here on Ubuntu:

2-1. Nginx

  • error log: /var/log/nginx/error.log
  • access log: /var/log/nginx/access.log
$ ls -la /var/log/nginx

2-2. Apache (apache2)

  • error log: /var/log/apache2/error.log
  • access log: /var/log/apache2/access.log
$ ls -la /var/log/apache2

3. First Check "error log" (Fastest Path)

Conclusion: Always read error.log first — root cause appears there, not in access.log.

Access log shows "what happened", but root cause (stack trace/config error/upstream death) appears in error.log.

3-1. View Last 200 Lines (First Step)

# Nginx
$ sudo tail -n 200 /var/log/nginx/error.log

# Apache
$ sudo tail -n 200 /var/log/apache2/error.log

3-2. Real-time Tracking While Reproducing (Most Powerful)

# Nginx
$ sudo tail -f /var/log/nginx/error.log

# Apache
$ sudo tail -f /var/log/apache2/error.log

Keep this open, reproduce with browser/curl in another tab, and you'll find the cause fast. "Checked logs but couldn't understand" usually means not reproducing simultaneously.

4. Find Failing Request in access log

Conclusion: grep " 500 " access.log isolates failures to cross-check with error.log.

4-1. Find 500 Errors Only

$ sudo grep " 500 " /var/log/nginx/access.log | tail -n 50

4-2. Find 404 Errors Only

$ sudo grep " 404 " /var/log/nginx/access.log | tail -n 50

4-3. Find Specific Path Only (e.g., /api/)

$ sudo grep " /api/" /var/log/nginx/access.log | tail -n 50

5. Status Code Isolation Guide

Conclusion: Code maps to layer: 500=app, 502/503=upstream, 403=permissions, 404=routing.

5-1. 500 (Internal Server Error)

  • App internal error (PHP/Node/Ruby, etc.)
  • Config mistake (FastCGI settings, etc.)
  • Permission/path (Permission denied) possible

Next: error.log (priority), app logs, journalctl -u

5-2. 502 / 503 / 504 (Bad Gateway / Service Unavailable / Gateway Timeout)

  • Nginx/Apache can't connect to upstream / slow response / dead

Next step:

$ nc -vz 127.0.0.1 3000
$ curl -I http://127.0.0.1:3000

5-3. 403 (Forbidden)

  • Basic auth, IP restriction, WAF, directory permission, file permission

Next: error.log will show "permission denied" or "client denied"

5-4. 404 (Not Found)

  • Routing / file doesn't exist
  • SPA rewrite config missing

6. Finding Non-Default Log Locations

Conclusion: nginx -T | grep error_log or apache2ctl -S finds non-default log paths.

6-1. Nginx: Dump All Config

$ sudo nginx -T 2>&1 | grep -E "access_log|error_log" | head -n 50

6-2. Apache: Check Config

$ sudo apache2ctl -S

7. Filtering Tips for Faster Investigation

Conclusion: Reproduce the error with tail -f error.log open — this is the fastest path.

7-1. Want to See Only What's Happening Now

Best: "reproduce -> tail -f"

7-2. Filter by Keyword (e.g., upstream)

$ sudo grep -i "upstream" /var/log/nginx/error.log | tail -n 50

8. Common error.log Messages

Conclusion: "refused" is upstream down; "timed out" is slow; "denied" is file access.

8-1. connect() failed (111: Connection refused) while connecting to upstream

Meaning: Upstream isn't listening / down

$ nc -vz 127.0.0.1 <upstream-port>
$ sudo systemctl status <app-service>

8-2. upstream timed out (110: Connection timed out)

Meaning: Upstream is slow/congested (load, DB, I/O, etc.)

8-3. permission denied

Meaning: File/directory permission issue, possibly SELinux/AppArmor

8-4. client intended to send too large body

Meaning: Upload size limit (nginx client_max_body_size, etc.)

9. Things to Avoid

Conclusion: Never restart before reading error.log — log disk usage also needs monitoring.

Don't: Spam restart Without Checking Logs

Restarting without logs just hides the cause and wastes time. Check error.log / journalctl first.

Don't: Only Check access.log and Stop There

Root cause is usually in error.log. Access log is for "which request failed".

Don't: Ignore Log Bloat

More traffic = more logs. Can lead to disk full (No space left). Monitor disk and configure log rotation (logrotate).

Copy-Paste Template (Nginx Example)

# Service status
sudo systemctl status nginx

# Error (check this first)
sudo tail -n 200 /var/log/nginx/error.log

# Real-time tracking while reproducing (most powerful)
sudo tail -f /var/log/nginx/error.log

# Find failing requests
sudo grep " 500 " /var/log/nginx/access.log | tail -n 50
sudo grep " 502 " /var/log/nginx/access.log | tail -n 50
sudo grep " 403 " /var/log/nginx/access.log | tail -n 50
sudo grep " 404 " /var/log/nginx/access.log | tail -n 50

Summary

  • Check error.log first, then access.log
  • Reproduce + tail -f is the fastest path
  • 502/503/504 -> investigate upstream (app). Use port connectivity checks.
  • Logs consume disk. Can cause "No space left" issues.

Next Reading