繁体   English   中英

从Symfony在Monolog日志中添加处理程序名称

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM