bilfeldt/laravel-correlation-id

在 Laravel 应用中处理 Request-ID 和 Correlation-ID

v1.2.0 2024-02-27 14:54 UTC

This package is auto-updated.

Last update: 2024-09-07 07:54:45 UTC


README

bilfeldt/laravel-correlation-id

Latest Version on Packagist Tests StyleCI Code Style Status Total Downloads

通过中间件创建请求的 Correlation-IDs,并将这个全局唯一的 Correlation-ID 以及任何用户提供的 Request-ID 传递给全局日志上下文。

动机

每个请求都应该有一个唯一的 Correlation ID,这个 ID 可以唯一确定用户交互。然后,应该将这个 Correlation ID 添加到所有日志条目作为上下文,错误报告以及任何子系统(如外部 API 调用或排队作业)。这样做可以使跟踪特定用户请求的相关接触点成为可能。更多信息请参阅 这里

客户端也可以提供一个 Request ID,良好的实践是在响应中返回它并将其与 Correlation ID 关联。更多信息请参阅 这里

安装

您可以通过 composer 安装此包

composer require bilfeldt/laravel-correlation-id

将 Correlation ID 分配给请求

注意

理想情况下,唯一的 Correlation ID 应该在您的基础设施的第一个接触点处创建,例如初始服务器,可能是负载均衡器

由于在服务器级别创建 Correlation ID 可能比较复杂,但在 Laravel 中使用中间件则非常简单。此包提供了一个创建 Correlation ID 并将其作为头部 Correlation-ID 以及响应头部附加到请求上的中间件。您应该在基础设施的第一个接触点处分配 correlation id,或者在 app/Http/Kernel.php 类的 $middleware 属性中全局注册 CorrelationIdMiddleware 中间件作为第一个中间件。

// app/Http/Kernel.php

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array<int, class-string|string>
 */
protected $middleware = [
    \Bilfeldt\CorrelationId\Middleware\CorrelationIdMiddleware::class, // <!-- Add this globally as the first toutchpoint
    // \App\Http\Middleware\TrustHosts::class,
    \App\Http\Middleware\TrustProxies::class,
    \Illuminate\Http\Middleware\HandleCors::class,
    \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];

将 Request ID 分配给响应

如果客户端在请求头部中提供了 Request ID,则将此复制到响应头部是一种良好的实践。这可以通过在 app/Http/Kernel.php 类的 $middleware 属性中全局添加 ClientRequestIdMiddleware 中间件来完成。

// app/Http/Kernel.php

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array<int, class-string|string>
 */
protected $middleware = [
    \Bilfeldt\CorrelationId\Middleware\CorrelationIdMiddleware::class,
    \Bilfeldt\CorrelationId\Middleware\ClientRequestIdMiddleware::class, // <!-- Add this globally
    // \App\Http\Middleware\TrustHosts::class,
    \App\Http\Middleware\TrustProxies::class,
    \Illuminate\Http\Middleware\HandleCors::class,
    \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];

用法

此包在 Illuminate\Http\Request 类上注册了一些宏

$request->getCorrelationId(); // UUID or null if not assigned

$request->getClientRequestId(); // The `Request-ID` header if provided by the client

$request->getUniqueId(); // Unique UUID for each request: 94d0e2d6-4cc6-449c-9140-80bca47d29b4

添加全局日志上下文

可以添加 Correlation IDRequest ID 到全局日志上下文,以便添加到日志中的任何内容都将自动附加 ID 作为上下文。

建议在将它们分配给请求后立即将它们添加到日志上下文中。这可以通过在 app/Http/Kernel.php 类的 $middleware 属性中全局注册 LogContextMiddleware 中间件来实现。

// app/Http/Kernel.php

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array<int, class-string|string>
 */
protected $middleware = [
    \Bilfeldt\CorrelationId\Middleware\CorrelationIdMiddleware::class,
    \Bilfeldt\CorrelationId\Middleware\ClientRequestIdMiddleware::class,
    \Bilfeldt\CorrelationId\Middleware\LogContextMiddleware::class, // <!-- Add this globally AFTER assigning Correlation ID and Request ID.
    // \App\Http\Middleware\TrustHosts::class,
    \App\Http\Middleware\TrustProxies::class,
    \Illuminate\Http\Middleware\HandleCors::class,
    \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];

将全局上下文添加到错误报告

可以将 Correlation IDRequest ID 添加到全局错误报告上下文中,以便在添加这些信息后,任何错误报告都将自动附加 ID 作为上下文。

如果变量已经添加到日志上下文,则建议将所有全局日志上下文合并到错误报告上下文中,覆盖应用程序的 App\Exceptions\Handlercontext 方法。

// app/Exceptions/Handler.php

/**
 * Get the default context variables for logging.
 *
 * @return array<string, mixed>
 */
protected function context(): array
{
    return array_merge(parent::context(), $this->getGlobalLogContext());
}

private function getGlobalLogContext(): array
{
    try {
        return Log::sharedContext();
    } catch (\Throwable $e) {
        return [];
    }
}

或者如果您不想共享所有全局日志上下文,只需使用上面描述的宏从 request() 辅助函数中获取 ID

// app/Exceptions/Handler.php

/**
 * Get the default context variables for logging.
 *
 * @return array<string, mixed>
 */
protected function context(): array
{
    return array_merge(parent::context(), [
        'correlation_id' => request()->getCorrelationId(),
        'request_id' => request()->getUniqueId(),
    ]);
}

将关联 ID 和请求 ID 传递到队列作业

该包确保将 关联 ID请求 ID 传递到队列作业的负载中,可以使用 $job->payload()['data'] 再次检索。

在队列作业开始处理之前,我们从负载中提取 关联 ID请求 ID 并将这些设置在 Illuminate\Http\Request 实例上,这样任何后续的作业如果被调度也将包含它们。

测试

composer test

变更日志

请参阅变更日志获取最近更改的更多信息。

贡献

请参阅贡献指南获取详细信息。

安全漏洞

请查阅我们的安全策略了解如何报告安全漏洞。

鸣谢

许可证

MIT 许可证 (MIT)。请参阅许可证文件获取更多信息。