logrotate无需额外安装,但默认配置不适用具体服务,应直接修改/etc/logrotate.d/下专属配置文件;其运行依赖系统cron(如/etc/cron.daily/logrotate),非常驻进程,可通过ls、grep或systemctl list-timers验证是否启用。

logrotate 不需要额外安装,但默认配置往往不适用你的服务——直接改 /etc/logrotate.d/ 下的专属配置文件最稳妥,别碰 /etc/logrotate.conf 主文件。
怎么判断 logrotate 是否在运行
它靠系统级 cron 触发,不是常驻进程。检查是否启用:
-
ls -l /etc/cron.daily/logrotate—— 存在即表示每日自动触发 -
grep logrotate /var/lib/logrotate/status—— 查看最近一次轮转时间戳 -
systemctl list-timers | grep logrotate(较新系统)—— 确认 timer 是否 active
如果没反应,可能是 cron 服务停了,或该脚本被注释/删改过。别急着重装,先确认 cron 正常:systemctl status cron 或 systemctl status crond。
为什么 daily 配置没按时切割
logrotate 的时间判断依赖状态文件 /var/lib/logrotate/status,而这个文件只在真正执行轮转时才更新。常见陷阱:
- 首次配置后,
daily不会立刻生效——它要等到第二天 cron 运行时才检测“是否满 24 小时” - 如果日志文件为空(
notifempty默认启用),即使到时间也不会轮转 -
missingok会让 logrotate 忽略路径不存在的错误,但也掩盖了路径写错的问题(比如/var/log/nginx/access.log实际是/var/log/nginx/access.log拼错) - 权限问题:logrotate 以 root 身份运行,但 postrotate 脚本里若用
kill -USR1发信号给 nginx,需确保/var/run/nginx.pid可读,且 nginx 主进程由 root 启动(否则信号发不出去)
如何安全测试新配置不破坏线上服务
永远先用 -d(debug)和 -f(force)组合验证,而不是直接等 cron:
logrotate -d -f /etc/logrotate.d/myapp
这会模拟执行全过程,但不真正重命名、不压缩、不调用 postrotate,只输出每一步打算做什么。重点关注输出里的:
-
rotating pattern—— 是否识别出你的日志路径 -
switching to configuration file—— 是否加载了你刚写的配置 -
error:开头的行 —— 直接暴露语法或路径错误
确认无误后,再跑一次去掉 -d 的命令强制执行一次:logrotate -f /etc/logrotate.d/myapp,然后立刻检查:
- 原日志是否变为空(
copytruncate场景)或被重命名(create场景) - 新日志文件权限是否符合
create 0644 user group设置 - 服务是否仍在写日志(
tail -f原路径,看是否有新内容)
copytruncate 和 create 的选择关键点
二者解决的是不同场景下的“日志丢失”风险,不能混用:
-
copytruncate:适用于无法重启/重载的服务(如某些 Java 应用、自研守护进程)。它先拷贝当前日志,再清空原文件。风险在于拷贝和清空之间有毫秒级窗口,可能丢几行日志;优势是完全不中断服务。 -
create:标准做法,logrotate 把原日志重命名为.log.1,新建一个空日志文件。但前提是服务必须能响应postrotate里的信号(如kill -USR1让 nginx 重新打开文件),否则还会往旧文件(已重命名)里写,导致日志“消失”。 -
sharedscripts必须和postrotate配合使用——否则多个匹配的日志文件(如/var/log/myapp/*.log)会为每个文件单独执行一遍 postrotate,容易重复发信号或报错。
真正容易被忽略的是:无论选哪个,都得确认服务本身支持日志文件被外部移动或清空。有些程序会缓存 fd、不检查文件 inode 变化,这时只有 copytruncate 能保底,但你要接受那几毫秒的丢失概率。











