Fideloper

Lead dev @digitalsurgeons. I do LAMP, Laravel, Nodejs, Python, and lots of server stuff.

Ubuntu in production: Logrotate

This is the first post of a series of useful server configurations. We use Ubuntu in many production environments, and so these posts will be geared towards Ubuntu Server (12.04).


Some frameworks have their own logging in place (CodeIgniter). Some custom applications may have custom loggers (Monolog!). In cases such as this, you should set up rotating logs and a log backup. Logrotate is there to do this for you.

What does Logrotate do?

Logrotate periodically reads your log files, backs up older ones and creates a new log. This helps prevent log files from getting unwieldy in size. It also will delete old log files so as not to fill your server memory.

Many apps setup logrotate for you. For instance, installing tasksel's lamp-server in Ubuntu adds the file /etc/logrotate.d/apache2, which is a configuration for Logrotate to rotate all apache access and error logs.

Configuring Logrotate

In stock Ubuntu, any config file you put into /etc/logrotate.d is going to run once per day. Logs are typically rotates once per day or less (Apache default in Ubuntu is in fact weekly).

Default Apache

Let's look over Apache's default in Ubuntu - /etc/logrotate.d/apache2.

/var/log/apache2/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
            /etc/init.d/apache2 reload > /dev/null
        endscript
        prerotate
            if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                    run-parts /etc/logrotate.d/httpd-prerotate; \
            fi; \
        endscript
}

This will rotate any files in /var/log/apache2 that end in ".log". Let's go through the options.

weekly: Rotate logs once per week

missingok: If no *.log files are found, don't freak out

rotate 52: Keep 52 files before deleting old log files (Thats a default of 52 weeks, or one years worth of logs!)

compress: Compress (gzip) log files

delaycompress: Delays compression until 2nd time around rotating. As a result, you'll have one current log, one older log which remains uncompressed, and then a series of compressed logs. More info on its specifics.

notifempty: Don't rotate empty files

create 640 root adm: Create new log files with set permissions/owner/group

sharedscripts: Run postrotate script after all logs are rotated versus once per each log.

postrotate: Scripts to run after rotating is done. In this case, Apache is reloaded so it writes to the newly created log files.

prerotate: Run before log rotating begins

Here's what I have for a CodeIgniter app in production, which uses Mongolog rather than the default logger.

/var/www/my-app/application/logs/*.log {
daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 660 appuser www-data
    sharedscripts
    dateext
    dateformat -web01-%Y-%m-%d-%s
    postrotate
        /etc/init.d/apache2 reload > /dev/null
        /usr/bin/s3cmd sync /var/www/my-app/application/logs/*.gz s3://app_logs
    endscript
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi; \
    endscript
}

The differences:

daily: This writes daily, since we expect a decent amount of traffic.

rotate 7: Keep only the last 7 days of logs in the server.

create 660 appuser www-data: New log files are owned by appuser, which is the user used to deploy files to the server. The log files are in group www-data, the same group that Apache runs as. The permissions (660) allow both owner and users of the same group to write to the file (appuser and apache users can then edit these files). This let's the CI app write to the log files! (Apache can write to the file as its in the same group, www-data. User appuser, as owner of the log files, can edit file if needed during or post-deployment).

dateext: Logs by default get a number appended to their filename. This option appends a date instead.

dateformat: The format of the date appended to the log filename you want. These logs also add web01, web02 (and so on) to the log file name so we know which webserver the log came from. This is needed if you are logging on multiple web servers behind a load balancer and will combine the logs at a later date.

postrotate: Note that I'm saving log files to Amazon S3 using the s3cmd CLI tool. Using 'sync' is similar to rsync - It will overwrite files in S3 with newer files. This is especially why differentiating log file names between web01, web02, etc is necessary. This is some magic right here - Both giving you off-site backups to your log files, and not taking up unnecessary server space.

The two most useful things here: Creating the log files with the correct permissions and saving log files to Amazon S3 for off-site backup.

comments powered by Disqus