Command documentation sourced from the linux-command project This comprehensive command reference is part of the linux-command documentation project.
logrotate - Rotate, compress, and mail system logs
The logrotate command is a system administration utility designed to manage the automatic rotation, compression, removal, and mailing of log files. It helps prevent log files from growing indefinitely and consuming excessive disk space. Logrotate is typically run as a daily cron job and reads configuration files that specify how log files should be handled. It supports flexible rotation schedules, compression methods, retention policies, and can execute scripts before and after rotation operations. This tool is essential for maintaining system health, managing storage resources, and ensuring logs remain organized and accessible.
Basic Syntax
logrotate [OPTIONS] <config_file>
Common Options
Command Line Options
-d, --debug- Debug mode: don't rotate anything, but show what would be done-f, --force- Force rotation even if it doesn't meet criteria-m, --mail <command>- Command to send mail (default is/usr/bin/mail -s)-s, --state <statefile>- Path to state file (default is/var/lib/logrotate/status)-v, --verbose- Display verbose messages during rotation-l, --log <logfile>- Log file to write messages to
Configuration Testing
--debug- Same as-d, show actions without executing--force- Same as-f, force rotation--usage- Display brief usage message
Configuration Directives
Rotation Schedule
daily- Rotate logs dailyweekly- Rotate logs weekly (default: Sunday)monthly- Rotate logs monthlyyearly- Rotate logs yearlysize <size>- Rotate when log exceeds specified size (e.g.,100M,1G)rotate <count>- Keep specified number of rotated logs
File Rotation
missingok- Don't error if log file is missingnotifempty- Don't rotate if log is emptydelaycompress- Compress rotated logs on next rotationcompress- Compress rotated logs with gzipnocompress- Don't compress rotated logscompresscmd <command>- Command to use for compressionuncompresscmd <command>- Command to use for uncompressioncompressext <extension>- Extension for compressed filescompressoptions <options>- Options for compression command
File Handling
create <mode> <owner> <group>- Create new log file after rotationcreateolddir <mode> <owner> <group>- Create directory for old logsolddir <directory>- Move rotated logs to specified directoryextension <ext>- Remove extension before adding rotation suffixstart <count>- Start numbering from specified number
Mail and Notification
mail <address>- Mail rotated logs to specified addressnomail- Don't mail logsmailfirst- Mail the first (oldest) rotated logmaillast- Mail the last (newest) rotated log
Scripts and Hooks
firstaction <script>- Run script before all log rotationslastaction <script>- Run script after all log rotationsprerotate <script>- Run script before rotating specific logspostrotate <script>- Run script after rotating specific logssharedscripts- Run scripts once for all logs in section
Advanced Options
maxage <days>- Remove logs older than specified daysminsize <size>- Don't rotate if log is smaller than specified sizemaxsize <size>- Don't rotate if log exceeds specified sizedateext- Use date extension instead of numbersdateyesterday- Use yesterday's date for dateextdateformat <format>- Format for date extensions
Usage Examples
Basic Log Rotation
Simple Configuration
# Basic logrotate configuration file
# /etc/logrotate.d/myapp
/var/log/myapp.log {
daily
rotate 7
compress
missingok
notifempty
create 644 root root
}
Testing Configuration
# Test configuration without making changes
logrotate -d /etc/logrotate.conf
# Test specific configuration file
logrotate -d /etc/logrotate.d/nginx
# Force rotation with verbose output
logrotate -vf /etc/logrotate.d/myapp
Rotation Scheduling
Daily Rotation
# Rotate logs daily, keep 7 days
/var/log/app/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 www-data www-data
}
Weekly Rotation
# Rotate logs weekly, keep 4 weeks
/var/log/system/*.log {
weekly
rotate 4
compress
missingok
notifempty
create 644 root root
}
Size-Based Rotation
# Rotate when log reaches 100MB
/var/log/bigapp.log {
size 100M
rotate 5
compress
delaycompress
missingok
notifempty
create 644 appuser appuser
}
Combined Criteria
# Rotate daily or when size exceeds 50MB
/var/log/database.log {
daily
size 50M
rotate 30
compress
missingok
notifempty
create 644 dbuser dbuser
}
Advanced Rotation Patterns
Date-Based Extensions
# Use date extensions instead of numbers
/var/log/access.log {
daily
rotate 30
dateext
dateformat -%Y-%m-%d
compress
missingok
notifempty
create 644 www-data www-data
}
Hourly Rotation
# Hourly rotation for high-volume logs
/var/log/highfreq.log {
hourly
rotate 24
compress
delaycompress
missingok
notifempty
create 644 appuser appuser
postrotate
/usr/bin/systemctl reload highfreq.service
endscript
}
Custom Compression
# Use bzip2 instead of gzip for better compression
/var/log/archive.log {
weekly
rotate 52
compresscmd /bin/bzip2
uncompresscmd /bin/bunzip2
compressext .bz2
compressoptions -9
missingok
notifempty
create 644 root root
}
File Organization
Move to Archive Directory
# Move old logs to archive directory
/var/log/production/*.log {
daily
rotate 90
compress
missingok
notifempty
olddir /var/log/archive/
create 644 produser produser
}
Separate Rotation Settings
# Different settings for different log types
/var/log/app/error.log {
daily
rotate 14
compress
create 644 appuser appuser
}
/var/log/app/access.log {
hourly
rotate 48
compress
create 644 appuser appuser
}
/var/log/app/debug.log {
size 10M
rotate 5
compress
create 644 appuser appuser
}
Practical Examples
System Administration
Web Server Logs
# Apache/Nginx log rotation
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 www-data www-data
sharedscripts
postrotate
/usr/sbin/nginx -s reload > /dev/null 2>&1 || true
endscript
}
# Apache logs with custom naming
/var/log/apache2/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 root adm
sharedscripts
postrotate
/usr/sbin/apache2ctl graceful > /dev/null 2>&1 || true
endscript
}
System Logs
# System log rotation
/var/log/syslog {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 syslog adm
sharedscripts
postrotate
/usr/bin/systemctl reload rsyslog > /dev/null 2>&1 || true
endscript
}
# Auth logs
/var/log/auth.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 644 root adm
}
Application Logs
# Multi-application log management
/var/log/apps/*.log {
daily
size 50M
rotate 30
compress
delaycompress
missingok
notifempty
create 644 appuser appgroup
sharedscripts
postrotate
find /var/log/apps/ -name "*.log.*" -mtime +90 -delete
endscript
}
Database Log Management
MySQL Logs
# MySQL error log rotation
/var/log/mysql/error.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 mysql mysql
postrotate
# Test if MySQL is running before attempting reload
if [ -x /usr/bin/mysqladmin ]; then
/usr/bin/mysqladmin ping > /dev/null 2>&1 && \
/usr/bin/mysqladmin flush-logs > /dev/null 2>&1
fi
endscript
}
# MySQL slow query log
/var/log/mysql/slow.log {
weekly
rotate 4
compress
delaycompress
missingok
notifempty
create 644 mysql mysql
size 1G
}
PostgreSQL Logs
# PostgreSQL log rotation
/var/log/postgresql/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 644 postgres postgres
sharedscripts
postrotate
/usr/bin/pg_ctl reload -D /var/lib/postgresql/data > /dev/null 2>&1
endscript
}
Development Workflow
Application Development Logs
# Development environment logs
/home/user/project/logs/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 $USER $USER
size 100M
maxage 30
}
# Debug logs with different retention
/home/user/project/logs/debug/*.log {
daily
rotate 3
compress
missingok
notifempty
create 644 $USER $USER
maxage 7
}
Build and CI/CD Logs
# CI/CD pipeline logs
/var/log/ci/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 jenkins jenkins
sharedscripts
postrotate
# Archive old build artifacts
find /var/lib/jenkins/jobs -name "*.log" -mtime +60 -delete
endscript
}
Backup and Archiving
Log Archive Strategy
# Production log archiving
/var/log/production/*.log {
daily
rotate 365
compress
delaycompress
missingok
notifempty
dateext
dateformat -%Y-%m-%d
create 644 produser prodgroup
olddir /archive/production/logs/
}
# Critical logs with longer retention
/var/log/production/critical/*.log {
daily
rotate 1095 # 3 years
compress
delaycompress
missingok
notifempty
dateext
dateformat -%Y-%m-%d
create 644 produser prodgroup
olddir /archive/production/critical/
}
Remote Log Management
# Centralized log server rotation
/var/log/central/hosts/*/*.log {
daily
rotate 90
compress
delaycompress
missingok
notifempty
create 644 syslog syslog
sharedscripts
postrotate
# Sync to backup server
rsync -a --delete /var/log/central/ backup-server:/logs/central/
endscript
}
Advanced Usage
Complex Configuration Patterns
Conditional Rotation
# Complex rotation with conditions
/var/log/app/application.log {
daily
size 500M
rotate 30
compress
delaycompress
missingok
notifempty
minsize 10M
maxsize 2G
create 644 appuser appgroup
sharedscripts
prerotate
# Check disk space before rotation
if [ $(df /var/log | awk 'NR==2 {print $5}' | sed 's/%//') -gt 90 ]; then
echo "Warning: Low disk space, skipping log rotation"
exit 1
fi
endscript
postrotate
# Clean up old compressed logs if needed
find /var/log/app/ -name "*.log.*.gz" -mtime +60 -delete
endscript
}
Multiple Log Sets
# Multiple log files with shared configuration
/var/log/webserver/*.log
/var/log/application/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
sharedscripts
prerotate
# Perform backup before rotation
if [ -d /backup/logs ]; then
rsync -a --include="*.log" --exclude="*" /var/log/ /backup/logs/
fi
endscript
postrotate
# Notify monitoring system
curl -X POST http://monitoring.local/alert \
-d "Log rotation completed for $(date)"
endscript
}
Custom Scripts Integration
External Script Execution
# Log rotation with custom processing
/var/log/transactions/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 transuser transgroup
sharedscripts
postrotate
# Process rotated logs
for logfile in /var/log/transactions/*.log.1.gz; do
if [ -f "$logfile" ]; then
/usr/local/bin/process_transaction_log "$logfile" &
fi
done
# Update database with rotation info
/usr/local/bin/update_log_rotation_db $(date +%Y-%m-%d)
endscript
}
Health Checks and Monitoring
# Log rotation with health monitoring
/var/log/critical/*.log {
hourly
rotate 24
compress
delaycompress
missingok
notifempty
create 644 root root
sharedscripts
lastaction
# Check if all logs were rotated successfully
failed=0
for log in $1; do
if [ ! -f "${log}.1.gz" ]; then
logger -t logrotate "Failed to rotate $log"
failed=1
fi
done
if [ $failed -eq 1 ]; then
# Send alert
echo "Log rotation failures detected" | \
mail -s "Logrotate Alert" admin@example.com
fi
endscript
}
Performance Optimization
Parallel Processing
# Optimized for high-volume systems
/var/log/highvolume/*.log {
hourly
rotate 12
compress
compresscmd /usr/bin/pigz # Parallel gzip
compressoptions -p 4 # Use 4 threads
delaycompress
missingok
notifempty
size 1G
create 644 hvuser hvgroup
sharedscripts
postrotate
# Clean up in background
find /var/log/highvolume/ -name "*.log.*" -mtime +7 -delete &
endscript
}
Memory-Efficient Configuration
# For systems with limited resources
/var/log/constrained/*.log {
weekly
rotate 4
nocompress # Skip compression to save CPU
missingok
notifempty
create 644 user user
maxage 30 # Remove old logs quickly
}
Integration and Automation
Cron Integration
Manual Cron Setup
# Add to crontab for custom schedule
crontab -e
# Run logrotate every hour
0 * * * * /usr/sbin/logrotate /etc/logrotate.hourly.conf
# Run logrotate every 6 hours
0 */6 * * * /usr/sbin/logrotate /etc/logrotate.conf
# Custom daily run at 2 AM with full path
0 2 * * * /usr/sbin/logrotate -s /var/lib/logrotate/status /etc/logrotate.conf
Custom Logrotate Configuration
# Create hourly logrotate configuration
cat > /etc/logrotate.hourly.conf << 'EOF'
# Hourly log rotation configuration
include /etc/logrotate.d/hourly
/var/log/nginx/access.log {
hourly
rotate 24
compress
delaycompress
missingok
notifempty
create 644 www-data www-data
postrotate
/usr/sbin/nginx -s reload > /dev/null 2>&1
endscript
}
EOF
Monitoring and Alerting
Logrotate Monitoring Script
#!/bin/bash
# Monitor logrotate execution and send alerts
LOGROTATE_LOG="/var/log/logrotate.log"
ALERT_EMAIL="admin@example.com"
ERROR_THRESHOLD=5
# Check logrotate log for errors
error_count=$(grep -c "error" "$LOGROTATE_LOG" 2>/dev/null || echo "0")
if [ "$error_count" -gt "$ERROR_THRESHOLD" ]; then
echo "Logrotate errors detected: $error_count" | \
mail -s "Logrotate Alert" "$ALERT_EMAIL"
fi
# Check for missing log files that should be rotated
missing_logs=$(find /var/log -name "*.log" -mtime +30 -type f 2>/dev/null | wc -l)
if [ "$missing_logs" -gt 0 ]; then
echo "Found $missing_logs potentially unrotated logs" | \
mail -s "Log Rotation Warning" "$ALERT_EMAIL"
fi
Systemd Service Integration
# Create systemd timer for custom logrotate schedule
cat > /etc/systemd/system/logrotate-hourly.timer << 'EOF'
[Unit]
Description=Hourly log rotation
Requires=logrotate-hourly.service
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
EOF
cat > /etc/systemd/system/logrotate-hourly.service << 'EOF'
[Unit]
Description=Hourly log rotation
[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.hourly.conf
EOF
# Enable and start the timer
systemctl enable logrotate-hourly.timer
systemctl start logrotate-hourly.timer
Troubleshooting
Common Issues
Configuration Errors
# Debug configuration syntax issues
logrotate -d /etc/logrotate.d/problematic_config
# Check configuration file syntax
logrotate -f /etc/logrotate.d/test_config 2>&1 | grep -i error
# Validate all configuration files
for config in /etc/logrotate.d/*; do
echo "Checking $config:"
logrotate -d "$config" 2>&1 | head -10
done
Permission Issues
# Check file permissions
ls -la /var/log/
ls -la /var/lib/logrotate/
# Fix common permission issues
chown root:adm /var/log/some.log
chmod 644 /var/log/some.log
# Check state file permissions
ls -la /var/lib/logrotate/status
chown root:root /var/lib/logrotate/status
chmod 644 /var/lib/logrotate/status
Disk Space Issues
# Find large log files
find /var/log -type f -size +100M -exec ls -lh {} \;
# Clean up old rotated logs manually
find /var/log -name "*.log.*" -mtime +90 -delete
# Check compression effectiveness
du -sh /var/log/app.log
du -sh /var/log/app.log.1.gz
Service Reload Issues
# Test reload commands manually
nginx -s reload
apache2ctl graceful
systemctl reload rsyslog
# Check service status after reload
systemctl status nginx
systemctl status apache2
systemctl status rsyslog
Debugging Techniques
Verbose Execution
# Run with maximum verbosity
logrotate -vf /etc/logrotate.conf
# Monitor specific log rotation
logrotate -vf /etc/logrotate.d/nginx | tee /tmp/rotation.log
# Check what would happen (dry run)
logrotate -d /etc/logrotate.conf | grep -A 10 "rotating pattern"
State File Analysis
# Examine logrotate state file
cat /var/lib/logrotate/status
# Check last rotation time for specific log
grep "/var/log/nginx/access.log" /var/lib/logrotate/status
# Reset rotation state for testing
sed -i '/\/var\/log\/test.log/d' /var/lib/logrotate/status
Related Commands
logger- Add entries to system logjournalctl- Query systemd journallogwatch- System log analyzer and reporterrsyslog- Reliable system and kernel logging daemoncron- Daemon to execute scheduled commandscrontab- Manage crontab filessystemctl- Control systemd system and service managerfind- Search for files and execute commandsdu- Estimate file space usagedf- Report file system disk space usage
Best Practices
- Test configurations with
-dflag before applying to production - Use
delaycompressto avoid compression-related race conditions - Set appropriate permissions for new log files with
createdirective - Use
sharedscriptsto avoid executing scripts multiple times - Monitor disk space and set appropriate retention policies
- Use
missingokfor optional log files that may not exist - Implement
notifemptyto avoid rotating empty log files - Use
dateextfor better chronological organization of old logs - Set up monitoring for logrotate failures and disk space issues
- Regularly review and adjust rotation intervals based on log growth patterns
Performance Tips
- Use
pigzinstead ofgzipfor parallel compression on multi-core systems - Adjust rotation intervals based on actual log growth rates
- Use
sizedirective for high-volume logs in addition to time-based rotation - Implement
maxageto prevent accumulation of very old logs - Use
olddirto separate current logs from archived ones - Optimize compression levels based on CPU vs. storage trade-offs
- Consider
nocompressfor frequently accessed old logs - Use
sharedscriptsto reduce the number of service reloads - Implement background cleanup tasks to remove old compressed logs
- Monitor system load during log rotation and adjust schedules accordingly
The logrotate command is an essential tool for managing log files in Linux systems. Its flexible configuration options, integration with system services, and automation capabilities make it indispensable for maintaining system hygiene, managing storage resources, and ensuring logs remain organized and accessible for troubleshooting and analysis purposes.