Where to start First steps track · 15 stages
Linux Labs

Log rotation with logrotate

4 min Ubuntu 24.04

Keeping logs from filling the disk — rotation, compression, retention, checking configs.

Cheat sheet

3 commands Printable version
  • sudo logrotate -d /etc/logrotate.conf dry run (changes nothing)
  • sudo logrotate -f /etc/logrotate.d/nginx force it now
  • cat /var/lib/logrotate/status rotation history

Overview

Text logs under /var/log (nginx, apache, custom apps) grow and can fill the disk. logrotate periodically renames, compresses and deletes old logs. It runs on a systemd timer (logrotate.timer).

The systemd journal (journalctl) is rotated separately, with its own limits — logrotate doesn't touch it.

Configuration

7

Globally in /etc/logrotate.conf, per service in /etc/logrotate.d/<service>:

/var/log/myapp/*.log {
    daily                 # how often (daily/weekly/monthly) — or size 100M
    rotate 14             # keep 14 copies
    compress              # compress old ones (.gz)
    delaycompress         # don't compress the most recent rotated file (still being appended to)
    missingok             # fine if the log is missing
    notifempty            # don't rotate empty files
    dateext               # date suffix (file-20260101) instead of .1
    create 0640 myapp myapp   # create a new log with these permissions/owner
    su myapp myapp            # run as this user (if the directory isn't root's)
    sharedscripts             # run postrotate once for all files in the pattern
    postrotate
        systemctl reload myapp >/dev/null 2>&1 || true
    endscript
}

Directives

Directive Meaning
daily/weekly/monthly the period
size 100M rotate by size (instead of, or together with, the period)
rotate N how many copies to keep
compress/delaycompress compress / defer compression by one cycle
copytruncate copy and truncate (if the service can't reopen its log file)
postrotate…endscript a command to run after rotation (reload the service)
maxage N delete files older than N days

postrotate (reload/reopen) or copytruncate is required for the service to start writing to the new file.

Nothing found. Try a shorter query.

Recipes

1

Commands

bash
sudo logrotate -d /etc/logrotate.conf     # debug/dry-run: what it WOULD do (no changes)
sudo logrotate -v /etc/logrotate.conf     # a verbose run
sudo logrotate -f /etc/logrotate.d/nginx  # FORCE rotation now
cat /var/lib/logrotate/status             # when each file was last rotated
systemctl status logrotate.timer          # is the timer active

Troubleshooting

4

The log keeps growing, no rotation happens

  • Is there a config in /etc/logrotate.d/? logrotate -d (dry-run) shows whether the file is picked up.
  • Is the timer active? systemctl status logrotate.timer.
  • An error in one config file blocks the rest — check the output of -d or journalctl -u logrotate.

After rotation the service keeps writing to the old (deleted) file

There's no postrotate with a reload, and no copytruncate. The service holds the old file descriptor open, so the space isn't freed (see disk-usage: lsof +L1). Add a reload or copytruncate.

"error: skipping … because parent directory has insecure permissions"

logrotate is complaining about permissions/ownership of the log directory. Add su user group to the block.

The disk is already full of logs

Urgent fix: run logrotate -f manually, compress or delete old files; then set up proper rotation and limits (disk-usage).

See also

  • journalctl — Reading the systemd journal (journald) — filters by service, time, priority.
  • disk-usage — Where the space and inodes went — df, du, finding large files, gotchas.
Loading…