Skip to content

Logrotate

Logrotate is essential for managing log files in Linux systems, preventing disk space exhaustion while maintaining historical logs for debugging and compliance. This chapter covers logrotate configuration, directives, application-specific examples, and best practices for production log management.


┌─────────────────────────────────────────────────────────────────────────┐
│ LOGROTATE WORKFLOW │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 1. Trigger (cron, size, time) │ │
│ │ 2. Check conditions (size, time, notifempty) │ │
│ │ 3. Rename current log (log.1) │ │
│ │ 4. Create new empty log file │ │
│ │ 5. Signal application to reopen logs (optional) │ │
│ │ 6. Compress old logs (optional) │ │
│ │ 7. Delete old logs exceeding rotation count │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ Log Rotation States: │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ app.log → app.log.1 → app.log.2.gz → app.log.3.gz │ │
│ │ (active) (rotated) (compressed) (oldest) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Terminal window
# /etc/logrotate.conf - Global configuration
# Rotate weekly
weekly
# Keep 4 weeks of logs
rotate 4
# Create new empty files after rotation
create
# Use date as suffix
dateext
# Compress logs (gzip)
compress
# Delay compression (keep .1 uncompressed)
delaycompress
# Include per-application configs
include /etc/logrotate.d
# Don't error if log missing
missingok
# Don't rotate if empty
notifempty
# Rotate even if size exceeds daily/weekly
maxsize 100M
# Default create permissions
create 0644 root root

DirectiveDescription
rotate NKeep N old log files
daily/weekly/monthlyRotation frequency
compressCompress rotated logs
delaycompressDelay compression of previous file
create mode owner groupCreate new empty log
dateextUse date suffix instead of number
dateformatDate format for dateext
missingokDon’t error if log missing
notifemptyDon’t rotate if empty
maxsize NRotate when size exceeds N
minsize NMinimum size to rotate
size NRotate when exactly N
postrotate/endscriptScripts after rotation
prerotate/endscriptScripts before rotation
sharedscriptsRun scripts once per rotation
copytruncateCopy and truncate (for apps that don’t close logs)
Terminal window
# Size-based rotation
maxsize 100M
minsize 10M
# Date format
dateext
dateformat -%Y%m%d-%s
# Compression options
compress
compresscmd /usr/bin/xz
uncompresscmd /usr/bin/unxz
compressext .xz
compressoptions -9
# Script examples
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript

/etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
/etc/logrotate.d/apache2
/var/log/apache2/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 root adm
sharedscripts
postrotate
/bin/systemctl reload apache2 > /dev/null 2>/dev/null || true
endscript
}
/etc/logrotate.d/mysql
/var/log/mysql/*.log {
daily
rotate 7
missingok
create 660 mysql mysql
compress
postrotate
test -x /usr/bin/mysqladmin || exit 0
/usr/bin/mysqladmin flush-logs
endscript
}
# MySQL slow query log
/var/log/mysql/slow.log {
weekly
rotate 12
compress
delaycompress
missingok
create 660 mysql mysql
}
/etc/logrotate.d/postgresql
/var/log/postgresql/*.log {
weekly
rotate 10
compress
delaycompress
missingok
create 0600 postgres postgres
postrotate
su - postgres -c '/usr/lib/postgresql/*/bin/pg_ctl reload -D /var/lib/postgresql/*/main -l /var/log/postgresql/postgresql-*-main.log' > /dev/null 2>&1 || true
endscript
}
/etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 myapp myapp
sharedscripts
postrotate
systemctl restart myapp
endscript
}

Terminal window
# Test configuration without actual rotation
logrotate -d /etc/logrotate.conf
# Verbose debug output
logrotate -dv /etc/logrotate.conf
# Force rotation
logrotate -f /etc/logrotate.conf
logrotate -f /etc/logrotate.d/nginx
# Rotate specific file
logrotate -f /var/log/nginx/access.log
# Check status
cat /var/lib/logrotate/status
Terminal window
# Dry run for specific config
logrotate -d /etc/logrotate.d/nginx
# Test with verbose
logrotate -dv /etc/logrotate.d/nginx
# Force rotation and see output
logrotate -vf /etc/logrotate.d/nginx

Terminal window
# Check log directory sizes
du -sh /var/log/*
du -sh /var/log/*/ 2>/dev/null
# Find largest files
find /var/log -type f -exec du -h {} + | sort -rh | head -20
# Alert on disk usage
df -h /var/log
# Monitor with cron
0 0 * * * du -sh /var/log/* | sort -rh | head -10 >> /var/log/disk_usage.log
/etc/systemd/system/logrotate.timer
[Unit]
Description=Daily logrotate
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/logrotate.service
[Unit]
Description=Logrotate
After=syslog.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf
StandardOutput=journal
StandardError=journal
Terminal window
# Example retention policy
/var/log/syslog {
daily
rotate 30
compress
missingok
notifempty
}
/var/log/kern.log {
weekly
rotate 12
compress
missingok
}
/var/log/debug {
weekly
rotate 4
compress
missingok
notifempty
}

┌─────────────────────────────────────────────────────────────────────────┐
│ LOGROTATE INTERVIEW QUESTIONS │
├─────────────────────────────────────────────────────────────────────────┤
Q1: What is logrotate and how does it work? │
A1: │
- Automatically rotates log files based on size/time │
- Renames current log, creates new one │
- Optionally compresses old logs │
- Deletes oldest logs based on rotation count │
- Can signal applications to reopen logs │
─────────────────────────────────────────────────────────────────────────┤
Q2: What is the difference between compress and delaycompress? │
A2: │
- compress: Compress immediately after rotation │
- delaycompress: Don't compress .1 until next rotation (.1 stays plain) │
- Useful when app needs time to switch to new log │
─────────────────────────────────────────────────────────────────────────┤
Q3: What does copytruncate do and when should you use it? │
A3: │
- Copies log file content and truncates original │
- Use when application doesn't support log rotation │
- Risk: could lose logs between copy and truncate │
- Better: use when app supports log reopening │
─────────────────────────────────────────────────────────────────────────┤
Q4: How do you test logrotate configuration? │
A4: │
- logrotate -d /etc/logrotate.conf (debug mode) │
- logrotate -f (force rotation) │
- Check /var/lib/logrotate/status │
─────────────────────────────────────────────────────────────────────────┤
Q5: What is sharedscripts in logrotate? │
A5: │
- Runs postrotate/prerotate script ONCE for all matched logs │
- Without it, script runs for EACH matched log │
- Use for commands that restart service once │
─────────────────────────────────────────────────────────────────────────┤
Q6: How do you handle logs for applications that don't reopen files? │
A6: │
- Use copytruncate option (not ideal) │
- Use postrotate to signal application │
- Example: kill -USR1 for nginx, systemctl reload for others │
- Or use logger to send USR1 signal │
─────────────────────────────────────────────────────────────────────────┤
Q7: What happens if you don't rotate logs? │
A7: │
- Log files grow until disk is full │
- Can cause application crashes │
- Performance degradation │
- Cannot debug issues (logs become unreadable) │
─────────────────────────────────────────────────────────────────────────┤
Q8: How do you set up logrotate for a custom application? │
A8: │
- Create file in /etc/logrotate.d/ │
- Specify log path with wildcards if needed │
- Set rotation policy (daily/weekly/monthly, size) │
- Configure compression │
- Add postrotate for service restart if needed │
└─────────────────────────────────────────────────────────────────────────┘

Terminal window
# Common logrotate options
weekly # Rotation frequency
rotate 4 # Keep 4 old files
compress # Compress old logs
delaycompress # Delay compression
create 0640 # New log permissions
missingok # Ignore missing logs
notifempty # Skip empty logs
maxsize 100M # Size trigger
# Testing
logrotate -d config # Debug mode
logrotate -f config # Force rotation

  • logrotate: Automatic log rotation tool
  • Compression: gzip, xz with delaycompress
  • Signaling: postrotate to restart apps
  • Testing: -d debug, -f force options

Chapter 38: System Monitoring Tools


Last Updated: February 2026