Логирование
Дата обновления перевода 2024-07-31
Логирование
Symfony поставляется с минималистичным логгером PSR-3: Logger.
В соответствии с двенадцатифакторной методологией приложений, он отправляет сообщения, начиная
с уровня WARNING
до stderr.
Минимальный уровень лога может быть изменен путем установки переменной окружения SHELL_VERBOSITY
:
???????? SHELL_VERBOSITY |
??????????? ??????? ???? |
---|---|
-1 |
ERROR |
1 |
NOTICE |
2 |
INFO |
3 |
DEBUG |
Минимальный уровень лога, вывод по умолчанию и формат лога могут также быть изменены путем передачи соответствующих аргументов коструктору Logger. Чтобы сделать это, переопределите определение сервиса "logger" .
Логирование сообщения
Чтобы логировать сообщение, внедрите логгер по умолчанию в ваш контроллер или сервис:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
use Psr\Log\LoggerInterface;
// ...
public function index(LoggerInterface $logger): Response
{
$logger->info('I just got the logger');
$logger->error('An error occurred');
// сообщения логов могут содержать заполнители, которые являются именами переменных,
// обернутых в скобки, чьи значения передаются в качестве второго аргумента
$logger->debug('User {userId} has logged in', [
'userId' => $this->getUserId(),
]);
$logger->critical('I left the oven on!', [
// добавить дополнительную информацию "контекста" в ваши логи
'cause' => 'in_hurry',
]);
// ...
}
Добавление заполнителей в сообщения логов рекомендуется потому, что:
- Проще проверять сообщения логов, потому что многие средства ведения логов группируют одинаковые сообщения логов, за исключением некоторых значений переменных внутри них;
- Такие сообщения логов гораздо проще переводить;
- Это лучше для безопасности, потому что экранирование может быть выполнено путем реализации с учетом контекста.
Сервис logger
имеет разные методы для разных уровней/приоритетов логирования. См.
LoggerInterface, чтобы увидеть список всех методов логгера.
Monolog
Symfony безупречно интегрируется с Monolog, наиболее популярной PHP-библиотекой логгирования, чтобы создавать и хранить сообщения логов в множестве разнообразных место и запускать разные действия.
Например, используя Monolog вы можете сконфигурировать логгер так, чтобы он делал разные вещи, основываясь на уровне сообщения (например, отправлять email при возникновении ошибки).
Выполните эту команду, чтобы установить логгер, основанный на Monolog, перед его использованием:
1
$ composer require symfony/monolog-bundle
Следующие разделы предполагают, что Monolog установлен.
Где хранятся логи
По умолчанию, логи записываются в файл var/log/dev.log
когда вы находитесь в
окружении dev
.
В окружении prod
, логи записываются в стрим STDERR PHP, что лучше всего
работает в современных контейнерных приложениях, развернутых на серверах без
разрешений записи на диск.
Если вы предпочитаете хранить логи производства в файле, установите path
обработчика(ов) ваших логов по пути файла для использования (например, var/log/prod.log
).
Обработчики: Запись логов в разных локациях
Логгер имеет кучу обработчиков и каждый может быть использован для записи логов в различных локациях (например, файлах, базе данных, Slack, и т.д.).
Tip
Вы также можете конфигурировать "каналы" логирования, которые схожи с категориями. Каждый канал может иметь свои собственные обработчики, что означает, что вы можете хранить разные сообщения логов в разных местах. См. Обработчики каналов.
Symfony предварительно конфигурирует некоторые базовые обработчики в файлах
конфигурации по умолчанию monolog.yaml
. Посмотрите на них, чтобы увидеть
настоящие примеры.
Этот пример использует два обработчика:stream
(чтобы записывать в файл)
и syslog
, чтобы записывать логи, используя функцию syslog:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# config/packages/monolog.yaml
monolog:
handlers:
# этот ключ "file_log" может быть чем угодно
file_log:
type: stream
# логировать в var/log/(environment).log
path: "%kernel.logs_dir%/%kernel.environment%.log"
# логировать *все* сообщения (debug - самый низший уровень)
level: debug
syslog_handler:
type: syslog
# логировать сообщения уровня ошибок и выше
level: error
Это определяет стек обработчиков и каждый обработчик называется в порядке, в котором он определен.
Note
Если вы хотите переопределить конфигурацию monolog
через другой файл конфигурации,
вам нужно будет переопределить весь стег handlers
. Конфигурация из двух файлов не может
быть объединена, потому что порядок важен, а слияние не позволяет контролировать очередность.
Обработчики, которые изменяют записи логов
Вмето того, чтобы записовать файлы логов где-либо, некоторые обработчики используются,
чтобы фильтровать или изменять записи логов перед тем, как отправлять их другим
обработчикам. Один мощный встроенный обработчик под названием fingers_crossed
используется в окружении prod
по умолчанию. Он сохраняет все сообщения логов во
время запроса, но передает им второму обработчику только если одно из сообщений
достигает уровня action_level
. Возьмем этот пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# config/packages/monolog.yaml
monolog:
handlers:
filter_for_errors:
type: fingers_crossed
# если *один* лог - ошибка или выше, передать *все* в file_log
action_level: error
handler: file_log
# теперь переданы *все* логи, но только если один из них ошибка или выше
file_log:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
# все еще передаются *все* логи, и все еще только если логи - ошибка или выше
syslog_handler:
type: syslog
level: error
Теперь, даже если одна запись лога имеет уровень error
или выше, то все записи
логов для этого запроса сохраняются в файл с помощью обработчика file_log
. Это
означает, что ваш файл логов будет содержать все детали о проблематичном запросе,
что значительно облегчит отладку!
Tip
Обработчик, называнный "file_log" не будет включен в стопку, так как он
используется в качестве гнездового обработчика fingers_crossed
.
Все встроенные обработчики
Monolog поставляется со многими встроенными обработчиками для отправки логов по почте, отправки их в Loggly, или для оповещения вас в Slack. Они документируются внутри самого MonologBundle. Для полного списка, см. Конфигурация Monolog.
Как чередовать ваши файлы логов
Со временем, файлы логов могут вырасти огромными, как во время разработки, так и в производстве. Наилучшей практикой решения является исползование инструмента вроде команды Linux logrotate для чередования файлов логов до того, как они станут слишком большими.
Еще одна опция - заставить Monolog чередовать файлы за вас, используя обработчик
rotating_file
. Этот обработчик создает новый файл логов каждый день, а также
может удалять старые файлы автоматически. Чтобы использовать его, просто установите
опциюtype
вашего обработчика как rotating_file
:
1 2 3 4 5 6 7 8 9 10
# config/packages/dev/monolog.yaml
monolog:
handlers:
main:
type: rotating_file
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
# максимальное количество хранящихся файлов логов
# по умолчанию равняется нулю, что означает бесконечное количество
max_files: 10
Использование логгера внутри сервиса
Если ваше приложение использует автоконфигурацию сервиса ,
любой сервис, клас которого реализует Psr\Log\LoggerAwareInterface
, будет получать
вызов к своему методу setLogger()
с сервисами логгера по умолчанию переданными в
качестве сервиса.
Если вы хотите использовать свои обственные сервисы, предварительно сконфигурированный логгер,
который использует определенный канал (по умолчанию app
), вы можете либо
автомонтировать кналы monolog или использовать тег
monolog.logger
со свойством channel
, как объясняется в
справочнике внедрения зависимостей .
Добавление дополнительных данных в каждый лог (например, метки уникального запроса)
Monolog также поддерживает процессоры: функции, которые могут динамически добавлять дополнительную информацию к вашим записями логов.
См. Как добавлять дополнительные данные в сообщения логов через процессор, чтобы узнать детали.
Работа с локами в долгосрочных процессах
Во время долгосрочных процессов логи могут накапливаться в Monolog и вызывать
переполнение буфера, увеличение памяти или даже нелогичные логи. Данные Monolog в памяти
могут быть очищены с помощью метода reset()
в экземпляре Monolog\Logger
.
Обычно этот метод следует вызывать между каждым заданием или задачей, над которой работает
долгосрочный процесс.
Узнайте больше
- Как сконфигурировать Monolog так, чтобы он отправлял ошибки по электронной почте
- Как записывать логи сообщений в разные файлы
- Как определить пользовательский форматировщик логирования
- Как добавлять дополнительные данные в сообщения логов через процессор
- Обработчики
- Как сконфигурировать Monolog для исключения конкретных HTTP-кодов из лога
- Как сконфигурировать Monolog так, чтобы он отображал конспольные сообщения