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

Laravel全局生成日志ID并记录至容器的实现方案咨询

Laravel 全局为所有日志添加统一请求ID的实现方法

当然可以实现全局统一生成日志ID,无需在每次打日志时手动传入。结合你已经尝试的中间件思路,这里提供两种完善的全局实现方案,覆盖HTTP请求和命令行任务场景:

方案一:全局中间件 + 日志上下文共享(适配HTTP请求)

你之前的中间件思路是可行的,只需完善配置让日志自动携带ID:

1. 完善全局中间件

修改你的AssignRequestId中间件,确保ID存入容器和请求实例,同时共享到日志上下文:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;
use Ramsey\Uuid\Uuid;

class AssignRequestId
{
    public function handle($request, Closure $next)
    {
        $requestId = Uuid::uuid4()->toString();
        
        // 存入请求实例,方便后续调用
        $request->attributes->set('request-id', $requestId);
        // 绑定到容器,全局可获取
        app()->instance('request-id', $requestId);
        // 共享到日志上下文,所有日志自动携带
        Log::shareContext(['request-id' => $requestId]);
        
        return $next($request);
    }
}

2. 注册全局中间件

在app/Http/Kernel.php的$middleware数组中注册该中间件,确保所有HTTP请求都经过:

protected $middleware = [
    // ...其他默认中间件
    \App\Http\Middleware\AssignRequestId::class,
];

3. 配置日志格式

修改config/logging.php,指定日志格式包含上下文信息,让request-id自动显示在日志中:

'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['single'],
    ],

    'single' => [
        'driver' => 'single',
        'path' => storage_path('logs/laravel.log'),
        'level' => env('LOG_LEVEL', 'debug'),
        'formatter' => \Monolog\Formatter\LineFormatter::class,
        'formatter_with' => [
            'format' => "[%datetime%] %level_name%: %message% | Request-ID: %context.request-id%\n",
            'dateFormat' => 'Y-m-d H:i:s',
        ],
    ],
];

方案二:Monolog处理器(适配所有日志场景)

如果需要覆盖命令行任务、队列等非HTTP场景的日志,可使用Monolog自定义处理器:

1. 创建自定义日志处理器

<?php

namespace App\Logging;

use Monolog\Processor\ProcessorInterface;
use Ramsey\Uuid\Uuid;

class RequestIdProcessor implements ProcessorInterface
{
    public function __invoke(array $record): array
    {
        // 优先使用HTTP请求中生成的ID,否则生成新UUID
        $requestId = app()->bound('request-id') ? app('request-id') : Uuid::uuid4()->toString();
        
        // 将ID存入日志的extra字段
        $record['extra']['request-id'] = $requestId;
        
        return $record;
    }
}

2. 配置日志通道使用处理器

修改config/logging.php,为目标日志通道添加处理器:

'single' => [
    'driver' => 'single',
    'path' => storage_path('logs/laravel.log'),
    'level' => env('LOG_LEVEL', 'debug'),
    'processors' => [
        \App\Logging\RequestIdProcessor::class,
    ],
    'formatter' => \Monolog\Formatter\LineFormatter::class,
    'formatter_with' => [
        'format' => "[%datetime%] %level_name%: %message% | Request-ID: %extra.request-id%\n",
        'dateFormat' => 'Y-m-d H:i:s',
    ],
],

全局获取Request-ID

在项目任何地方,都可以通过容器获取当前请求/任务的ID:

$requestId = app('request-id');

内容的提问来源于stack exchange,提问作者cong wang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:12:04