我希望能够根据Symfony命令或应用程序服务器调用服务来区分Monolog使用的通道。
例如:
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
通道(文件命令-{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} .log。
在此先感谢您的帮助。
答案 0 :(得分:1)
您可以为此使用tagged Strategy Pattern和here。
独白
假设您创建了两个自定义的独白处理程序。 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;
}
服务A
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);
}
}
服务B
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.');