ThinkPHP 5.1 日志占满磁盘的根本原因是日志类型配置错误、缺乏大小限制与轮转机制。必须将 'type' => 'single' 改为 'daily',并设置 'max_file_size' => 5242880,删除无效的 'single' => true 和 'apart_level' 配置,确保 logrotate 使用 copytruncate 和 postrotate 刷新 PHP-FPM 句柄,清理脚本仅删 .log 文件且加锁防并发。

线上日志把磁盘占满,根本不是“日志太多”,而是没切通道、没设上限、没配轮转——ThinkPHP 5.1 的 daily 类型默认不控制单文件大小,single 类型压根不支持级别过滤,max_files 只管归档数量不管体积。靠改配置或手动删 runtime/log/ 目录,治标不治本。
ThinkPHP 5.1 日志类型必须从 single 切到 daily
很多项目卡在 'single' => true,以为“一个文件好管理”,结果所有 Log::debug() 全堆进 log.php 里,一天就能冲到 2GB+。5.1 版本下 single 模式完全忽略 log_level 配置,连 env('APP_DEBUG', false) 包裹都无效。
-
config/log.php中必须改成'type' => 'daily',否则level、max_file_size全部失效 - 同时补上
'max_file_size' => 5242880(5MB),否则即使 daily,单日仍可能生成超大文件(如高频接口打满 debug) - 删掉所有残留的
'single' => true和'apart_level'配置项——5.1 不支持按 level 分文件,写了也白写 - 确认
path是绝对路径(如/www/wwwroot/myapp/runtime/log/),相对路径在 CLI 任务里容易错位
logrotate 必须用 copytruncate + postrotate 刷新句柄
ThinkPHP 5.1 没有内置日志 reopen 机制,PHP-FPM 进程持有日志文件句柄,直接 mv 或 gzip 原文件会导致新日志继续写进已重命名的 .1 文件里——这就是为什么你配了 logrotate 却发现磁盘还是涨。
- 配置中必须包含
copytruncate:先复制内容再清空原文件,不中断写入 -
postrotate脚本不能省:kill -USR1 $(cat /www/server/php/74/var/run/php-fpm.pid 2>/dev/null) || true(路径按实际 PHP-FPM pid 文件调整) -
create 644 www www权限要对,宝塔环境用户组是www,Ubuntu 系是www-data,写错会导致新日志无法创建 - 测试时别等 cron:用
sudo logrotate -f /etc/logrotate.d/myapp强制触发,再ls -l runtime/log/看是否生成2026-07-07.log.1且权限正确
清理脚本要绕过 Log 类,直接删文件但保留结构
ThinkPHP 5.1 的 Log::clear() 只清内存缓存,runtime/log/ 下的文件它根本不碰。有人写 rm -rf runtime/log/*,结果删掉了日期子目录结构,下次写日志失败报错。
立即学习“PHP免费学习笔记(深入)”;
- 安全清理脚本只删
.log文件,不碰日期目录:find /www/wwwroot/myapp/runtime/log/ -name "*.log" -mtime +30 -delete - 如果用了
max_files => 30,TP 5.1 实际只在 daily 初始化时检查,不会自动删旧目录,得靠外部脚本 - 避免用
unlink遍历删除——大目录下 opendir/readdir 容易超时,find更稳 - 加锁防并发:
if [ -f /tmp/myapp_log_cleanup.lock ]; then exit; else touch /tmp/myapp_log_cleanup.lock; fi,跑完rm /tmp/myapp_log_cleanup.lock
最常被忽略的一点:logrotate 配置里的路径必须和 PHP 实际写入路径 100% 一致,少一个斜杠、多一个点,logrotate -d 输出里就会显示 skipping。别信文档写的“默认路径”,php -r "echo realpath('./runtime/log/');" 才是唯一真相。



















