
Laravel日志切single模式需将default设为single、确保single通道驱动为single且path可写;daily驱动通过days控制保留天数,文件名由RotatingFileHandler固定生成;自定义通道需独立配置driver和path,并用tap注入Formatter;LOG_LEVEL限制输出等级,生产环境默认error级不输出debug。
Laravel 默认用的是 stack 通道,背后其实是 daily 驱动 —— 想要单文件日志或自定义格式,不能只改 config/logging.php 里的 default,得同步调整驱动、通道、处理器和日志路径权限。
single)模式默认的 daily 每天一个文件,适合生产;但开发调试时想 grep 全量日志,single 更直接。关键不是换驱动,而是确保通道不走 stack 套娃:
config/logging.php 中把 'default' => 'single'
'single' 通道存在且驱动为 'single',不是嵌套在 stack 里'path' 必须可写,比如 storage/logs/laravel.log,Laravel 不会自动创建父目录APP_ENV=local 却没生效,检查 .env 是否被 php artisan config:clear 清过缓存return [
'default' => 'single',
'channels' => [
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
],
];
daily)的保留天数和文件名控制daily 驱动默认只保留 7 天日志,且文件名带日期后缀(如 laravel-2025-06-15.log),但命名和清理逻辑藏在 Monolog\Handler\RotatingFileHandler 里,Laravel 只暴露了有限配置:
'days' 控制保留天数,设为 30 就留一个月,设 0 表示不删除旧文件'filename' 不能直接改——daily 固定用 date() 拼接,想自定义前缀只能重写 Handler
2025-06-15.log 可能一直空着,直到第一条日志写入storage/logs/ 权限不足,PHP 进程无法创建新文件'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 30,
],
payment)并指定格式业务敏感操作(如支付、退款)需要单独归档、结构化记录,不能混在主日志里。Laravel 支持用 tap 扩展处理器,但更稳的方式是注册独立通道 + 自定义 Formatter:
config/logging.php 新增通道,driver 用 single 或 daily,'path' 指向专用路径(如 storage/logs/payment.log)'tap' 数组注入自定义类,该类必须实现 __invoke 方法,接收 Logger 实例tap 类中调用 $logger->getHandlers()[0]->setFormatter(...) 替换格式器,比如用 LineFormatter 输出 JSONLog::channel('payment')
->info('order_paid', ['order_id' => 123]);,别用 Log::info(),否则走默认通道use Monolog\Formatter\LineFormatter;
return [
'channels' => [
'payment' => [
'driver' => 'single',
'path' => storage_path('logs/payment.log'),
'level' => 'info',
'tap' => [App\Logging\CustomPaymentFormatter::class],
],
],
];
Log::debug() 在生产环境不输出不是代码问题,是 LOG_LEVEL 环境变量或配置限制了最低输出等级。Laravel 的 level 是 Monolog 的级别,debug ,而生产环境默认 LOG_LEVEL=error:
.env 中 LOG_LEVEL=debug 是否生效,运行 php artisan tinker 后执行 config('logging.channels.stack.level') 看实际值LOG_LEVEL 只影响 stack 通道及其子通道,单独定义的 single 通道需显式设 'level' => 'debug'
syslog 或 papertrail 驱动,debug 级日志可能被远程服务过滤,本地 storage/logs/ 里反而看不到LOG_LEVEL,得去服务器环境变量里确认真正难调的从来不是配哪个 driver,而是当 storage/logs/ 权限不对、LOG_LEVEL 被多层覆盖、或者自定义 tap 类抛了异常却没日志可查时,连问题出在哪都摸不到。先跑通 php -r "error_log(\Log::channel('single')->getLogger()->getLevel());",再动其他。