Laravel 日志实战:Channel 体系、结构化上下文与生产配置

Laravel 日志中文实战:config/logging.php 频道配置、single/daily/stack/monolog/custom 五种驱动、Log 门面与 context 结构化字段、FilterHandler 级别过滤、tap 自定义 Monolog、生产环境 JSON 输出,以及观测云 DataKit 采集告警落地方案。

最佳实践
Laravel 日志实战:Channel 体系、结构化上下文与生产配置技术指南封面

Laravel 的日志体系建立在 Monolog 之上,用"频道(channel)+ 驱动(driver)"的声明式配置把 Monolog 的灵活性包装成了优雅的框架体验。本文讲解频道驱动的选择、结构化上下文的写法、生产配置清单,以及观测云平台落地方案。

核心要点速览

  • 一切配置在 config/logging.php:默认频道由 LOG_CHANNEL 环境变量控制,代码里 Log::info() 即用。
  • daily 驱动优于 single:按天轮转 + 自动清理(days 参数),告别单个巨型日志文件。
  • stack 驱动实现多路输出:一条日志同时进多个频道,是"文件 + 告警"组合的基础。
  • 生产落地:JSON 格式 stdout 输出,观测云 DataKit 采集,监控器告警。

快速上手:Log 门面与结构化上下文

use Illuminate\Support\Facades\Log;

Log::info("订单创建成功", ["order_id" => $order->id, "amount" => $order->amount]);
Log::warning("库存不足", ["sku" => $sku]);
Log::error("扣款失败", ["order_id" => $order->id, "exception" => $e]);

// 指定频道
Log::channel("payments")->info("支付回调", $payload);

第二个参数是 context 数组(结构化字段),底层 Monolog 会把它序列化进日志。

六种频道驱动怎么选?

驱动 行为 适用
single 写入单个文件 storage/logs/laravel.log 本地开发
daily 按天轮转,days 控制保留天数 生产主机部署
syslog / errorlog 写系统日志 / PHP error_log 与系统日志整合
stack 聚合多个频道同时输出 生产多路输出
monolog 直接调用任意 Monolog Handler 高级定制(FilterHandler 等)
custom 工厂创建完全自定义 logger 特殊集成
// config/logging.php
"channels" => [
    "stack" => [
        "driver" => "stack",
        "channels" => ["daily", "stderr"],
        "ignore_exceptions" => false,
    ],
    "daily" => [
        "driver" => "daily",
        "path" => storage_path("logs/laravel.log"),
        "level" => env("LOG_LEVEL", "info"),
        "days" => 14,
    ],
    "stderr" => [
        "driver" => "monolog",
        "handler" => \Monolog\Handler\StreamHandler::class,
        "with" => ["stream" => "php://stderr"],
    ],
],

用 monolog 驱动做精细控制

monolog 驱动可以直接使用任意 Monolog Handler,例如 FilterHandler——只有精确匹配的级别才进入该频道(而非最低级别放行):

"alerts" => [
    "driver" => "monolog",
    "handler" => \Monolog\Handler\FilterHandler::class,
    "with" => [
        "handler" => new \Monolog\Handler\StreamHandler(storage_path("logs/critical.log")),
        "acceptedLevels" => [\Monolog\Level::Critical, \Monolog\Level::Alert, \Monolog\Level::Emergency],
    ],
],

tap:给频道注入自定义逻辑

"daily" => [
    "driver" => "daily",
    "path" => storage_path("logs/laravel.log"),
    "tap" => [App\Logging\CustomizeFormatter::class],
],

tap 类拿到 Monolog 实例后可换 formatter、加 processor——生产 JSON 化就靠它

class CustomizeFormatter
{
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new \Monolog\Formatter\JsonFormatter());
        }
    }
}

生产配置清单

  1. LOG_CHANNEL=stack(daily + stderr)或容器环境直接 stderr;
  2. JSON 化:tap 注入 JsonFormatter;
  3. 级别走环境变量 LOG_LEVEL=info
  4. daily 的 days 按磁盘与合规要求设置(14-30 天);
  5. 队列消费者日志与 Web 日志同频道或按业务分频道。

观测云落地:Laravel 日志采集与分析

  1. 应用侧:JSON 输出 stdout/stderr(容器)或 daily 文件(主机)。不要在应用内直推远程日志服务——采集交给 DataKit,应用与后端解耦。
  2. DataKit 采集:容器 stdout 自动采集;主机 conf.d/log/logging.conflogfiles 指向 storage/logs/laravel-*.logsource: laravelservice 标识服务。JSON 自动解析。
  3. Pipeline 标准化level_name 映射标准 statusdatetime 解析为 time,context 字段顶层化。
  4. 检索告警:日志查看器按 status/service 过滤,聚类分析归纳异常;监控器对 error 以上级别、特定异常关键字设阈值,告警策略路由钉钉/企业微信/飞书。
  5. 链路关联:接入 OpenTelemetry PHP 探针后 trace_id 进日志,与观测云 APM 双向跳转。
  6. 成本控制:多索引按级别拆保留策略,历史数据转发归档对象存储。

常见问题(FAQ)

single 和 daily 到底选哪个?

生产一律 daily。single 的文件无限增长,排查时打开都费劲;daily 按天切分、自动清理,还可配合系统 logrotate 做更复杂的归档策略。

队列任务(Queue Worker)的日志在哪?

同在配置的频道里。Horizon/queue worker 是独立进程,日志同样走 Log 门面;建议用 context 加 job_idqueue 字段,平台侧按字段过滤还原任务执行。

Laravel 的异常都记到哪里?

框架异常处理器(App\Exceptions\Handler)默认把未处理异常写进默认频道。想定制(比如特定异常不记录、或附加业务上下文),重写 Handler 的 report 逻辑。

日志里能看到 SQL 吗?

DB::listen 或开启查询日志可以,但生产慎开——量极大且可能含敏感数据。排障时临时开启,或用观测云 APM 的数据库链路分析替代。

系列阅读


获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台