Managing logs with logrotate on Ubuntu 16.04

How to set up logrotate to keep your system and application logs under control.

Logrotate is a system utility that handles the automatic rotation, compression, and cleanup of log files. Left unmanaged, logs on a long-running server will quietly eat up all your available disk space — logrotate prevents that from ever becoming a problem.

On Ubuntu 16.04, logrotate comes pre-installed and is already configured to handle log rotation for all system packages and applications.

Checking the installation

logrotate --version

You should see something like:

logrotate 3.8.7

How the configuration is structured

Logrotate's configuration lives in two places:

  • /etc/logrotate.conf — the main config file with global defaults and templates for non-system files
  • /etc/logrotate.d/ — a directory of per-service config files that extend or override those defaults

Let's look at the built-in config for apt as an example:

cat /etc/logrotate.d/apt

Output:

/var/log/apt/term.log {
rotate 12
monthly
compress
missingok
notifempty
}
/var/log/apt/history.log {
rotate 12
monthly
compress
missingok
notifempty
}

This file defines rotation rules for both term.log and history.log. Any directive not specified here falls back to the global defaults in /etc/logrotate.conf.

What each directive does:

  • rotate 12 — keep 12 archived copies before deleting old ones
  • monthly — rotate once a month
  • compress — compress archived logs (gzip by default)
  • missingok — don't throw an error if the log file doesn't exist
  • notifempty — skip rotation if the log file is empty

Method 1 — Adding a config to /etc/logrotate.d/

This is the standard approach for most applications. The config runs daily as root alongside all other logrotate jobs.

Here's an example for an app that writes access.log and error.log to /var/log/example-app/:

sudo nano /etc/logrotate.d/example-app
/var/log/example-app/*.log {
daily
missingok
rotate 14
compress
notifempty
create 0640 www-data www-data
sharedscripts
postrotate
systemctl reload example-app
endscript
}

What each directive does:

  • create 0640 www-data www-data — create a fresh empty log file after rotation with 0640 permissions, owned by www-data
  • sharedscripts — run the postrotate script once after all matching files are processed, rather than once per file
  • postrotate ... endscript — commands to run after rotation; in this example, the app is reloaded so it picks up the new log file

Once configured, test it without actually making any changes:

sudo logrotate /etc/logrotate.conf --debug

This dry-run mode prints a detailed breakdown of what logrotate would do — nothing is modified.

Our products and services

Web HostingReliable hosting services for websites of any scale.
Order
VPSFlexible cloud infrastructure with full root access.
Order
Dedicated ServersBare metal servers for maximum performance.
Order

Method 2 — Custom config with cron scheduling

If you need rotation on a non-standard schedule — say, every hour — you'll want to set up a config outside /etc/logrotate.d/ and trigger it manually via cron.

In this example, the app runs as user newuser and writes logs to /home/newuser/logs/. Create a local config file:

nano /home/newuser/logrotate.conf
/home/newuser/logs/*.log {
hourly
missingok
rotate 24
compress
create
}

This will rotate logs every hour, keeping 24 compressed archives and creating a fresh log file each time.

Create the log directory and a test file to work with:

cd ~
mkdir logs
touch logs/access.log

Run logrotate manually, pointing it to a custom state file:

logrotate /home/newuser/logrotate.conf --state /home/newuser/logrotate-state --verbose --force

Output:

reading config file /home/newuser/logrotate.conf
Handling 1 logs
rotating pattern: /home/newuser/logs/*.log  hourly (24 rotations)
empty log files are rotated, old logs are removed
considering log /home/newuser/logs/access.log
log does not need rotating

--verbose prints a detailed account of everything logrotate does. --force triggers rotation regardless of whether it's due yet. --state tells logrotate where to store its record of the last run.

Check what logrotate wrote to the state file:

cat /home/newuser/logrotate-state

Output:

logrotate state -- version 2
"/home/newuser/logs/access.log" 2020-05-18-16:0:0

This is how logrotate tracks what it's seen and when — so it knows exactly what to do on the next run. Run the same command an hour later and the log will be rotated as expected.

Automating with cron

To have logrotate run automatically every hour, add a cron job:

crontab -e

Add this line at the end of the file:

14 * * * * /usr/sbin/logrotate /home/newuser/logrotate.conf --state /home/newuser/logrotate-state

This will run logrotate at the 14th minute of every hour, every day.

Help

If you have any questions or need assistance, please contact us through the ticket system — we're always here to help!

Need help?Our engineers will help you free of charge with any question in minutesContact us