Nginx Logging and Debugging Access Logs, Error Logs, and Troubleshooting
Learn how to configure and use Nginx access logs and error logs for debugging your Node.js deployment, including custom log formats and log analysis.
Nginx Logging and Debugging
Nginx logs are invaluable for debugging and monitoring your Node.js deployment. This guide covers access logs, error logs, custom formats, and log analysis.
Access Logs
Nginx logs every HTTP request to the access log:
# Default location /var/log/nginx/access.log # View in real-time sudo tail -f /var/log/nginx/access.log # View last 100 lines sudo tail -100 /var/log/nginx/access.log
Default Log Format
The default format (combined) looks like:
192.168.1.1 - - [20/Jul/2026:10:30:45 +0000] "GET /api/feed HTTP/1.1" 200 1234 "https://yourdomain.com" "Mozilla/5.0..."
Fields: IP - user [timestamp] "method path protocol" status size "referrer" "user-agent"
Custom Log Format
Define a custom format in nginx.conf:
log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'urt="$upstream_response_time"'; access_log /var/log/nginx/access.log main;
This adds:
$request_timeTotal time to serve the request$upstream_connect_timeTime to connect to Node.js$upstream_response_timeTime for Node.js to respond
Error Logs
# Default location /var/log/nginx/error.log # View in real-time sudo tail -f /var/log/nginx/error.log # View errors only sudo grep "[error]" /var/log/nginx/error.log
Error Log Levels
# In nginx.conf error_log /var/log/nginx/error.log warn;
Levels (from least to most severe):
debugVery detailed (for development only)infoInformationalnoticeNormal but significantwarnWarning (potential problem)errorError (something failed)critCritical (urgent)alertAlert (immediate action)emergEmergency (system unusable)
Use warn for production. Use debug only when troubleshooting specific issues.
Debugging Nginx Configuration
# Test configuration sudo nginx -t # Test with verbose output sudo nginx -T # Check if Nginx is running sudo systemctl status nginx # Check Nginx process ps aux | grep nginx
Common Error Scenarios
502 Bad Gateway
# Check error log sudo tail -20 /var/log/nginx/error.log # Common cause: Node.js not running pm2 status # Common cause: Wrong proxy_pass port sudo grep proxy_pass /etc/nginx/sites-enabled/*
504 Gateway Timeout
# Node.js is taking too long to respond # Increase proxy timeouts
location / { proxy_connect_timeout 60; proxy_send_timeout 60; proxy_read_timeout 60; proxy_pass http://localhost:3000; }
413 Request Entity Too Large
# Increase max body size client_max_body_size 20M;
301 Redirect Loop
# Common cause: Nginx redirects HTTP to HTTPS, but Node.js also redirects # Fix: Set trust proxy in Express # app.set("trust proxy", 1);
Log Analysis
Find Most Requested URLs
sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
Find Top IPs
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
Find 404 Errors
sudo grep " 404 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn
Find 5xx Errors
sudo grep -E " 5[0-9]{2} " /var/log/nginx/access.log
Find Slow Requests
# With custom log format including $request_time sudo awk '{print $NF}' /var/log/nginx/access.log | sort -rn | head -20
Log Rotation
Nginx log rotation is configured by default:
# Check logrotate config cat /etc/logrotate.d/nginx
Default settings:
- Daily rotation
- Keep 10 days
- Compress old logs
Disable Logging for Static Files
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { access_log off; expires 1y; }
This reduces log file size and disk I/O.
Send Logs to External Service
For centralized logging, send logs to a service like CloudWatch, Datadog, or ELK:
# Example: Send access log to syslog access_log syslog:server=127.0.0.1:514 main;
The Takeaway
Nginx logging involves access logs (every HTTP request) and error logs (errors and warnings). Use custom log formats to include request time and upstream response time for performance analysis. Common debugging steps: check error.log for 502/504 errors, verify Node.js is running with pm2 status, test config with nginx -t, and analyze logs with awk, grep, and sort for patterns like top URLs, IPs, and error rates.
Access logs are at /var/log/nginx/access.log (every HTTP request) and error logs are at /var/log/nginx/error.log (errors and warnings). View in real-time with sudo tail -f /var/log/nginx/access.log or /var/log/nginx/error.log.
Define log_format in nginx.conf with variables like $request_time (total request time), $upstream_connect_time (time to connect to Node.js), and $upstream_response_time (Node.js response time). Then use access_log /path/to/log main; to apply it.
Check sudo tail -20 /var/log/nginx/error.log for the error cause. Verify Node.js is running with pm2 status. Check that the proxy_pass port matches the Node.js port. Restart both Nginx and PM2 if needed.
Use awk to extract the URL field and count: sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20. This shows the top 20 most requested URLs with request counts.
Use 'warn' for production. It logs warnings and errors without filling the disk with debug info. Use 'debug' only temporarily when troubleshooting specific issues. Use 'error' if you want only errors, but 'warn' catches potential problems early.
Ready to master Node.js completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master Node.js
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

