Configuring Logging
1. Setting Access Log
| Directive | Values | Description |
|---|---|---|
| access_log | path [ format ] |
Defines the path to the access log file and optional format. Default is /var/log/nginx/access.log. |
| access_log | off |
Disables access logging for the current context. |
Example: Custom Log Format
log_format custom '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log custom;
Note: The
log_format directive must be defined before it is used in access_log.
2. Setting Error Log
| Directive | Values | Description |
|---|---|---|
| error_log | path [ level ] |
Set the error log file and logging level |
Example: Multiple error logs with different levels
error_log /var/log/nginx/error.log warn;
error_log /var/log/nginx/ssl_error.log error;
Note: The
error_log directive can be used at the main, http, stream, or server context levels.
Log Levels
debug- Detailed information, typically of interest only when diagnosing problems.info- General information about the operation of the server.notice- Normal but significant conditions that require attention.warn- Warning messages indicating potential issues.error- Error messages indicating problems that prevent normal operation.crit- Critical errors that require immediate attention.alert- Alerts that require immediate action.emerg- Emergency conditions that cause the system to be unusable.
3. Defining Log Format
| Directive | Description | Example |
|---|---|---|
| log_format | Defines a named log format with custom fields and variables. | log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; |
Example: Custom Log Format Definition
log_format detailed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log detailed;
Note: The
log_format directive can be defined multiple times with different names to support various logging styles.
Common Log Format Variables
$remote_addr- Client IP address$remote_user- User name if authenticated$time_local- Local time of the request$request- Original request line$status- Response status code$body_bytes_sent- Bytes sent to client$http_referer- Referer header$http_user_agent- User agent string
4. Using JSON Log Format
| Directive | Description | Example |
|---|---|---|
| log_format | Defines a named log format including JSON structure | log_format json '{"time": "$time_iso8601", "remote_addr": "$remote_addr", "request": "$request", "status": "$status", "body_bytes_sent": "$body_bytes_sent"}'; |
| access_log | Specifies the log file and format to use | access_log /var/log/nginx/access.log json; |
Example: JSON Log Format Configuration
log_format json '{"time": "$time_iso8601", "remote_addr": "$remote_addr", "request": "$request", "status": "$status", "body_bytes_sent": "$body_bytes_sent", "request_time": "$request_time"}';
access_log /var/log/nginx/access.log json;
Note: The JSON format is useful for structured logging and integration with log analysis tools like ELK stack or Grafana.
5. Disabling Logs
| Directive | Description | Values | Notes |
|---|---|---|---|
| access_log | Disables access logging | off |
Set to off to disable access logging entirely |
| error_log | Disables error logging | off |
Set to off to disable error logging entirely |
Note: Disabling logs can make debugging and monitoring difficult. Ensure alternative logging mechanisms are in place if needed.
6. Implementing Conditional Logging
| Directive | Description | Usage |
|---|---|---|
| access_log | Defines the file to which access logs are written. | access_log /var/log/nginx/access.log; |
| error_log | Defines the file to which error logs are written. | error_log /var/log/nginx/error.log; |
| log_format | Defines custom log formats for access logs. | log_format main '$remote_addr - $remote_user [$time_local] "$request" ...'; |
Example: Conditional Logging Based on Status Code
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/access.log main if=$status;
error_log /var/log/nginx/error.log warn;
location / {
return 200 "Hello World";
}
location /api/ {
proxy_pass http://backend;
access_log /var/log/nginx/api.log json if=$request_time > 1;
}
}
Example: Custom Log Format with Conditional Fields
log_format detailed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/access.log detailed if=$status < 400;
access_log /var/log/nginx/error_access.log detailed if=$status >= 400;
}
Note: The
if condition in logging directives is evaluated at runtime and can be based on variables like $status, $request_time, or custom variables.
7. Setting Log Buffer
| Directive | Values | Description |
|---|---|---|
| error_log | path |
Specifies the path to the error log file. Default is logs/error.log. |
| error_log | path level |
Same as above, but with a specific logging level (e.g., debug, info, warn, error). |
| error_log | syslog:server=address facility=tag |
Logs to a syslog server. address can be an IP or Unix socket path. |
| error_log | off |
Disables logging to the error log. |
Example: Setting Log Buffer Size
error_log /var/log/nginx/error.log warn;
# Log to syslog with custom facility
error_log syslog:server=unix:/dev/log facility=local7;
# Disable error logging
error_log off;
Note: The
error_log directive can be set at the main, http, server, or location level. It is inherited by child contexts unless overridden.
Log Buffer Configuration Summary
- error_log: Controls where and how error logs are written.
- Levels:
debug,info,notice,warn,error,crit,alert,emerg. - Buffering: Nginx buffers logs by default to reduce I/O overhead.
- Log Rotation: Use external tools like
logrotateto manage log file size and rotation.
8. Using Syslog
| Directive | Values | Description |
|---|---|---|
| error_log | syslog:server=address,facility=LOG_LOCAL0,tag=nginx |
Configures error logging to syslog with specified facility and tag. |
| access_log | syslog:server=address,facility=LOG_LOCAL1,tag=nginx |
Configures access logging to syslog with specified facility and tag. |
Example: Syslog Configuration
error_log syslog:server=unix:/dev/log,facility=LOG_LOCAL0,tag=nginx;
access_log syslog:server=unix:/dev/log,facility=LOG_LOCAL1,tag=nginx;
location / {
proxy_pass http://backend;
}
Note: Ensure that your system's syslog daemon (e.g., rsyslog or syslog-ng) is configured to handle messages from the specified facility and tag.
9. Configuring Log Rotation
| Directive | Description | Default | Notes |
|---|---|---|---|
| log_format | Defines a named log format for use in access logs | combined |
Can be reused across multiple access_log directives |
| access_log | Specifies the file to write access logs to | /var/log/nginx/access.log |
Can be specified multiple times for different formats or files |
| error_log | Specifies the file to write error logs to | /var/log/nginx/error.log |
Can be specified multiple times with different levels |
Example: Basic Log Format Definition
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
Example: Log Rotation with logrotate
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0644 nginx nginx
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
Note: The
postrotate script sends a signal to the Nginx master process to reopen log files, ensuring logs are rotated without downtime.
10. Logging to Multiple Files
| Directive | Description | Example |
|---|---|---|
| access_log | Defines the file to which access logs are written. Can be specified multiple times for different log formats or files. | access_log /var/log/nginx/access.log combined; |
| error_log | Defines the file to which error logs are written. Can also be specified multiple times. | error_log /var/log/nginx/error.log warn; |
Example: Logging to Multiple Files with Different Formats
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
log_format extended '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
server {
listen 80;
root /var/www;
# Log to main file with main format
access_log /var/log/nginx/access_main.log main;
# Log to extended file with extended format
access_log /var/log/nginx/access_extended.log extended;
# Error logs to separate file with warn level
error_log /var/log/nginx/error_warn.log warn;
}
}
Note: The
access_log and error_log directives can be used at multiple levels (http, server, location) to define different logging behavior for various parts of the configuration.
11. Using Custom Variables in Logs
| Variable | Definition | Usage |
|---|---|---|
| custom_var | log_format directive to define custom variables |
Used in access_log to include custom data |
Example: Defining and Using Custom Variables
log_format custom '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time $custom_var';
server {
listen 80;
server_name example.com;
# Define custom variable
set $custom_var "value";
access_log /var/log/nginx/access.log custom;
}
12. Implementing Structured Logging
| Directive | Description | Values | Notes |
|---|---|---|---|
| log_format | Defines a named log format for use in access logs | json, combined, custom format |
Can include variables like $request_time, $status |
| access_log | Specifies the file to which access logs are written | File path or off |
Can be set per server or location |
| error_log | Specifies the file to which error logs are written | File path or off |
Can be set with log levels like error, warn |
Example: JSON Log Format
log_format json_log '{"time": "$time_iso8601", "remote_addr": "$remote_addr", "request": "$request", "status": "$status", "body_bytes_sent": "$body_bytes_sent"}';
access_log /var/log/nginx/access.log json_log;
Example: Structured Log with Custom Fields
log_format structured '{"timestamp": "$time_iso8601", "method": "$request_method", "uri": "$uri", "status": "$status", "user_agent": "$http_user_agent", "ip": "$remote_addr"}';
access_log /var/log/nginx/structured.log structured;
Note: Structured logging is useful for integration with log aggregation tools like ELK stack or Splunk.