logrotate配置文件默认在/etc/logrotate.conf,服务规则存于/etc/logrotate.d/;修改后由cron自动生效,调试可用sudo logrotate -d手动验证。

logrotate 配置文件写在哪、怎么加载
logrotate 不是开箱即用的守护进程,它靠 cron 定期调用 logrotate 命令执行轮转逻辑。默认配置在 /etc/logrotate.conf,所有全局策略(如保留几份、是否压缩)都从这里继承;具体服务的日志规则放在 /etc/logrotate.d/ 下的独立文件里,比如 /etc/logrotate.d/nginx。
修改后无需重启服务或重载 daemon——下一次 cron 触发时自动生效。但调试阶段建议手动运行验证:
sudo logrotate -d /etc/logrotate.d/myapp
-d 是 debug 模式,只打印执行步骤不真正操作,适合检查路径、条件是否匹配。
日志文件没被轮转?先看匹配路径和权限
常见现象是配置写了,但日志始终不切割。最常踩的坑是路径没写对,或者 logrotate 进程没权限读取日志文件或其父目录。
检查点列出来:
-
logrotate默认以 root 身份运行,但如果日志文件属主是www-data且父目录权限是drwx------(仅属主可进入),logrotate 就进不去目录,直接跳过该规则 - 通配符路径如
/var/log/myapp/*.log不会递归匹配子目录,要多级就写/var/log/myapp/**/*.log(需 logrotate ≥ 3.18 + shell 支持 globstar,更稳妥是单独列路径) - 如果日志路径含变量或软链接,logrotate 默认解析的是目标文件,不是链接本身;若想按链接路径轮转,得加
copytruncate或用create配合olddir
weekly vs size 触发条件冲突怎么办
logrotate 同时声明 weekly 和 size 100M 时,只要任一条件满足就会触发轮转——不是“必须同时满足”。这点容易误解。
但要注意顺序和副作用:
-
size判断基于当前日志文件大小,单位可以是k、M、G;注意别写成100MB(会当成 100 字节) -
weekly实际是“每周第一次运行时检查”,具体哪天取决于 cron 的执行时间(通常是每天06:25),不是严格按日历周重置计时器 - 如果日志增长极快,可能一天内多次触发
size,此时rotate 4表示最多保留 4 个归档,旧的会被立刻删除,不是等满 4 个才删最老的
rotate 后应用还在往旧文件写?用 copytruncate 或 reopen
轮转后常见问题:日志文件名变了(如 app.log → app.log.1),但应用进程仍持有原文件描述符,继续往 app.log.1 写——导致新日志进错位置,原 app.log 始终为空。
两种主流解法:
-
copytruncate:先复制内容再清空原文件,应用无感知,但有极小概率丢最后一段日志(复制和截断之间) -
postrotate ... endscript中调用kill -USR1或systemctl kill -s USR2 myapp.service,前提是应用支持重载日志句柄(Nginx、Redis、rsyslog 都支持)
别用 create 单独解决这个问题——它只控制新日志文件的权限和属主,不解决句柄残留。










