日志写入失败主因是权限或驱动类型错误:runtime/log目录及父目录需对Web用户可写;log.level须不低于日志级别;type必须为file等落盘驱动;file_size=0才按天滚动。

日志写入失败:先查 runtime/log 目录是否可写
绝大多数写入失败不是配置问题,而是目录权限卡死。ThinkPHP 默认把日志写进 runtime/log,这个路径必须对 Web 进程用户(如 www-data、nginx 或 apache)有写权限,且父目录 runtime 也得可写——否则连日志文件都创建不了。
- 用
ls -ld runtime log看权限,确认属组和权限位(常见应为drwxr-xr-x或更宽松,但不能是drwx------) - 别只改
log目录权限,runtime本身也要可写,否则Log::write()会静默失败 - 线上环境禁用
chmod 777,推荐用chown -R www-data:www-data runtime+chmod -R 755 runtime - 如果用 Docker,确保挂载卷的 UID/GID 与容器内 Web 用户一致,否则权限照样失效
log.level 配置低于实际触发级别,日志就“消失”了
ThinkPHP 日志默认只记录 error 及以上级别,如果你在代码里调用 Log::info('xxx') 却没看到日志,大概率是 log.level 设成了 'error' 或 'notice',而 info 比它低。
- 配置位置通常在
config/log.php,关键项是'level' => 'error',可选值包括'debug'、'info'、'notice'、'warning'、'error'、'critical' - 开发环境建议设为
'debug';生产环境至少设为'warning',避免info类日志刷爆磁盘 - 注意:级别是“最低记录门槛”,
level => 'warning'表示只记warning、error、critical,不记info - 如果用了多通道(如文件+邮件),每个通道可单独配
level,别只改全局配置却漏掉通道级覆盖
日志驱动切换成 trace 或 test 后,根本不会落盘
ThinkPHP 支持多种日志驱动,但 'type' => 'trace' 和 'type' => 'test' 是调试用的内存驱动,它们不写文件,只存到内存或 Trace 面板里。线上误配成这两个,日志就“凭空消失”。
- 确认
config/log.php中'type'值是'file'(默认)或'socket'等真实落盘驱动 -
trace驱动只在开启调试模式(app_debug = true)时生效,且仅用于内置 Trace 页面,和日志文件无关 - 如果想看实时日志又不想刷盘,可用
'type' => 'socket'配合tail -f,但需额外起服务监听,别指望它自动写文件 - 用
Log::getLog()可查当前所有未刷新的日志条目,适合验证是否真被丢弃,还是只是没 flush
日志文件名含日期但没按天滚动?检查 log.file_size 和 log.time_format
ThinkPHP 的文件驱动默认按日期生成文件(如 20240615.log),但“按天滚动”不是靠文件名决定的,而是靠 log.file_size 是否为 0:设为 0 才启用日期分割;非零值则按大小切分,日期名就失效了。
-
'file_size' => 0:启用日期命名,每天一个新文件(如20240615.log) -
'file_size' => 10485760(10MB):无视日期,写满就切xxx_1.log、xxx_2.log -
'time_format' => 'Y-m-d'只影响文件名格式,不影响滚动逻辑,别以为改了它就能按天切 - 大流量项目慎用
file_size => 0,因为每天零点会新建文件,若日志量突增,可能瞬间创建多个句柄,触发系统限制
日志写不进文件,90% 是权限或驱动类型搞错;剩下那 10%,往往卡在 file_size 和 level 这两个看似不起眼的开关上。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










