error_log()写不到指定文件主因是参数非3、路径非绝对或目录无写权限;需用error_log($msg, 3, $abs_path),确保目录存在、www-data可写且手动加换行符。

error_log() 写不到指定文件?八成是没传对参数或路径权限不对。直接用它写生产日志不推荐,但它是理解 PHP 日志机制最短的上手路径。
为什么 error_log($msg, 3, $path) 没生成日志
这不是函数失效,而是三个常见硬伤同时出现:
— 第二个参数不是 3:传 0 或省略,日志就进了 Web 服务器错误日志(比如 Apache 的 error_log),根本不会碰你给的 $path
— 路径不是绝对路径:用 ./logs/app.log 或 logs/app.log,PHP 不报错但静默失败;必须写成 /var/log/myapp/app.log
— 目录不存在或权限不足:error_log() 不创建父目录,只尝试写文件;Web 进程用户(如 www-data)必须对整个路径有写权限,建议用 ls -ld /var/log/myapp 确认
file_put_contents() 并发写日志丢数据的根本原因
它默认不是线程安全的——多个请求同时执行 file_put_contents($f, $msg, FILE_APPEND),可能触发竞态:内容错位、覆盖、甚至整行消失。
必须加 LOCK_EX:file_put_contents($path, $line, FILE_APPEND | LOCK_EX)
— FILE_APPEND 保证追加,LOCK_EX 强制排他锁,写完自动释放
— 不要只加 FILE_APPEND,这是线上丢日志最常被忽略的一行
— 返回值是写入字节数,失败返回 false,简单判断一下比盲目信任更稳妥
什么时候该放弃裸写,自己封装一个最小日志工具
当项目里开始反复出现这些信号:
— 每次写日志都要手动拼 date('Y-m-d H:i:s') 和换行符 \n
— 不同脚本里日志路径不一致,有的写 ./log/,有的写 /tmp/,迁移时全得改
— 开发时想看屏幕输出,生产只想写文件,但又不想改一堆 echo + error_log()
— 日志文件越来越大,某天发现 app.log 已经 2.3GB,tail -n 100 都卡住
一个够用的封装只要 15 行左右:用静态方法统一入口,路径从配置读,时间戳和换行自动加,轮转逻辑只检查文件修改时间是否超 24 小时 + rename() 即可,不必一上来就拉 Monolog
Monolog 是不是“必须”引入
不是。它的价值在「扩展性」,不在「能不能写」:
— 如果你只需要按级别(info/warning/error)过滤日志,且未来可能对接 Slack、Syslog 或 Elasticsearch,那值得引入
— 如果只是单机小项目,日志只写文件、不轮转、不发告警,error_log() 配合合理路径和权限,完全扛得住
— Composer 安装后,Logger 实例 + StreamHandler 两行就能跑起来,但别忘了:它不解决路径权限问题,也不自动建目录,该配的还是得配
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











