Установил версию 5.0.7 и разобрался как работает логирование, решил поделиться в виде конфига с комментариями.
monolog:
# список хедлеров, которые применяются согласно порядку в котором они описаны
handlers:
main:
# type: fingers_crossed - один из преднастроенных symfony-хендлеров, см:
# vendor/symfony/monolog-bundle/DependencyInjection/MonologExtension.php:376
# все возможные типы и их атрибуты:
# vendor/symfony/monolog-bundle/DependencyInjection/Configuration.php:25
# Работает так: все log-records копятся и сохраняются только тогда, когда появляется
# log-record с уровнем равным или больше чем указано в action_level (см. ниже)
type: fingers_crossed
action_level: notice
# получается, что в хендлере есть хедлер, значит log-record будет передана в nested
handler: nested
# просим symfony не логировать эксепшены, которые возникают в результате выброса
# которых клиенту отдается один из перечисленных здесь http-status-ов. Подробнее
# https://symfony.com/doc/current/logging/monolog_exclude_http_codes.html и если
# присмотреться к сноске внизу, то видно, что это работает не всегда, например когда
# Symfony-эксепшен выбрасывается из какого-либо сервиса, то Symfony воспринимает это как
# ошибку и пытается залогировать ее.
excluded_http_codes: [404, 405]
formatter: App\Infrastructure\Logger\JsonFormatterDecorator
# лучше задавать значение 1, причины:
# - если возникает ошибка, которую не способен обработать symfony хендлер ошибок (например
# рекурсия или php-скрипт съел всю память и упал), то ни одна лог-запись возникшая до этого
# не будет записана (ведь все упадет)
# - полезно когда логируем в нужных местах чтобы отдебажить какой-то сценарий (ряд
# логических действий), который конечно не завершается ошибкой, то ни одна лог-запись
# возникшая до этого не будет записана
buffer_size: 1 # How many messages should be saved? Prevent memory leaks
# т.к. данный хедлер используется в main, то это всего лишь часть хедлера main
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: notice
# в dev-режиме был исключен канал событий, в проде он логируется:
# channels: ["!event"]
# console хендлер по-умолчанию ничего не делает, потому что его $this->output равен null, но
# хендлер подписан на события, которые делают
# setOutput( \Symfony\Component\Console\Output\StreamOutput ), подробнее:
# \Symfony\Bridge\Monolog\Handler\ConsoleHandler::getSubscribedEvents
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
monolog:
handlers:
main:
type: fingers_crossed
handler: nested
# указываем удовлетворяющую стратегию фильтрации:
activation_strategy: monolog.strategy.activation.seo_strategy
# но, теперь настройка excluded_http_codes не работает, ведь она часть стратегии активации
nested:
type: stream
path: php://stderr
level: "debug"
formatter: monolog.formatter.jsonИ теперь в файле config/services.yaml настраиваем каналы более гибко:
# Объявляем сервис обработки логов по каналам, другими словами - фильтрация ошибок по уровню.
# Ниже разрешаем логировать все сообщения всех каналов с уровнем NOTICE и выше, а для канала "app"
# все уровни начиная с DEBUG.
Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy:
arguments:
$defaultActionLevel: !php/const Monolog\Logger::NOTICE
$channelToActionLevel:
app: !php/const Monolog\Logger::DEBUG
# Переопределяем стратегию логирования для монолог-хендлера fingers_crossed при этом указывая
# подавление HTTP-ошибок: 404, 405 (уровень error) так же как это делал excluded_http_codes
monolog.strategy.activation.seo_strategy:
class: Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy
arguments:
$inner: '@Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy'
$exclusions:
- { code: 404, urls: [] }
- { code: 405, urls: [] }monolog:
handlers:
main:
type: service
id: My\LogHandler
Увы, указывать атрибут handler бесполезно где-либо, кроме хендлера type: fingers_crossed т.к. атрибут будет проигнорирован, например в следующем примере в оба хендлера будет передана log-record:
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
handler: custom
custom:
type: service
id: My\LogHandler
В любом хендлере (кроме своего) Вы можете использовать интересный атрибут "include_stacktraces: true" благодаря которому, в log-record будут добавлены стек-трейсы всех эксепшенов, которые Вы передадите в контекст log-record, давайте на примере:
$exception1 = new \Exception();
$exception2 = new \Exception();
$logger->error('message with two exception trace', [$exception1, $exception2]);
Особенность: "include_stacktraces" работает только, если Вы используете один из следующих форматеров: JsonFormatter, LineFormatter, которые в свою очередь для преобразования эксепшена используют функцию NormalizerFormatter::normalizeException()
Посмотреть список каналов можно командой: bin/console debug:autowiring | grep monolog
Мне выдало:
Psr\Log\LoggerInterface (monolog.logger)
Psr\Log\LoggerInterface $cacheLogger (monolog.logger.cache)
Psr\Log\LoggerInterface $consoleLogger (monolog.logger.console)
Psr\Log\LoggerInterface $deprecationLogger (monolog.logger.deprecation)
Psr\Log\LoggerInterface $doctrineLogger (monolog.logger.doctrine)
Psr\Log\LoggerInterface $eventLogger (monolog.logger.event)
Psr\Log\LoggerInterface $httpClientLogger (monolog.logger.http_client)
Psr\Log\LoggerInterface $phpLogger (monolog.logger.php)
Psr\Log\LoggerInterface $profilerLogger (monolog.logger.profiler)
Psr\Log\LoggerInterface $requestLogger (monolog.logger.request)
Psr\Log\LoggerInterface $routerLogger (monolog.logger.router)
Psr\Log\LoggerInterface $securityLogger (monolog.logger.security)
Psr\Log\LoggerInterface $translationLogger (monolog.logger.translation)Удачи господа.
Источники: 1 - 2 - 3 - 4 - 5 - 6