Skip to main content

Log Rotation

Access log rotation is the process of:

  • Periodically archiving current access logs
  • Creating new log files
  • Optionally compressing or deleting old logs

This prevents:

  • Disk space exhaustion
  • Performance degradation
  • Unmanageable log files
  • Compliance violations

NGINX does NOT rotate logs automatically — rotation must be handled externally.

Why Log Rotation Is Critical (Security & Monitoring)

Risk Without RotationImpact
Disk fills upNGINX crashes
Huge log filesSlow analysis
No retentionCompliance issues
No compressionWasted storage

How NGINX Handles Access Logs Internally

  • NGINX keeps file descriptors open
  • Renaming a log file does not stop logging
  • NGINX must be reloaded or signaled to reopen logs

This is why rotation requires reload or USR1 signal.

On most Linux systems, logrotate is the standard and safest solution.

Basic Access Log Rotation Configuration

Example: Rotate NGINX Access Logs Daily

/var/log/nginx/access.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 nginx adm
sharedscripts
postrotate
systemctl reload nginx > /dev/null 2>&1
endscript
}

Explanation of Each Directive

DirectiveMeaning
dailyRotate every day
rotate 14Keep 14 old logs
compressGzip old logs
delaycompressCompress from 2nd rotation
missingokDon’t error if log missing
notifemptySkip empty logs
createCreate new file with permissions
sharedscriptsRun postrotate once
postrotateReload NGINX to reopen logs

How Rotation Actually Works (Step-by-Step)

  1. access.log → renamed to access.log.1
  2. Older logs shift: .2, .3, etc.
  3. New empty access.log is created
  4. NGINX reloads and writes to new file
  5. Old logs optionally compressed

Rotating Multiple Access Logs

If you use per-site access logs:

/var/log/nginx/\*access.log {
daily
rotate 7
compress
missingok
notifempty
sharedscripts
postrotate
systemctl reload nginx > /dev/null 2>&1
endscript
}

Rotation with Custom Access Log Formats

Example NGINX config:

log_format security '$remote_addr [$time_iso8601] "$request" $status';
access_log /var/log/nginx/security_access.log security;

Logrotate:

/var/log/nginx/security_access.log {
daily
rotate 30
compress
create 0640 nginx adm
postrotate
systemctl reload nginx
endscript
}

Log rotation is independent of log format.

Using USR1 Signal Instead of Reload (Advanced)

    postrotate
kill -USR1 `cat /run/nginx.pid`
endscript
  • Faster than reload
  • No config revalidation
  • Preferred for high-traffic systems

Log Rotation in Containers (Docker / Kubernetes)

Best Practice

    access_log /dev/stdout;
error_log /dev/stderr;
  • Let container runtime handle rotation
  • Avoids file-based logs

Security Considerations for Log Rotation

PracticeBenefit
Limited permissionsPrevent log tampering
CompressionProtects storage
Retention policyCompliance
Central shippingIncident response
Immutable storageForensics

Common Log Rotation Mistakes

MistakeImpact
No reload/USR1Logs continue writing to old file
No compressionDisk usage spikes
Too long retentionStorage waste
Too short retentionLoss of evidence
World-readable logsInformation leak
  1. Recommended Production Setup NGINX
access_log /var/log/nginx/access.log main;

Logrotate

/var/log/nginx/access.log {
daily
rotate 14
compress
delaycompress
create 0640 nginx adm
postrotate
kill -USR1 `cat /run/nginx.pid`
endscript
}