Nginx Cheatsheet
Logging
Use this Nginx reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Default Log Locations
| File | Contents |
|---|---|
/var/log/nginx/access.log | Every HTTP request |
/var/log/nginx/error.log | Errors, warnings, notices |
# Watch logs live tail -f /var/log/nginx/access.log tail -f /var/log/nginx/error.log # Filter by status code tail -f /var/log/nginx/access.log | grep '" 5' # Count requests by IP awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
Access Log Directive
access_log path [format [buffer=size [flush=time]] [if=condition]]; # Examples access_log /var/log/nginx/example.access.log combined; access_log /var/log/nginx/example.access.log main buffer=32k flush=5s; access_log off; # Disable entirely for this block
Error Log Directive
error_log path [level]; # Level (lowest to most verbose): emerg alert crit error warn notice info debug error_log /var/log/nginx/error.log warn; # Production default error_log /var/log/nginx/error.log debug; # Full debug (very verbose) error_log /dev/null; # Suppress all errors (not recommended)
Built-in Log Formats
# "combined" (default) — already defined in nginx.conf log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; # "main" (defined in the stock nginx.conf, not built in) is combined # plus "$http_x_forwarded_for" — see Custom Log Format below
Custom Log Format
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format json_combined escape=json
'{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_time":"$upstream_response_time",'
'"upstream_addr":"$upstream_addr",'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.json json_combined;
}Useful Log Variables
| Variable | Example value | Description |
|---|---|---|
$remote_addr | 203.0.113.5 | Client IP |
$http_x_forwarded_for | 203.0.113.5 | Original IP behind proxy |
$time_local | 13/Jun/2024:12:00:00 +0000 | Local time |
$time_iso8601 | 2024-06-13T12:00:00+00:00 | ISO 8601 time |
$request | GET /api/v1/users HTTP/1.1 | Full request line |
$request_method | GET | HTTP method |
$request_uri | /api/v1/users?page=2 | URI + query string |
$status | 200 | Response status code |
$body_bytes_sent | 1234 | Bytes sent (excludes headers) |
$bytes_sent | 1398 | Total bytes sent (includes headers) |
$request_time | 0.045 | Request processing time (seconds) |
$upstream_response_time | 0.042 | Time upstream took to respond |
$upstream_addr | 127.0.0.1:3000 | Backend server address |
$upstream_cache_status | HIT | Cache result |
$http_referer | https://google.com | Referer header |
$http_user_agent | Mozilla/5.0 ... | User-Agent header |
$ssl_protocol | TLSv1.3 | TLS version (HTTPS only) |
$ssl_cipher | TLS_AES_256_GCM_SHA384 | Cipher used |
Per-location Log Control
# Silence noisy health checks
location = /health {
access_log off;
return 200;
}
# Log static assets to a separate file
location ~* \.(js|css|png|jpg)$ {
access_log /var/log/nginx/static.log;
root /var/www/app;
}
# Conditional logging — skip 2xx responses from monitoring IPs
map $status $log_this {
~^2 0;
default 1;
}
access_log /var/log/nginx/errors.log combined if=$log_this;Conditional Access Log (if=)
# Only log errors
map $status $is_error {
~^[45] 1;
default 0;
}
access_log /var/log/nginx/errors.log combined if=$is_error;Log Rotation
# /etc/logrotate.d/nginx (installed by package, shown for reference) /var/log/nginx/*.log { daily missingok rotate 14 compress delaycompress notifempty create 640 nginx adm sharedscripts postrotate # Send USR1 to reopen log files without restarting nginx -s reopen endscript }
# Force immediate rotation sudo logrotate -f /etc/logrotate.d/nginx # Manually reopen logs (zero-downtime) sudo nginx -s reopen # or sudo kill -USR1 $(cat /var/run/nginx.pid)
Buffered Logging (High Traffic)
# Buffer writes — flush every 5 s or when buffer is full access_log /var/log/nginx/access.log combined buffer=64k flush=5s;
Reduces disk I/O on high-request-rate servers.