laravel日志写不进storage/logs/主因是权限不足或log_channel配置为stderr;需确保storage目录可写、检查logging.php配置,并按环境设置log_channel与log_level。

日志写不进 storage/logs/ 是什么情况
默认情况下,Laravel 会把日志写到 storage/logs/laravel.log,但如果你发现文件没更新、目录为空或报错“Permission denied”,大概率是权限或驱动配置问题。
-
storage/目录必须对 Web 服务器用户(如 www-data、nginx 或 _www)可写,用chmod -R 775 storage/比直接 777 更安全 - 检查
config/logging.php中默认 channel 是否为'default' => env('LOG_CHANNEL', 'stack'),且stack的channels里包含daily或single - 如果用了
LOG_CHANNEL=stderr(常见于 Docker 容器),日志会输出到标准错误流,不会落盘——这不算故障,只是输出目标变了
怎么按环境切不同日志行为
Laravel 日志行为由 LOG_CHANNEL 和 LOG_LEVEL 环境变量控制,不是靠改代码分支来区分。
- 开发环境通常设
LOG_CHANNEL=stack+LOG_LEVEL=debug,stack默认聚合single和stderr,方便本地看和查 - 生产环境建议
LOG_CHANNEL=stack但把channels改成['daily'],避免单个日志文件无限膨胀;同时设LOG_LEVEL=error减少 I/O 压力 -
LOG_LEVEL不是越低越好:debug会记录 Query、Redis 调用等敏感信息,上线前务必确认是否开启
想记自定义内容,Log::info() 和 Log::channel('xxx')->info() 有什么区别
前者走默认 channel(通常是 stack),后者强制指定 channel,适用于需要隔离日志场景,比如审计日志单独存 ES、操作日志单独发 Slack。
- 先在
config/logging.php的'channels'里加一个新 channel,比如叫'audit',driver 设为'single','path'指向storage/logs/audit.log - 调用时用
Log::channel('audit')->info('user_id: '.$userId, ['action' => 'delete_post']),结构化数据会自动 JSON 化 - 注意:自定义 channel 不会自动继承
stack的处理器(如SlackWebhookHandler),要手动配或复用已有 handler
日志里看不到 SQL 查询,但 DB::enableQueryLog() 又太重
真正轻量的方案是改日志 level 和 DB 配置,而不是手动捞 query log。
- 确保
APP_DEBUG=true且LOG_LEVEL=debug,Laravel 会在 debug 级别自动记录慢查询和所有查询(只要没关log_queries) - 检查
config/database.php中对应连接的'options' => [PDO::ATTR_EMULATE_PREPARES => true]不影响日志,但'log_queries' => env('DB_LOG_QUERIES', false)必须为true(Laravel 9+ 默认关闭) - 如果只想要慢查询,设
'slowlog' => true并配'slow' => 1000(单位 ms),比全量记录更可控
Log::getLogger() 返回的对象可能和预期不一致。真要调试,直接 dump Log::driver()->getMonolog() 最靠谱。











