Logrotate切割后应用写入失败的主因是新日志属主/权限不匹配:需在配置中显式用create 640 user group指定权限与属主,并验证目录权限、SELinux上下文及强制ACL影响,再通过logrotate -vf手动测试确认。

Logrotate 切割日志后应用写入失败,常见原因之一是新生成的日志文件属主/权限与原文件不一致,导致应用进程(如 nginx、tomcat、自定义服务)因无写权限而静默丢弃日志。这类问题通常不报错,但日志“突然停止增长”,排查需聚焦权限链和 logrotate 行为逻辑。
确认日志文件属主是否被意外重置
logrotate 默认使用 create 指令创建新日志时,会按配置指定属主和权限;若未显式设置,将继承运行 logrotate 的用户(通常是 root)并使用默认 umask(如 0022 → 权限 644),而非原始日志的属主。这会导致:应用以非 root 用户(如 www-data、tomcat、appuser)运行,却无法写入属主为 root:root、权限为 644 的新日志文件。
- 对比切割前后的文件信息:
ls -l /var/log/myapp.log(切割前)ls -l /var/log/myapp.log.1 /var/log/myapp.log(切割后) - 重点检查:
– 新日志(myapp.log)的属主是否变成 root
– 是否缺失写权限(如权限为 644,但应用用户不是 owner 或 group)
检查 logrotate 配置中是否明确声明 create 参数
在对应配置文件(如 /etc/logrotate.d/myapp)中,必须显式用 create 指定新日志的属主、属组和权限,否则 logrotate 不保证还原原始状态。
- 正确写法示例:
/var/log/myapp.log {<br> daily<br> missingok<br> rotate 7<br> compress<br> delaycompress<br> create 640 appuser appgroup # ← 关键!指定权限、用户、组<br> copytruncate<br>} - 注意:
–create后三个字段顺序固定:权限 mode、用户 user、组 group
– 若应用以appuser身份运行,且日志目录属组为appgroup,则设为640+appuser appgroup最稳妥
– 避免只写create(无参数),它会使用默认 600 权限且属主 root
验证日志目录本身的权限和继承机制
即使 logrotate 正确设置了新日志属主,若其所在目录不具备相应写入能力,或存在 ACL/SELinux 干预,仍可能失败。
- 检查日志目录权限:
ls -ld /var/log/myapp/
确保appuser对该目录有 w(写)和 x(执行,即进入权限) - 若启用 SELinux(常见于 CentOS/RHEL):
– 日志目录需有var_log_t类型上下文,否则 logrotate 创建文件后,应用可能因策略拒绝写入
– 执行:chcon -Rv --type=var_log_t /var/log/myapp/
– 验证:ls -Z /var/log/myapp/应显示system_u:object_r:var_log_t:s0 - 检查是否存在强制 ACL(如 setfacl 设置的默认 ACL),可能覆盖 logrotate 的 create 行为
复现并观察完整轮转过程
避免依赖“等明天自动触发”,用强制轮转 + 日志监控快速定位:
- 手动触发并跟踪:
logrotate -vf /etc/logrotate.d/myapp
加-v显示详细步骤,加-f强制执行,观察输出中是否提示权限错误或 create 失败 - 轮转后立即验证:
– 查看新日志属主/权限是否符合预期
– 切换到应用用户,测试写入:sudo -u appuser sh -c 'echo "test" >> /var/log/myapp.log'
– 检查应用进程是否仍在向该文件写入(lsof -p $(pgrep -f myapp) | grep log) - 若应用使用
copytruncate,注意它不依赖新文件属主——而是直接清空原文件。此时属主变化不影响写入,但要确认copytruncate确实生效(适合无法重启服务的场景)


















