Symfony 3.4 — Дифференцированный логгер на основе «контекста»

Я хотел бы иметь возможность различать канал, используемый Monolog, в зависимости от того, вызывается ли служба командой Symfony или сервером приложений.

Например:

class A {
private $logger;

public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}
}

class B {
private $logger;

public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}
}

class SomeCommand extends Symfony\Component\Console\Command\Command {
private $logger;

public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}

protected function configure() {
$this->setName('my-app:command');
}

protected function execute(InputInterface $input, OutputInterface $output) {
// execute something from class A
// execute something from class B
}
}

Если я бегу php bin\console my-app:command Я бы хотел, чтобы Symfony написал все commands channel (file commands- {environment} .log), в то время как если класс A и B используются запросом от контроллера, они записывают все в другой канал.

На данный момент у меня есть конфиг:

monolog:
channels: ['commands']
handlers:
main:
type: rotating_file
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
channels: [!commands]
commands_only:
type: rotating_file
path: '%kernel.logs_dir%/commands-%kernel.environment%.log'
level: debug
channels: [commands]

Внедрение регистратора только в службу Command не дает мне желаемого результата: он записывает только журнал из класса Command в файл command- {environment} .log, в то время как другие классы продолжают вести запись в файл {envinronment. }.журнал.

Спасибо заранее за любую помощь.

0

Решение

Ты можешь использовать помеченный шаблон стратегии для этого и Вот.

монолог

Предполагая, что вы создали два пользовательских обработчика монологов. handler_x а также handler_y

конфиг

service:
# CONSUMER
App\Service\StrategyService:
arguments: [!tagged mytag]

App\Service\ServiceA:
- @monolog.logger.handler_x
tags:
- { name: mytag }

App\Service\ServiceB:
arguments:
- @monolog.logger.handler_y
tags:
- { name: mytag }

StrategyService

declare(strict_types=1);

namespace App\Service;

use Traversable;

class StrategyService
{
private $services;

public function __construct(Traversable $services)
{
$this->services = $services;
}

public function process(string $name, string $message): bool
{
/** @var ServiceInterface $service */
foreach ($this->services as $service) {
if ($service->canProcess($name)) {
$service->process($message);

break;
}
}
}
}

ServiceInterface

declare(strict_types=1);

namespace App\Service;

interface ServiceInterface
{
public function canProcess(string $name): bool;

public function process(string $message): void;
}

ServiceA

declare(strict_types=1);

namespace App\Service;

use Psr\Log\LoggerInterface;

class ServiceA implements ServiceInterface
{
private $logger;

public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}

public function canProcess(string $name): bool
{
return $name === 'handler_x';
}

public function process(string $message): void
{
// Do something with your service

$this->logger->error($message);
}
}

ServiceB

declare(strict_types=1);

namespace App\Service;

use Psr\Log\LoggerInterface;

class ServiceB implements ServiceInterface
{
private $logger;

public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}

public function canProcess(string $name): bool
{
return $name === 'handler_y';
}

public function process(string $message): void
{
// Do something with your service

$this->logger->error($message);
}
}

Теперь все, что вам нужно сделать, это ввести StrategyService командовать и звонить process метод.

$this->strategyService->process('handler_x', 'This goes to ServiceA logger.');
$this->strategyService->process('handler_y', 'This goes to ServiceB logger.');
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru