[英]Adding handler name in Monolog logs from Symfony
我使用的是此处所述的自定义monolog处理器,我想将处理程序名称添加到我的日志中。 上述链接上的代码段显示了作为会话传递的参数。 如何传递处理程序参数?
app.logger.session_request_processor:
class: AppBundle\Logger\SessionRequestProcessor
arguments: ['@session']
tags:
- { name: monolog.processor, method: processRecord }
这并不像看起来那么容易。 处理器按记录器或处理程序进行注册。
如果处理器已在记录器中注册,则无法知道处理器经过了哪个处理程序,因为所有处理器都在执行完所有处理器之后执行 。 如果在处理程序上注册处理器,则始终知道要执行哪个处理程序,但是手动为每个处理程序注册处理器非常麻烦。
为了解决这个问题,您可以添加一个CompilerPass来为您完成手动工作。
假设我们有这个处理器
class HandlerProcessor
{
/**
* @var string
*/
private $handlerName;
public function __construct($handlerName)
{
$this->handlerName = $handlerName;
}
public function processRecord(array $record)
{
$record['extra']['handler_name'] = $this->handlerName;
return $record;
}
}
然后,使用该处理器,您可以创建一个编译器通道,该通道为创建的不同处理程序单体日志创建所有定义。
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class HandlerProcessorPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasParameter('monolog.handlers_to_channels')) {
return;
}
foreach ($container->getParameter('monolog.handlers_to_channels') as $handlerId => $channels) {
$definition = new Definition(HandlerProcessor::class);
$handlerDefinition = $container->getDefinition($handlerId);
$handlerName = $handlerDefinition->getClass();
$definition->addArgument($handlerName);
$handlerProcessorId = 'handler_processor.' . $handlerId;
$container->setDefinition($handlerProcessorId, $definition);
$handlerDefinition->addMethodCall('pushProcessor', array(new Reference($handlerProcessorId)));
}
}
}
如果您以前从未使用过编译器,则可能会很混乱,因此请逐行进行:
if (!$container->hasParameter('monolog.handlers_to_channels')) {
return;
}
这将检查monolog捆绑包是否已注册。 参数monolog.handlers_to_channels
被添加到在所述容器MonologExtension 。 参数本身包含一个数组,其中键是处理程序ID的名称,值是一个包含该处理程序已注册到的所有通道的数组(如果此处理程序对所有通道均有效,则返回null)
foreach ($container->getParameter('monolog.handlers_to_channels') as $handlerId => $channels) {
$definition = new Definition(HandlerProcessor::class);
$handlerDefinition = $container->getDefinition($handlerId);
在这里,我们为HandlerProcessor
创建一个新定义,并获取当前已处理的处理程序的定义。
$handlerName = $handlerDefinition->getClass();
$definition->addArgument($handlerName);
这将获取处理程序的类名(例如Monolog \\ Handler \\ SlackHandler ),并将其作为构造函数参数添加到HandlerProcessor
$handlerProcessorId = 'handler_processor.' . $handlerId;
$container->setDefinition($handlerProcessorId, $definition);
$handlerDefinition->addMethodCall('pushProcessor', array(new Reference($handlerProcessorId)));
最后但并非最不重要的一点是,我们为刚刚在foreach循环开始时创建的处理器定义创建了一个新ID,并将其与方法pushProcessor
一起添加到我们新创建的处理器中。
现在已经完成了所有设置,您必须在容器中注册此编译器通道。 我假设您使用的是symfony 2.x,所以您必须在AppBundle
这样做
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new HandlerProcessorPass());
}
}
以下是一些可能有用的附加链接:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.