Symfony 3.4 - 基于"context"区分记录器



我希望能够根据服务是由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 SymfonyComponentConsoleCommandCommand {
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 binconsole my-app:command我希望 Symfony 将所有内容写入commands通道(文件命令-{环境}.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-{environment}.log,而其他类继续记录到文件 {envinronment}.log。

提前感谢您的任何帮助。

您可以为此和此处使用标记的策略模式。

独白

假设您创建了两个自定义单日志处理程序。handler_xhandler_y

配置

service:
# CONSUMER
AppServiceStrategyService:
arguments: [!tagged mytag]
AppServiceServiceA:
- @monolog.logger.handler_x
tags:
- { name: mytag }
AppServiceServiceB:
arguments:
- @monolog.logger.handler_y
tags:
- { name: mytag }

战略服务

declare(strict_types=1);
namespace AppService;
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;
}
}
}
}

服务接口

declare(strict_types=1);
namespace AppService;
interface ServiceInterface
{
public function canProcess(string $name): bool;
public function process(string $message): void;
}

服务A

declare(strict_types=1);
namespace AppService;
use PsrLogLoggerInterface;
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 AppService;
use PsrLogLoggerInterface;
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.');

最新更新