Я использовал следующую конфигурацию для моего ведения журнала:
monolog: handlers: mail: type: fingers_crossed action_level: error handler: grouped grouped: type: group members: [streamed, buffered] streamed: type: stream path: %kernel.logs_dir%/%kernel.environment%.log level: debug # buffered is used to accumulate errors and send them as batch to the email address buffered: type: buffer handler: swift swift: type: swift_mailer from_email: info@....com to_email: info@....com subject: Error Occurred! level: debug
Это отправляет письма следующим образом:
[2012-03-21 21:24:09] security.DEBUG: Прочтите SecurityContext из сеанса [] []
[2012-03-21 21:24:09] security.DEBUG: перезагрузка пользователя от поставщика. [] []
[2012-03-21 21:24:09] security.DEBUG: Имя пользователя "jakob.asdf" было перезагружено у поставщика услуг. [] [] [2012-03-21 21:24:09] request.INFO: Соответствующий маршрут «_user_settings» (параметры: «_controller»: «… Bundle \ Controller \ UserController :: settingsAction», «username»: «Jakob.asdf», «_route»: «_user_settings») [] []
[2012-03-21 21:24:09] request.ERROR: Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException: … Bundle \ Entity \ User объект не найден. (неперехваченное исключение) в /var/www/…/vendor/bundles/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/DoctrineParamConverter.php line 50 [] []
[2012-03-21 21:24:09] security.DEBUG: Напишите SecurityContext в сеансе [] []
Мне бы очень хотелось иметь трассировку стека здесь или, по крайней мере, номер строки в моем контроллере, который вызвал ошибку. В противном случае это действительно много догадок о том, что могло пойти не так.
Теперь вопрос: есть ли способ достичь такого еще более подробного ведения журнала?
Да, это может быть достижимо.
Создайте класс ExceptionListener
.
//namespace declarations class ExceptionListener{ /** * @var \Symfony\Component\HttpKernel\Log\LoggerInterface */ private $logger =null; /** * @param null|\Symfony\Component\HttpKernel\Log\LoggerInterface $logger */ public function __construct(LoggerInterface $logger = null) { $this->logger = $logger; } /** * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event */ public function onKernelException(GetResponseForExceptionEvent $event) { if($this->logger === null) return; $exception = $event->getException(); $flattenException = FlattenException::create($exception); $this->logger->err('Stack trace'); foreach ($flattenException->getTrace() as $trace) { $traceMessage = sprintf(' at %s line %s', $trace['file'], $trace['line']); $this->logger->err($traceMessage); } } }
А затем зарегистрируйте слушателя.
kernel.listener.your_listener_name: class: FQCN\Of\ExceptionListener tags: - { name: kernel.event_listener, event: kernel.exception, method: onKernelException , priority: -1} - { name: monolog.logger, channel: mychannel } arguments: - "@logger"
Вы можете настроить его как свое требование.
Мне нравится решение из документов Symfony . Все, что вам нужно сделать, это добавить следующий код в свой файл services.yml
:
services: my_service: class: Monolog\Processor\IntrospectionProcessor tags: - { name: monolog.processor }
Это использует IntrospectionProcessor
, проверенный процессор, чтобы добавить дополнительную информацию в ваш журнал. Он вытаскивает информацию, о которой вы заботитесь, возможно, тоже.