绝大多数情况不是配置没开,而是reload逻辑卡死或权限/路径错位导致postrotate阶段异常退出;应检查日志是否重命名、新日志是否写入、磁盘空间是否释放,并用logrotate -d确认skipping或stat failed。

宝塔 Nginx 日志切割失败,**绝大多数情况不是配置没开,而是 reload 逻辑卡死或权限/路径错位导致 postrotate 阶段异常退出**。直接看日志文件是否被重命名、新日志是否继续写入、磁盘空间是否释放,比查“有没有启用切割”更有诊断价值。
logrotate 执行后日志没重命名,postrotate 段根本没跑
常见现象:/www/wwwlogs/example.com.log 始终存在且持续增长,看不到 example.com.log-20260907 这类文件。
- 检查
/www/server/panel/vhost/logrotate/nginx文件里postrotate是否被注释或语法错误(比如漏了endscript) - 确认该文件权限为
644,且属主是root;若被改成www或其他用户,logrotate 会静默跳过执行 -
postrotate中的命令必须用绝对路径:/bin/kill而非kill,/www/server/nginx/sbin/nginx而非仅nginx - 如果用了
sharedscripts却只配了单个站点路径,logrotate 可能因匹配不到任何文件而跳过整个块
日志重命名了,但新日志不写入,access.log 变成空文件
这是最典型的权限+信号组合故障:旧文件被 mv,新文件创建失败,USR1 也发不出去。
-
create 644 www www必须存在且www用户真实存在——宝塔默认 Nginx 工作用户是www,不是www-data或nginx - 确认
/www/wwwlogs/目录本身权限是755,且属主为www;否则即使 create 写对了,mkdir 失败也会让新日志无法落地 -
kill -USR1发送目标必须是 master 进程 PID:/www/server/nginx/logs/nginx.pid文件必须存在且可读;若用ps aux | grep nginx提取 PID,极易误杀 worker 进程 - 如果 Nginx 是 systemd 启动(宝塔 7.9+ 默认),
kill -USR1 $(cat /www/server/nginx/logs/nginx.pid)仍有效,但不要混用systemctl reload nginx——它会阻塞数秒甚至失败
日志重命名了、新日志也在写,但磁盘空间不释放
说明有 worker 进程仍在往已被 mv 的旧文件写入,典型句柄未释放问题。
- 运行
lsof +L1 | grep wwwlogs,若输出类似nginx 12345 www 10w REG 8,1 123456789 /www/wwwlogs/example.com.log (deleted),证明 fd 悬挂 - 此时不能删、不能 gzip 被标记为
(deleted)的文件;应先确保 USR1 已生效,再等几秒观察lsof输出是否清空 - 高并发下 USR1 可能延迟响应,建议在
postrotate里加简单轮询:sleep 0.3 && lsof -p $(cat /www/server/nginx/logs/nginx.pid) | grep -q 'access\.log' || true - 长期规避方案:改用
copytruncate模式(需 logrotate 支持),它 truncate 原文件而非 mv,Nginx fd 始终有效
宝塔后台显示“已启用日志切割”,但实际没生效
宝塔的“启用日志切割”只是开关,背后依赖三处独立配置,任一环节断链都会失效。
- 面板设置只是生成
/www/server/panel/vhost/logrotate/域名文件,不保证该文件被 logrotate 加载——需确认/etc/logrotate.d/下有软链或内容已同步 - 系统级 logrotate 默认只跑
/etc/cron.daily/logrotate,若服务器凌晨离线,当天任务就丢;宝塔计划任务中“强制执行 logrotate”才是兜底手段 - 若手动改过
/www/server/panel/vhost/logrotate/nginx,宝塔升级可能覆盖它——真正稳定的做法是新建独立规则如/etc/logrotate.d/bt-custom并禁用宝塔内置切割 - 宝塔自带切割只管
/www/wwwlogs/域名.log和.error.log,完全不碰/www/server/panel/logs/或/www/server/nginx/logs/error.log,别指望它“全包”
真正难排查的点在于:logrotate 错误通常不报错,只默默跳过。务必用 logrotate -d 跑一次 debug 模式,盯着输出里有没有 skipping 或 stat failed 字样——这才是第一手证据。











