返回 Skill 列表
extension
分类: 开发与工程无需 API Key

logrotate

logrotate日志文件轮转管理:配置语法、轮转频率、压缩、后轮转脚本、应用程序信号处理、故障排除轮转失败以及状态文件检查。触发条件包括:logrotate、日志轮转、日志文件轮转、日志增长、轮转日志、logrotate.conf、/etc/logrotate.d、copytruncate、postrotate、日志清理、日志归档。

person作者: jakexiaohubgithub

Identity

  • Binary: /usr/sbin/logrotate
  • Config: /etc/logrotate.conf
  • Drop-in dir: /etc/logrotate.d/ (each file rotates one or more applications)
  • State file: /var/lib/logrotate/status (tracks last rotation time per log path)
  • Scheduler: run daily via /etc/cron.daily/logrotate or logrotate.timer (systemd)
  • Distro install: apt install logrotate / dnf install logrotate

Key Operations

| Operation | Command | |-----------|---------| | Test config (dry-run, verbose) | logrotate -d /etc/logrotate.conf | | Test a specific drop-in config | logrotate -d /etc/logrotate.d/nginx | | Force rotation now (ignore schedule) | logrotate -f /etc/logrotate.conf | | Force-rotate a single config | logrotate -f /etc/logrotate.d/myapp | | Run with verbose output | logrotate -v /etc/logrotate.conf | | Combine force + verbose | logrotate -vf /etc/logrotate.conf | | Check state file (last rotation times) | cat /var/lib/logrotate/status | | Show last rotation for one log | grep myapp /var/lib/logrotate/status | | Validate config syntax only | logrotate --debug /etc/logrotate.conf | | Run as a specific user | sudo -u www-data logrotate -f /etc/logrotate.d/myapp | | Check systemd timer status | systemctl status logrotate.timer |

Expected State

  • State file updated daily; each line shows "<path>" <ISO-date>
  • Daily cron or systemd timer runs without error output (silent on success)
  • Rotated files named app.log.1 (numbered) or app.log-YYYYMMDD (dateext)
  • Compressed files have .gz suffix when compress is set

Health Checks

  1. logrotate -d /etc/logrotate.conf 2>&1 | grep -i error — no output means config is valid
  2. stat /var/lib/logrotate/status — confirm file exists and mtime is recent (within 24–48h)
  3. grep -r 'error\|warning' /var/log/syslog | grep logrotate — no recent failures in syslog

Common Failures

| Symptom | Likely cause | Check/Fix | |---------|-------------|-----------| | error: error opening /var/log/app.log: Permission denied | logrotate runs as root but postrotate script or create mode doesn't match log owner | Run ls -la /var/log/app.log; add su <user> <group> directive to config block | | postrotate script failed | postrotate command exits non-zero (e.g., service not running, wrong path) | Run the postrotate command manually; check $?; add sharedscripts to avoid re-running on each matched file | | unknown option or config parse error | Typo or unsupported directive in config file | Run logrotate -d /etc/logrotate.d/<file> and read the error line number | | Rotation not happening despite age | Log path glob doesn't match actual file path | Run logrotate -vd and look for "no matches" or "skipping" messages; fix glob in config | | .gz file is corrupted or missing | Compress fails because gzip not installed, or disk full | Check which gzip; check df -h; try running logrotate -f and observe stderr | | Application keeps writing to old inode after rotation | Missing or broken postrotate reload signal | Add postrotate ... endscript with SIGHUP or restart; alternatively use copytruncate | | Old rotated files not being deleted | rotate count too high, or maxage not set | Check rotate N value; add maxage 30 to remove files older than 30 days | | stat of /var/lib/logrotate/status failed | State file missing or wrong path | Create with touch /var/lib/logrotate/status; check if alternate state path is set with -s |

Pain Points

  • Applications must reopen their log file descriptor after rotation. Rotation renames the file; a running process keeps writing to the old inode (now .log.1). Fix: postrotate block sending SIGHUP (or equivalent) to reload the app, or use copytruncate as a fallback.
  • copytruncate risks losing log lines. It copies the current log then truncates the original in two steps. Log lines written between copy and truncate are silently lost. Use SIGHUP-based rotation when the application supports it.
  • delaycompress is required when the application is still writing to .log.1. Without it, logrotate compresses .log.1 immediately while the app may still hold it open (especially relevant with postrotate that only restarts, not reloads).
  • Daily rotation runs via cron.daily, not at a precise time. The actual run time depends on when cron.daily fires (commonly 06:25 on Debian systems). Logs are not rotated in real time; a 1 GB log can accumulate between runs.
  • dateext makes filenames substantially clearer than numbered suffixes. Numbered rotation (app.log.1, .2) shifts all existing files on each run, making timestamp-based grep harder. dateext with dateformat -%Y%m%d avoids this and prevents name collisions.
  • sharedscripts is almost always wanted for glob patterns. Without it, postrotate runs once per matched file, potentially sending SIGHUP dozens of times to the same process.

References

See references/ for:

  • logrotate.conf.annotated — full config with every directive explained, nginx and custom app examples
  • docs.md — man pages, upstream documentation, and community resources