如何通过处理器向日志消息添加额外数据
Monolog 允许你在记录每个日志条目之前通过添加额外数据来处理它。这是处理器的作用,它可以应用于整个处理器堆栈,或者仅应用于特定的处理器或频道。
处理器是一个可调用对象,它接收记录作为它的第一个参数。处理器使用 monolog.processor
DIC 标签配置。请参阅关于它的参考文档。
添加 Session/请求令牌
有时很难分辨日志中的哪些条目属于哪个会话和/或请求。以下示例将使用处理器为每个请求添加一个唯一的令牌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
// src/Logger/SessionRequestProcessor.php
namespace App\Logger;
use Monolog\LogRecord;
use Monolog\Processor\ProcessorInterface;
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
use Symfony\Component\HttpFoundation\RequestStack;
class SessionRequestProcessor implements ProcessorInterface
{
public function __construct(
private RequestStack $requestStack
) {
}
// method is called for each log record; optimize it to not hurt performance
public function __invoke(LogRecord $record): LogRecord
{
try {
$session = $this->requestStack->getSession();
} catch (SessionNotFoundException $e) {
return $record;
}
if (!$session->isStarted()) {
return $record;
}
$sessionId = substr($session->getId(), 0, 8) ?: '????????';
$record->extra['token'] = $sessionId.'-'.substr(uniqid('', true), -8);
return $record;
}
}
接下来,将你的类注册为服务,以及一个使用额外信息的格式化器
1 2 3 4 5 6 7 8 9 10
# config/services.yaml
services:
monolog.formatter.session_request:
class: Monolog\Formatter\LineFormatter
arguments:
- "[%%datetime%%] [%%extra.token%%] %%channel%%.%%level_name%%: %%message%% %%context%% %%extra%%\n"
App\Logger\SessionRequestProcessor:
tags:
- { name: monolog.processor }
最后,设置要在你想要的任何处理器上使用的格式化器
1 2 3 4 5 6 7 8
# config/packages/prod/monolog.yaml
monolog:
handlers:
main:
type: stream
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
formatter: monolog.formatter.session_request
如果你使用多个处理器,你也可以在处理器级别或频道级别注册处理器,而不是全局注册(请参阅以下章节)。
当注册一个新的处理器时,你可以使用 #[AsMonologProcessor]
属性应用于处理器类,而不是在你的配置文件中手动添加标签
1 2 3 4 5 6 7 8 9 10
// src/Logger/SessionRequestProcessor.php
namespace App\Logger;
use Monolog\Attribute\AsMonologProcessor;
#[AsMonologProcessor]
class SessionRequestProcessor
{
// ...
}
#[AsMonologProcessor]
属性接受这些可选参数
channel
: 处理器应推送到的日志频道;handler
: 处理器应推送到的处理器;method
: 处理记录的方法(当将属性应用于整个类而不是单个方法时很有用)。
3.8
#[AsMonologProcessor]
属性在 MonologBundle 3.8 中引入。
Symfony 的 MonologBridge 提供了可以在你的应用程序内部注册的处理器。
- DebugProcessor
- 向记录添加有用的调试信息,例如时间戳或错误消息。
- TokenProcessor
- 向记录添加当前用户令牌的信息,包括用户名、角色以及用户是否已认证。
- SwitchUserTokenProcessor
- 向记录添加关于正在模拟已登录用户的用户的信息,包括用户名、角色以及用户是否已认证。
- WebProcessor
- 使用 Symfony 请求对象内部的数据覆盖来自请求的数据。
- RouteProcessor
- 添加关于当前路由的信息(控制器、动作、路由参数)。
- ConsoleCommandProcessor
- 添加关于当前控制台命令的信息。
另请参阅
查看内置的 Monolog 处理器,以了解更多关于如何创建这些处理器的信息。
为每个处理器注册处理器
你可以使用 monolog.processor
标签的 handler
选项为每个处理器注册一个处理器
1 2 3 4 5
# config/services.yaml
services:
App\Logger\SessionRequestProcessor:
tags:
- { name: monolog.processor, handler: main }
为每个频道注册处理器
默认情况下,处理器应用于所有频道。将 channel
选项添加到 monolog.processor
标签以仅将处理器应用于给定的频道
1 2 3 4 5
# config/services.yaml
services:
App\Logger\SessionRequestProcessor:
tags:
- { name: monolog.processor, channel: 'app' }
本作品,包括代码示例,在 Creative Commons BY-SA 3.0 许可下获得许可。