Я хотел бы создать пользовательский HandlerWrapper чтобы использовать его с Monolog в моем проекте Symfony 2.8 .
Цель состоит в том, чтобы использовать этот CustomHandler в качестве фильтра, который решает, как CustomHandler / вложенный обработчик или нет.
==============
ОБНОВЛЕНИЕ: следующий вопрос уже решён благодаря ответу @Yonel. Однако это привело к новой проблеме, описанной ниже.
Расширение Monolog\Handler\HandlerWrapper , не проблема. Но я борюсь за нас с config_prod.yml классом в конфигурации config_prod.yml в config_prod.yml :
namespace AppBundle\Log; use Monolog\Handler\HandlerWrapper; class CustomHandler extends HandlerWrapper { public function handle(array $record) { // some custom handling/processing... if ($this->doSomeCheck()) return $this->handler->handle($record); else return false; // Do not call nested handler } }
Config:
services: monolog.custom_handler.service: class: AppBundle\Log\CustomHandler monolog: main: type: service id: monolog.custom_handler.service level: error handler: someHandler someHandler: ...
Проблема: при запуске app/console cache:warmup в этом конфиге, я получаю следующую ошибку:
[Symfony \ Component \ Debug \ Exception \ ContextErrorException]
Catchable Fatal Error: аргумент 1, переданный Monolog \ Handler \ GroupHandler :: __ construct () должен быть из массива типов, ни один заданный
Ну, я думаю, что источник проблемы очевиден: определение службы monolog.custom_handler.service не передает никаких аргументов классу. Но как я могу передать someHandler качестве аргумента, как определено в конфигурации Monolog?
==============
EDIT: новая проблема
Как описывает Йонел в своем ответе, on может использовать следующую конфигурацию, чтобы передать someHandler в custom_handler :
services: monolog.custom_handler.service: class: AppBundle\Log\CustomHandler arguments: - '@monolog.handler.testHandler' monolog.test_handler.service: class: AppBundle\Log\TestHandler monolog: # Skip level checking (can be solved by adding a FingersCrossed handler) main: type: service id: monolog.custom_handler.service testHandler: type: service id: monolog.test_handler.service nested: true
Это работает: TestHandler теперь правильно передается в CustomHandler
Однако цель состояла в том, чтобы позволить CustomHandler принять решение, TestHandler или нет. Это не работает с этой конфигурацией: TestHandler вызывается в любом случае (я предполагаю, что непосредственно Monolog, как и любой другой обработчик). Это не имеет никакого значения, если TestHandler передается в CustomHandler , помечен как nested или нет.
Я реализовал CustomHandler как HandlerWrapper и TestHandler как AbstractHandler . Оба класса непосредственно связаны с файлом журнала (не используя Монолог) при вызове метода handle . Таким образом, я могу проверить, работают ли обработчики TestHandler ( TestHandler следует TestHandler только в том случае, если позволяет CustomHandler ). Это не тот случай.
Независимо от того, TestHandler ли TestHandler в CustomHandler , если он помечен как nested , если CustomHandler возвращает true или false в методе handle и т. Д., Результат всегда один и тот же: TestHandler , вне зависимости от того, что CustomHandler решает.
Как это решить?
Реализации обработчиков:
namespace AppBundle\Log; use Monolog\Handler\HandlerWrapper; class CustomHandler extends HandlerWrapper { public function handle(array $record) { // some custom handling/processing... if ($this->doSomeCheck()) { $this->directlyWriteToFileNotUsingMonolog('CustomHandler: Call TestHandler'); return $this->handler->handle($record); else { $this->directlyWriteToFileNotUsingMonolog('CustomHandler: Do NOT call TestHandler'); return false; // Do not call nested handler } } class TestHandler extends AbstractHandler { public function handle(array $record) { $this->directlyWriteToFileNotUsingMonolog('TestHandler'); return false; } }