Я хотел бы создать пользовательский 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; } }