Skip to main content
RunBook Academy

LinuxVIII · Logging and journaldlogrotate

logrotate — the rotation policy

Intermediate⏱ ~10 minbashlogrotatecat

What you'll learn

  • Read and write logrotate configuration files
  • Distinguish rotation, compression, retention, and postrotate actions
  • Diagnose logrotate failures (most often: missing postrotate and copytruncate)
  • Configure rotation for a custom application log

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

logrotate runs (typically) daily via cron or a systemd timer, rotating text log files so they do not grow without bound. A misconfigured logrotate produces two failure modes: the disk fills with old logs, or the rotation breaks the application because it does not know to reopen the file.

Reading a logrotate config

Read-only / Safelogrotate nginx
$ cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}

Illustrative output

The directives

DirectiveMeaning
daily / weekly / monthly / yearlyRotation cadence
size 100MRotate when the file exceeds this size
rotate NKeep N rotated files before deleting
compressgzip rotated files
delaycompressSkip compression on the most recent rotation; compress on the next
nocompressNever compress
missingokSkip if the file does not exist (no error)
notifemptySkip if the file is empty
ifemptyForce rotation even if empty
create MODE OWNER GROUPCreate a new empty file with these attributes after rotation
nocreateDo not create a new file — the application must create one
copytruncateTruncate the original file in place after copying; use for applications that cannot be told to reopen
sharedscriptsRun postrotate once for all matched files (not once per file)
postrotateendscriptCommand to run after rotation
prerotateendscriptCommand to run before rotation
Read-only / Safelogrotate --debug
$ logrotate --debug /etc/logrotate.d/nginx 2>&1 | head -10
reading config file /etc/logrotate.d/nginx
Considering log file: /var/log/nginx/access.log
log file /var/log/nginx/access.log is empty, not rotating
Considering log file: /var/log/nginx/error.log
log file /var/log/nginx/error.log is empty, not rotating
...

Illustrative output

copytruncate — the application-friendly rotation

Read-only / Safecopytruncate
$ cat /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 7
compress
copytruncate
missingok
notifempty
}

Illustrative output

Common logrotate bugs

BugSymptom
Missing postrotate for an app that holds file descriptors openApplication writes to the rotated file; old log is gone, new file is empty
Missing create directiveNew empty file does not exist after rotation; application may fail to log
copytruncate without sufficient disk space for the copyRotation fails; log file grows unbounded
Missing delaycompress and the application reads the latest rotated fileApplication opens a compressed file it cannot read
rotate 0Log file is deleted after rotation — no retention
Read-only / Safedry run
$ logrotate -d /etc/logrotate.conf 2>&1 | tail -10
reading config file /etc/logrotate.conf
... considering /var/log/myapp/access.log
... rotating, keeping 7, compressing
... considering /var/log/myapp/error.log
... rotating, keeping 7, compressing
... considering /var/log/wtmp
... not rotating (no logs to rotate)

Illustrative output

Adding rotation for a custom log

sudo tee /etc/logrotate.d/myapp <<'EOF'
/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp myapp
    sharedscripts
    postrotate
        /usr/bin/systemctl reload myapp.service > /dev/null 2>&1 || true
    endscript
}
EOF

logrotate --debug /etc/logrotate.d/myapp

This rotates myapp’s logs daily, keeps 14 days, compresses with a one-day delay, creates a new file with the correct ownership, and reloads the service so it reopens the log file descriptor.

Knowledge check

Knowledge check · 3 questions

  1. Q1. What does `copytruncate` do?

  2. Q2. An application that holds its log file open keeps writing to the rotated file until something tells it to reopen.

  3. Q3. Which of the following are correct logrotate practices? Select all that apply.

Passing score: 75%. Answers are checked in this browser.