日志驱动应按滚动需求选daily或single:daily每天新建文件,生产环境更稳妥;single只追加到单文件,适合调试。daily支持days配置保留天数,single不支持但可配permission。

日志驱动配成 single 还是 daily?看滚动需求
选错驱动会导致日志不写、文件不轮转,甚至磁盘被撑爆。single 只往一个文件里追加,适合调试或低流量场景;daily 每天新建文件(如 laravel-2024-06-15.log),生产环境更稳妥。别图省事全用 single,尤其在有定时任务或高并发写入时,单文件锁竞争会拖慢请求。
-
DAILY驱动默认保留 7 天日志,通过days配置项调整,比如'days' => 30 -
SINGLE不支持days,但可配'permission' => 0644避免权限问题导致写入失败 - 如果用
stack驱动(多通道聚合),各子通道仍需单独指定daily或single
怎么把日志写进自定义路径的文件?改 path 不够,还得过权限关
只改 config/logging.php 里的 'path' => storage_path('logs/my-app.log') 常常没用——Laravel 默认只认 storage/logs/ 下的路径,且 PHP 进程得有写权限。更可靠的做法是:用 daily 驱动 + 自定义 path,再确保目录存在且可写。
- 手动创建目录并赋权:
mkdir -p /var/log/my-laravel-app && chown www-data:www-data /var/log/my-laravel-app - 配置中路径必须用绝对路径,相对路径(如
../logs/custom.log)会被 Laravel 忽略 - 若用
syslog或papertrail等远程驱动,path参数无效,别白折腾
LOG_CHANNEL 环境变量和 config/logging.php 冲突怎么办?
环境变量优先级高于配置文件。比如 .env 里写了 LOG_CHANNEL=stderr,哪怕你在 logging.php 把 stack 设为默认,实际生效的仍是 stderr。调试时先 dd(config('logging.default')) 看真正加载的是哪个 channel。
- 本地开发想用
single,生产用daily,别硬编码,靠.env切:LOG_CHANNEL=daily - 自定义 channel 名称必须在
logging.php的'channels'数组里明确定义,否则报错Log driver [xxx] is not defined - 运行
php artisan config:clear后,.env修改才生效,缓存不刷新就永远读不到新值
日志内容空、格式乱、没上下文?检查 tap 和 context 的用法
默认日志只有消息体,没 trace、没请求 ID、没用户 ID。想补全,得靠 tap 数组引入自定义 Monolog 处理器,而不是在业务代码里拼字符串。
- 在 channel 配置里加
'tap' => [App\Logging\AddRequestContext::class],类里实现__invoke方法塞$logger->pushProcessor(...) - 业务中记录带上下文的日志:用
Log::info('Order processed', ['order_id' => $id, 'user_id' => auth()->id()]),别用Log::info("Order processed, order_id: $id") - JSON 格式日志要设
'formatter' => Monolog\Formatter\JsonFormatter::class,但注意JsonFormatter会把所有 context 转成 JSON,含对象时可能抛异常
php -r "var_dump(config('logging.channels.daily'));" 看最终结构,比猜强得多。











