在记录业务日志时,我们经常需要为每一条日志都补充上类似 RequestId
类的唯一标识串
,方便后期快速的将某请求的相关的日志流 聚合
查询出来。首先,RequestId
是要单例贯穿整个请求生命周期的,如果在整个请求处理过程中,包括不同的服务层、模块,我都需要将 RequestId
透传或作为参数显示的传入 logger
中,那代码简直不要太美观。
Monolog
作为最为流行的 PHP
日志组件,如果可以实现为每一条日志自动填充 RequestId
,那使用起来是非常舒服的。
Monolog
的 pushProcessor
方法可以方便我们实现这一需求,pushProcessor
中的 processor
会对你记录的每一条日志进行处理并返回。
在请求的初始阶段,为本次请求生成一个全局的 RequestId
,我是放在 Request
对象上,不同框架获取请求会话的 Request
单例对象的方法可能不同,大家理解就好。或者你可以单独使用一个单例对象去维护 RequestId
,只要保证对当前请求是单例模式(放在 DI Container
中最好)。
<?php
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler::class;
use Monolog\Formatter\LineFormatter::class;
class Log
$logger = new Logger('default');
// 添加处理器
$rfHandler = new RotatingFileHandler(__DIR__ . '/app_default.log', Logger::DEBUG);
$format = "[%datetime%] %channel%.%level_name%: %extra% %message% %context%\n";
$dateFormat = 'Y-m-d H:i:s';
$lFormatter = new LineFormatter($format, $dateFormat, true);
$rfHandler->setFormatter($lFormatter)
$logger->pushHandler($rfHandler);
// 就是在这里做处理啦 $request->getRequestId 自己去实现
$logger->pushProcessor(function ($log) {
/** @var Request $request */
$request = \request();//webman的
$log['extra']['request-id'] = $request->getRequestId();
return $log;
});
<?php
// 现在你就可以用日志服务了
$logger->info('this is monolog example');
$logger->info('this is log will auto fill requestId');
记得把 RequestId
返回给前端,这样问题反馈就容易追踪请求链路了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。