logrotate Configuration: Directives and Troubleshooting - 夜莺博客

logrotate Configuration: Directives and Troubleshooting

A log file that never rotates will eventually fill a filesystem at three in the morning, and the service writing it is usually the one that matters. logrotate is the standard answer on Linux, but its defaults are conservative and its behaviour depends on directives that interact in non-obvious ways — especially when the application keeps a file descriptor open. This article covers the directive set you actually need, the copytruncate trade-off, and how to test a configuration safely.

The basic stanza

/var/log/myapp/*.log {
    daily
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    create 0640 myapp adm
    sharedscripts
    postrotate
        systemctl reload myapp >/dev/null 2>&1 || true
    endscript
}
  • rotate 14 keeps 14 old versions before deleting; 0 removes old versions immediately, -1 never removes them (watch disk usage).
  • missingok stops logrotate complaining when the wildcard matches nothing on first run.
  • notifempty skips rotation of zero-byte files — useful for noisy wildcard sets.
  • sharedscripts runs the postrotate script once for the whole wildcard set rather than once per file.

Time or size, not both in the same way

daily | weekly | monthly | yearly
size 100M
maxsize 500M
minsize 10M
maxage 90

Time-based and size-based directives combine as "rotate when either is true". maxsize is the more useful control on busy services: it forces a rotation when a log grows past a ceiling even if the time interval has not elapsed. maxage removes rotated files older than a number of days regardless of rotate.

The copytruncate trade-off

By default logrotate renames the old log and asks the application to reopen its logfile (via create plus a postrotate reload). When an application cannot be told to close its file, copytruncate copies the file and then truncates the original in place:

/var/log/app/access.log {
    daily
    rotate 7
    copytruncate
    compress
}

Two consequences to accept deliberately. There is a very small window between the copy and the truncate, so a few log lines can be lost — a real problem for audit logs. And when copytruncate is used, create has no effect because the old logfile stays in place. Also note that copy or copytruncate is required if you want to use olddir across different filesystems, since a plain rename cannot cross devices.

Dated archives

dateext
dateformat -%Y%m%d
dateyesterday

dateext names archives with a date extension instead of a number, which makes retention and compliance reporting far easier. The date string must be lexically sortable — year first, then month, then day — because logrotate sorts rotated filenames to decide which are oldest. dateyesterday uses yesterday's date so the filename matches the timestamps inside a log rotated just after midnight.

Testing before you trust it

# verify the config and see what would happen
logrotate -d /etc/logrotate.d/myapp

# force a rotation now, ignoring the time interval
logrotate -f /etc/logrotate.d/myapp

# check the last run state
cat /var/lib/logrotate/logrotate.status

-d is a dry run that prints every decision — which files match, whether the time condition is met, which postrotate script would run. Always dry-run a new stanza before adding it to production cron or a systemd timer. If a log is not rotating despite a correct stanza, the state file usually shows the file was already processed in the current interval.

Common failures

  • Log continues growing after rotation — the service never reopened the file. Add a postrotate systemctl reload, or switch to copytruncate if the daemon cannot be signalled.
  • Permission denied on the rotated file — create must specify owner and group that the service can reopen, and the postrotate script runs as root, so file modes must match what the daemon expects.
  • Wildcard stanza skips files — logrotate refuses to rotate files whose parent directory is group-writable for security reasons, and a config file must not be group-writable to be read at all.
  • Disk still fills — compressed archives of a log that grows faster than the rotation interval will still consume space. Combine maxsize with a centralised collector rather than increasing rotate.

See also: forwarding logs to a central rsyslog server, recovering a full overlay2 filesystem, and systemd timers for scheduled jobs.

原文链接:https://www.man7.org/linux/man-pages/man8/logrotate.8.html