Я хотел бы иметь возможность различать канал, используемый 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. }.журнал.
Спасибо заранее за любую помощь.
Ты можешь использовать помеченный шаблон стратегии для этого и Вот.
монолог
Предполагая, что вы создали два пользовательских обработчика монологов. 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.');
Других решений пока нет …