Server Management

Logrotate - Automatic Log Management

How to configure logrotate to automatically rotate, compress and delete logs on your VPS

Without logrotate logs grow indefinitely until they fill the disk. logrotate is pre-installed on Ubuntu/Debian and runs automatically every night.


Check status

# See global configuration
cat /etc/logrotate.conf

# List application-specific configurations
ls /etc/logrotate.d/

# Run logrotate manually (dry run)
sudo logrotate -d /etc/logrotate.conf

# Force immediate rotation
sudo logrotate -f /etc/logrotate.conf

Global configuration

/etc/logrotate.conf:

# Rotate weekly by default
weekly

# Keep 4 weeks of logs
rotate 4

# Compress old logs
compress

# Don't error if file doesn't exist
missingok

# Don't rotate if file is empty
notifempty

Application-specific configurations

Each file in /etc/logrotate.d/ configures rotation for a service.

Nginx

sudo nano /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

Apache

sudo nano /etc/logrotate.d/apache2
/var/log/apache2/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 640 root adm
    sharedscripts
    postrotate
        if invoke-rc.d apache2 status > /dev/null 2>&1; then
            invoke-rc.d apache2 reload > /dev/null 2>&1
        fi
    endscript
}

MySQL/MariaDB

sudo nano /etc/logrotate.d/mysql
/var/log/mysql/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 640 mysql adm
    sharedscripts
    postrotate
        mysqladmin --defaults-extra-file=/etc/mysql/debian.cnf flush-logs
    endscript
}

Custom application

sudo nano /etc/logrotate.d/my-app
/var/log/my-app/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    # copytruncate: copy and empty the original file
    # (alternative to postrotate if app doesn't support reload)
}

Main options

OptionDescription
daily / weekly / monthlyRotation frequency
rotate NHow many versions to keep
compressCompress with gzip
delaycompressCompress from previous version (not the latest)
missingokDon't error if file is missing
notifemptyDon't rotate if file is empty
create MODE USER GROUPCreate new file with these permissions
copytruncateCopy + empty (for apps that don't support reload)
postrotate ... endscriptScript to run after rotation
size 100MRotate when exceeds 100 MB (instead of time-based)
maxsize 500MRotate if exceeds this size even before period

Check logrotate logs

# System log for logrotate
grep logrotate /var/log/syslog | tail -20

# Status of last run
cat /var/lib/logrotate/status | head -30

Find logs using too much space

# Largest logs on the system
sudo find /var/log -type f -name "*.log" -exec du -sh {} \; | sort -rh | head -20

# Total per folder
sudo du -sh /var/log/*

Manual cleanup of old logs

# Delete compressed logs older than 30 days
sudo find /var/log -name "*.gz" -mtime +30 -delete

# Empty a log without deleting it (keep inode)
sudo truncate -s 0 /var/log/syslog

# Empty all Nginx logs
sudo truncate -s 0 /var/log/nginx/*.log

On this page