Symfony Monolog:如何在现有格式化器前后执行自定义处理器?
在Symfony中控制Monolog处理器与格式化器的执行顺序
一、常规场景:让处理器在格式化器之前执行(推荐用于敏感数据过滤)
这是Monolog的默认执行逻辑,也是处理敏感数据的合理顺序——先修改日志记录(替换敏感字段),再交给格式化器生成最终日志内容。
1. 注册自定义处理器为服务
在config/services.yaml中添加以下配置,将处理器绑定到你的main日志处理器:
services: App\CoreBundle\Logger\PIIFilterProcessor: tags: # 绑定到main handler,仅对该处理器生效 - { name: monolog.processor, handler: main, priority: 10 } # 若要让处理器对所有日志处理器生效,去掉handler参数即可: # - { name: monolog.processor, priority: 10 }
priority参数用于控制多个处理器的执行顺序:数值越高,处理器执行越早。
2. 验证执行顺序
当你记录日志时(例如$logger->info('用户登录', ['email' => 'user@example.com', 'password' => '123456'])),流程为:
- 触发日志事件,先执行
PIIFilterProcessor,将context中的敏感字段替换为***FILTERED*** - 处理后的日志记录再传给
logstash_formatter_private_lib进行格式化 - 最终格式化后的日志写入指定文件
二、特殊场景:让处理器在格式化器之后执行(不推荐)
这种场景仅适用于需要修改已格式化完成的日志字符串的特殊需求,由于格式化后的数据是字符串,处理敏感数据容易出错,不推荐用于敏感信息过滤。
1. 自定义日志处理器
创建继承自StreamHandler的自定义处理器,重写write方法实现格式化后处理:
<?php namespace App\CoreBundle\Logger; use Monolog\Handler\StreamHandler; class FilteredStreamHandler extends StreamHandler { // 针对格式化后字符串的敏感字段匹配规则 private $piiPatterns = [ '/email":\s*"([^"]+)"/' => 'email":"***FILTERED***"', '/password":\s*"([^"]+)"/' => 'password":"***FILTERED***"', // 可添加其他字段的正则匹配规则 ]; protected function write(array $record): void { // 先调用格式化器生成日志字符串 $formatted = $this->getFormatter()->format($record); // 对格式化后的字符串进行敏感字段替换 foreach ($this->piiPatterns as $pattern => $replacement) { $formatted = preg_replace($pattern, $replacement, $formatted); } // 将处理后的字符串写入日志文件 fwrite($this->stream, $formatted); } }
2. 修改Monolog配置
将原有的main处理器替换为自定义处理器:
monolog: handlers: main: type: service id: App\CoreBundle\Logger\FilteredStreamHandler path: "%log_file_path%" level: "%log_level%" formatter: logstash_formatter_private_lib
3. 注册自定义处理器服务
在config/services.yaml中添加:
services: App\CoreBundle\Logger\FilteredStreamHandler: arguments: $path: "%log_file_path%" $level: "%log_level%" calls: - method: setFormatter arguments: ['@logstash_formatter_private_lib']
内容的提问来源于stack exchange,提问作者Melchia
相关产品推荐
相关产品推荐

