Log Files
# Default locations
/var/log/nginx/access.log # All HTTP requests
/var/log/nginx/error.log # Errors and warnings
Custom Access Log Format
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $request_time';
log_format json escape=json '{"time":"$time_iso8601",'
'"ip":"$remote_addr","method":"$request_method",'
'"uri":"$uri","status":$status,'
'"size":$body_bytes_sent,"duration":$request_time,'
'"referer":"$http_referer","agent":"$http_user_agent"}';
access_log /var/log/nginx/access.log main;
}
Per-Site Logging
server {
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;
# Disable logging for specific paths
location /health {
access_log off;
}
location ~* \.(jpg|css|js)$ {
access_log off;
}
}
Error Log Levels
| Level | Description |
|---|
| debug | Everything (very verbose) |
| info | Informational messages |
| notice | Normal but significant |
| warn | Warnings (recommended for production) |
| error | Errors only |
| crit | Critical problems |
Analyzing Logs
# Top 10 IP addresses
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# Top requested URLs
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 404 errors
awk '$9 == 404' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn
# Requests per hour
awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1-2 | sort | uniq -c