How to Configure Logrotate to Manage and Compress System Logs in Ubuntu

Production servers, self-hosted Docker containers, web servers (such as Nginx and Apache), and custom system services generate continuous streams of diagnostic logging in Ubuntu. Left unmanaged, active log files inside /var/log/ can quietly swell to tens of gigabytes, consuming critical disk space, slowing system I/O, and eventually crashing databases or preventing system boots when storage reaches 100%. Ubuntu automates log lifecycle maintenance using logrotate, an indispensable administrative daemon that rotates, compresses, and purges logs on predetermined schedules.

How Logrotate Operates in Modern Ubuntu

In Ubuntu 22.04 LTS and 24.04 LTS, logrotate is triggered automatically once per day via a systemd timer (logrotate.timer) rather than legacy cron. When triggered, logrotate evaluates configuration directives stored in /etc/logrotate.conf along with modular service files located in /etc/logrotate.d/. If a target log satisfies defined criteria (such as passing a time interval or exceeding a file size limit), logrotate moves the active log, creates a blank replacement, and compresses older cycles.

Understanding Default Configuration Files

Ubuntu organizes logrotate rules into two distinct tiers:

  • /etc/logrotate.conf: Establishes global defaults (such as weekly rotation, keeping 4 backlogs, and utilizing gzip compression).
  • /etc/logrotate.d/: Contains modular configuration files for individual applications (such as rsyslog, dpkg, ufw, and nginx). Directives here override global settings for specific log paths.

How to Create a Custom Logrotate Configuration

Suppose you host a custom web application or Python backend that outputs logs to /var/log/myapp/app.log. Follow these steps to build an automated rotation policy:

Step 1: Create a Dedicated Service File

Open a terminal on your Ubuntu system and create a new configuration file inside /etc/logrotate.d/ using nano:

sudo nano /etc/logrotate.d/myapp

Step 2: Define Rotation Directives

Add the following configuration block tailored for high-volume logs:

/var/log/myapp/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        systemctl reload myapp.service > /dev/null 2>&1 || true
    endscript
}

Directive Breakdown and Operational Explanation

Each directive in the configuration block serves a specific safeguard role:

  • daily: Rotates the log once every 24 hours (alternatives include weekly, monthly, or size-based triggers like size 100M).
  • missingok: Prevents logrotate from throwing an error if the log file does not exist.
  • rotate 14: Retains 14 rotated log files before automatically deleting the oldest backlog.
  • compress: Compresses rotated files using gzip (converting app.log.1 to app.log.2.gz), reducing disk consumption by up to 90%.
  • delaycompress: Defers compression of the most recently rotated log until the subsequent cycle, ensuring active processes writing trailing entries are not interrupted.
  • notifempty: Skips rotation if the log file contains zero bytes, preventing unnecessary archive creation.
  • create 0640 www-data adm: Creates the new empty log immediately after rotation with specified file permissions, owner user, and group.
  • postrotate / endscript: Executes shell commands once rotation finishes. This sends a reload signal to the running application daemon so it releases the old file descriptor and begins writing to the newly created log file.

Testing and Validating Logrotate with Dry Runs

Never wait until an outage to discover a syntax error in your logrotate configuration. Test your rules safely using the debug flag:

sudo logrotate -d /etc/logrotate.d/myapp

The -d (debug) flag performs a comprehensive dry run. It outputs exact actions logrotate would take—including file checks, permission assignments, and command executions—without actually altering, moving, or compressing any files.

Forcing an Immediate Rotation

If you wish to test live file rotation immediately without waiting for the daily timer, use the -f (force) flag:

sudo logrotate -f /etc/logrotate.d/myapp

Verify that your log was rotated by listing directory contents:

ls -la /var/log/myapp/

You should see the original log renamed to app.log.1 alongside a fresh, empty app.log file with correct permissions.

Essential Logrotate Directives Reference

Directive Function Typical Application
size 50M Rotates as soon as file exceeds 50MB, regardless of schedule High-traffic API endpoints
copytruncate Copies log and truncates original in place Apps that cannot release file handles on reload
maxsize 500M Enforces rotation if size is breached before daily cycle Runaway error prevention
dateext Appends YYYYMMDD date format instead of integer numbers Compliance and audit logging

Troubleshooting Common Logrotate Failures

If logs fail to rotate or processes stop logging, check these frequent issues:

  • Insecure File Permissions: Logrotate rejects configuration files that have loose permissions. Ensure your file inside /etc/logrotate.d/ is owned by root:root and has permissions 0644.
  • Process Holds File Handle: If new logs remain empty while the old rotated log continues growing, the application was not signalled to reopen its file handle. Add a proper postrotate reload command or use copytruncate.
  • Checking Systemd Timer Status: Confirm that the automated daily trigger is active by checking systemctl status logrotate.timer.

Establishing automated log rotation policies ensures your Ubuntu servers maintain consistent storage headroom, smooth diagnostic logging, and optimal performance across long-term deployments.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.