You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据debug状态开启或关闭Laravel日志的上下文附加数据

如何根据debug状态开启或关闭Laravel日志的上下文附加数据

我来帮你解决这个问题!你遇到的情况是因为withoutContext()的作用范围和你想控制的全局上下文不是一回事——withoutContext()只能清除日志实例的本地上下文(也就是你通过Log::withContext()手动添加的内容),而框架自动附加的是全局ContextRepository里的元数据,这部分是通过日志管理器的处理器注入的,所以你的原有代码没法生效。

下面给你两种可行的解决方案,选哪种都能实现需求:

方案一:自定义日志格式化器(推荐,更符合Laravel配置风格)

这种方法通过自定义格式化器,根据debug状态动态决定是否保留全局上下文数据:

  1. 创建自定义格式化器类
    在app/Logging目录下新建CustomDnsFormatter.php(如果没有Logging目录就自己创建):
<?php

namespace App\Logging;

use Illuminate\Log\ContextRepository;
use Monolog\Formatter\LineFormatter;

class CustomDnsFormatter extends LineFormatter
{
    public function format(array $record): string
    {
        // 当debug为false时,移除extra中的全局上下文数据
        if (!config('app.debug')) {
            $globalContext = app(ContextRepository::class)->all();
            foreach (array_keys($globalContext) as $key) {
                unset($record['extra'][$key]);
            }
        }

        return parent::format($record);
    }
}
  1. 配置日志通道使用自定义格式化器
    打开config/logging.php,找到你的dns通道配置,添加formatter指定我们刚创建的类:
'dns' => [
    'driver' => 'single', // 你的通道驱动,可能是single/daily等
    'path' => storage_path('logs/dns.log'),
    'level' => 'debug',
    'formatter' => App\Logging\CustomDnsFormatter::class, // 新增这一行
],
  1. 简化你的业务代码
    现在不需要在代码里判断debug状态了,直接使用日志通道即可:
public function __construct()
{
    $this->r = new ResultMsg();
    $this->r->msgPrefix = "POWERDNSSERVICE: ";
    $this->log = Log::channel('dns'); // 直接用通道,格式化器会自动处理
    $this->logException = Log::channel('dns_exception');
}

方案二:通过服务提供者动态修改日志处理器

如果你不想修改格式化器,也可以在服务提供者中动态为日志通道添加处理器,过滤上下文数据:

在App\Providers\AppServiceProvider.php的boot方法中添加以下代码:

use Illuminate\Log\ContextRepository;
use Illuminate\Log\LogManager;
use Monolog\Processor\ProcessorInterface;

public function boot()
{
    $this->app->extend(LogManager::class, function (LogManager $logManager) {
        // 针对dns通道进行修改
        $logManager->extend('dns', function ($app, $config) use ($logManager) {
            // 获取原本的dns通道实例
            $logger = $logManager->resolve($config);

            // 如果debug为false,添加处理器移除全局上下文
            if (!config('app.debug')) {
                $logger->pushProcessor(new class implements ProcessorInterface {
                    public function __invoke(array $record): array
                    {
                        $globalContext = app(ContextRepository::class)->all();
                        foreach (array_keys($globalContext) as $key) {
                            unset($record['extra'][$key]);
                        }
                        return $record;
                    }
                });
            }

            return $logger;
        });

        return $logManager;
    });
}

之后同样可以直接在业务代码中使用Log::channel('dns'),处理器会根据debug状态自动处理上下文数据。

备注:内容来源于stack exchange,提问作者Lem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:04:35