Symfony 自定义日志处理程序服务调用

Symfony custom log handler service call

我已经在 symfony 中创建了自定义日志处理程序。创建它不是问题,配置:config/packages/dev/monolog.yaml

monolog:
    handlers:
     ....
        alerts:
            type: service
            id: App\Logger\AlertLogger
            channels: [app]
            level:  warning

我的服务:

<?php

namespace App\Logger;
use Monolog\Handler\AbstractProcessingHandler;
class AlertLogger extends AbstractProcessingHandler
{
    protected function write(array $record)
    {
        // handle log
    }
}

但问题是我想将这些日志发送到RabbitMQ并在Consumer中做一些事情,但是没有办法调用任何其他服务。我试图将其传递给构造,但出现如下错误:

Argument 3 passed to App\Logger\AlertLogger::__construct() must implement interface OldSound\RabbitMqBundle\RabbitMq\ProducerInterface, string given, called in .....

那是因为AbstractProcessingHandler中有一个构造定义。

=============== 编辑:我的测试:

Parents class 构造函数:

public function __construct($level = Logger::DEBUG, $bubble = true)
{
    $this->setLevel($level);
    $this->bubble = $bubble;
}

我尝试将日志处理程序作为服务添加到 services.yaml:

services:
    .....
    App\Logger\AlertLogger:
        arguments:
            $producer: OldSound\RabbitMqBundle\RabbitMq\Producer

我的日志处理程序:

...
class AlertLogger extends AbstractProcessingHandler
{
    /**
     * @var ProducerInterface
     */
    private $producer;
    public function __construct(ProducerInterface $producer)
    {
        $this->producer = $producer;
    }
  ......

但是我收到这个错误:

Argument 1 passed to App\Logger\AlertLogger::__construct() must implement interface OldSound\RabbitMqBundle\RabbitMq\ProducerInterface, string given, called in

当我尝试设置构造参数时:

....
class AlertLogger extends AbstractProcessingHandler
{
    /**
     * @var ProducerInterface
     */
    private $producer;
    public function __construct($level, $bubble, ProducerInterface $producer)
    {
        parent::__construct($level, $bubble);
        $this->producer = $producer;
    }
.....

我收到错误:

Cannot autowire service "App\Logger\AlertLogger": argument "$level" of method "__construct()" has no type-hint, you should configure its value explicitly.

Lucas,为了覆盖您的构造函数参数,您应该为其定义自定义构造函数并为其配置服务定义(如果未自动装配)。不幸的是,这会导致预定义功能的丢失(即 level 设置在这里无用),因此您必须自己重新定义它。

如果将处理程序定义为服务,它实际上不会以任何方式处理

https://github.com/symfony/monolog-bundle/blob/master/DependencyInjection/MonologExtension.php#L131-L135

您可以尝试 post 您的构造函数和服务定义以获得有关其状态的更具体的答案。乍一看,我可以建议您手动创建服务定义而忘记了 @ 符号。只是猜测。

编辑:

应该是

services:
    .....
    App\Logger\AlertLogger:
        arguments:
            $level: 'warning'
            $bubble: true
            $producer: "@OldSound\RabbitMqBundle\RabbitMq\Producer"

有构造函数

/**
 * @var ProducerInterface
 */
private $producer;
public function __construct($level, $bubble, ProducerInterface $producer)
{
    parent::__construct($level, $bubble);
    $this->producer = $producer;
}