Как записать логи в файл

Обновлено: 06.07.2024

Людям свойственно ошибаться. Это относится не только к разработчикам, но и к пользователям. В ходе разработки мы контролируем процесс и можем разобраться в неправильном поведении программы простой отладкой. А вот расследовать случай, который произошёл в production-окружении, не всегда просто. В таких ситуациях на помощь приходят журналы. И чтобы от них действительно была польза, их нужно вести правильно.

Логирование — это процесс ведения таких журналов. Помогает обнаружить скрытые ошибки, разобраться в проблемах пользователей и просто понять, что произошло на самом деле. В простейшей реализации такие журналы пишутся в текстовом файле и содержат точное время и описание произошедшего события. В логировании есть множество подходов и давно определены лучшие практики — это хорошо для нас.

В этой статье разберёмся, как правильно организовать ведение журналов в PHP-приложении, как эффективно с ними взаимодействовать и какие библиотеки и инструменты могут быть полезны.

Стандарт PSR-3. Уровни логирования

PSR — это свод рекомендаций для PHP-разработчиков. Он содержит советы по оформлению кода, некоторые интерфейсы и другие рекомендации. Один из его документов (PSR-3) посвящён реализации логера.

Знакомство с этими рекомендациями предлагаю начать с уровней логирования, которые в них предлагаются.

  • DEBUG — отладочная информация, подробно раскрывающая детали события;
  • INFO — любые интересные события. Например, когда пользователь авторизовался;
  • NOTICE — важные события в рамках ожидаемого поведения;
  • WARNING — исключительные ситуации, не являющиеся ошибками. Например, использование устаревшего метода, неправильный запрос в API;
  • ERROR — ошибки, которые следует отслеживать, но они не требуют срочного исправления;
  • CRITICAL — критическое состояние или событие. Например, недоступность компонента, неожиданное исключение (Exception);
  • ALERT — ошибка или событие, требующие срочных действий. Например, когда база данных недоступна;
  • EMERGENCY — ситуация, когда программа или система полностью выведены из строя.

Чтобы использовать эти уровни, достаточно добавлять их название к строке каждой записи журнала. Например:

На уровни ALERT и EMERGENCY часто ставят дополнительное информирование, например по SMS. По INFO можно легко восстановить последовательность действий пользователя, по DEBUG — узнать точные значения переменных, результат работы функции в определённом месте и прочее.

PSR-3. Интерфейс для класса-логера

Помимо класса с уровнями, PSR-3 предлагает нам интерфейс для реализации собственных логеров — LoggerInterface. Соблюдать его очень полезно, так как большинство существующих библиотек его поддерживает. Если вы решите заменить свой логер на другой, просто подключите вместо него новый класс.

LoggerInterface требует реализации методов ведения журнала — и чтобы она учитывала уровни, которые мы разобрали выше. Создадим собственный класс-логер, который будет соответствовать этому интерфейсу и делать записи в файл.

Для начала загрузим код стандарта PSR-3 с помощью Composer.

В загруженном пакете содержится несколько классов, трейтов и интерфейсов. Среди них — LogLevel, который мы разобрали выше, и интересующий нас в данный момент LoggerInterface. Давайте создадим новый класс, реализующий этот интерфейс. Важно: убедитесь, что у вас подключён класс-автозагрузчик (vendor/autoload.php).

Класс мы создали. Но чтобы он удовлетворял требованиям стандарта, нужно написать все методы, описанные в интерфейсе. Самый важный из них — log. В нём будет указана основная логика записи в файл.

Для полного удовлетворения интерфейса LoggerInterface нам осталось написать реализацию для методов emergency, alert, critical, error, warning, notice, info и debug, которые соответствуют уровням (их мы разобрали выше). Их реализация сводится к очень простому принципу: мы вызываем метод log, передав в него необходимый уровень.

Использование логера

Теперь, когда наш класс реализует интерфейс, предложенный стандартом PSR-3, мы можем легко задействовать его в любом месте. Например, в файле index.php:

Или в любом другом классе.

Обратите внимание: в качестве типа аргумента конструктора мы указываем не конечную реализацию (FileLogger), а именно интерфейс стандарта PSR-3. Это удобно, потому что позволяет легко заменять применяемый логер на любой другой, поддерживающий этот интерфейс.

Контекст

Вы могли заметить, что все методы интерфейса LoggerInterface содержат аргумент $context. Зачем он нужен?

Контекст предназначен для передачи вспомогательной и зачастую динамичной информации. Например, если вы делаете отладочную запись (уровень debug), можно передать в контекст значение переменной.

Чтобы применять этот аргумент, нам нужно поддержать его в методе log. Давайте доработаем его, учитывая, что $context — массив.

Теперь в любом месте вызова логера мы можем передать вторым аргументом массив дополнительной информации.

В результате мы получим запись следующего вида:

Библиотека Monolog

Несмотря на всю простоту принципа ведения журналов, в этой области широкий простор для модификаций. Мы могли бы поддержать другие форматы записей, реализовать отправку SMS или элементарно дать возможность менять имя конечного файла логов.

Здорово, что всё это уже реализовано в большинстве библиотек. Одна из самых распространённых – monolog.

Среди весомых преимуществ этого пакета:

  • полная поддержка PSR-3;
  • поддержка разных принципов обработки логов в зависимости от уровня;
  • поддержка имён каналов (имена логеров);
  • очень широкая поддержка фреймворков.

Чтобы начать использовать этот прекрасный инструмент, установим его с помощью Composer.

Использование Monolog

Работа библиотеки monolog основывается на обработчиках. Они позволяют задавать конкретное поведение в ответ на события логирования. Например: запись в файл — это специальный обработчик, который называется StreamHandler. Давайте заменим использование нашего класса на загруженную библиотеку.

Если мы запустим этот код, в файле gb.log появится запись следующего вида:

Очень похоже на то, что было у нас ранее, кроме добавления имени канала (gb-demo).

Важная особенность обработчиков monolog: им можно задать уровень, на котором они работают. Например, чтобы писать все ошибки в отдельный файл.

Подключённый на уровень ERROR обработчик будет принимать на себя все записи уровня ERROR и выше. Поэтому вызов метода emergency попадает в оба файла: gb.log и errors.log

Такое простое разделение записей по уровням значительно упрощает для нас реагирование на ошибки. Ведь больше не нужно искать их среди всех записей в журнале. Это простая и полезная функция.

Все записи от одного запроса

Когда мы разрабатываем проект, журналы читаются очень просто, они последовательны и ясны. Но когда продуктом пользуются несколько человек, логи могут перемешиваться и больше запутывать, чем помогать. Для решения этой проблемы есть простой трюк. Вместо имени канала (логера) используйте уникальный идентификатор сессии. Получить его можно с помощью встроенной функции session_id(). При этом сессия должна быть обязательно запущена с помощью session_start()

Рассмотрим пример реализации такого приёма:

Что нам даёт такая простая доработка? Важную возможность — группировать все записи запросам пользователя.

Что дальше?

Monolog поддерживает множество полезных готовых обработчиков, на которые стоит обратить внимание:

  • TelegramBotHandler — отправляет записи в Telegram от имени бота. Пригодится для высоких уровней логирования;
  • SlackHandler — похож на предыдущий, но отправляет записи в Slack;
  • SwiftMailerHandler — позволяет отправлять записи по email;
  • ChromePHPHandler – даёт доступ к журналам прямо из браузера Chrome в режиме Live.

Заключение

Логирование поможет исправлять ошибки на ранних этапах разработки и быть уверенными, что ничего не сломалось в новой версии кода. А ещё расследовать случаи ваших пользователей и иметь общее видение проекта.

Минимальный уровень лога может быть изменен путем установки переменной окружения SHELL_VERBOSITY :

значение SHELL_VERBOSITY Минимальный уровень лога
-1 ERROR
1 NOTICE
2 INFO
3 DEBUG

Минимальный уровень лога, вывод по умолчанию и формат лога могут также быть изменены путем передачи соответствующих аргументов коструктору Logger . Чтобы сделать это, переопределите определение сервиса “logger” .

Сервис logger имеет разные методы для разных уровней/приоритетов логирования. См. LoggerInterface, чтобы увидеть список всех методов логгера.

Monolog¶

Выполните эту команду, чтобы установить логгер, основанный на Monolog, перед его использованием:

Следующие разделы предполагают, что Monolog установлен.

Где хранятся логи¶

По умолчанию, логи записываются в файл var/log/dev.log когда вы находитесь в окружении dev . В окружении prod , логи записываются в var/log/prod.log , но только во время запроса, в котором была ошибка или высокоприоритетный лог (т.е. error() , critical() , alert() или emergency() ).

Чтобы контролировать это, вы конфигурируете различные обработчики, которые обрабатывают записи логов, иногда вносят в них изменения и в конце-концов сохраняют их.

Обработчики: Запись логов в разных локациях¶

Логгер имеет кучу обработчиков и каждый может быть использован для записи логов в различных локациях (например, файлах, базе данных, Slack, и т.д.).

Symfony предварительно конфигурирует некоторые базовые обработчики в файлах конфигурации по умолчанию monolog.yaml . Посмотрите на них, чтобы увидеть настоящие примеры.

Этот пример использует два обработчика: stream (чтобы записывать в файл) и syslog , чтобы записывать логи, используя функцию syslog :

Это определяет стек обработчиков и каждый обработчик называется в порядке, в котором он определен.

Если вы хотите переопределить конфигурацию monolog через другой файл конфигурации, вам нужно будет переопределить весь стег handlers . Конфигурация из двух файлов не может быть объединена, потому что порядок важен, а слияние не позволяет контролировать очередность.

Обработчики, которые изменяют записи логов¶

Теперь, даже если одна запись лога имеет уровень error или выше, то все записи логов для этого запроса сохраняются в файл с помощью обработчика file_log . Это означает, что ваш файл логов будет содержать все детали о проблематичном запросе, что значительно облегчит отладку!

Обработчик, называнный “file_log” не будет включен в стопку, так как он используется в качестве гнездового обработчика fingers_crossed .

Все встроенные обработчики¶

Monolog поставляется со многими встроенными обработчиками для отправки логов по почте, отправки их в Loggly, или для оповещения вас в Slack. Они документируются внутри самого MonologBundle. Для полного списка, см. Конфигурация Monolog.

Как чередовать ваши файлы логов¶

Со временем, файлы логов могут вырасти огромными, как во время разработки, так и в производстве. Наилучшей практикой решения является исползование инструмента вроде команды Linux logrotate для чередования файлов логов до того, как они станут слишком большими.

Еще одна опция - заставить Monolog чередовать файлы за вас, используя обработчик rotating_file . Этот обработчик создает новый файл логов каждый день, а также может удалять старые файлы автоматически. Чтобы использовать его, просто установите опцию``type`` вашего обработчика как rotating_file :

Использование логгера внутри сервиса¶

Если ваше приложение использует автоконфигурацию сервиса , любой сервис, клас которого реализует Psr\Log\LoggerAwareInterface , будет получать вызов к своему методу setLogger() с сервисами логгера по умолчанию переданными в качестве сервиса.

Если вы хотите использовать свои обственные сервисы, предварительно сконфигурированный логгер, который использует определенный канал (по умолчанию app ), вы можете либо автомонтировать кналы monolog или использовать тег monolog.logger со свойством channel , как объясняется в справочнике внедрения зависимостей .

Добавление дополнительных данных в каждый лог (например, метки уникального запроса)¶

Monolog также поддерживает процессоры: функции, которые могут динамически добавлять дополнительную информацию к вашим записями логов.

Logging

Логи можно сравнить с уликами на месте преступления, а разработчиков — с криминалистами. Роль логов трудно переоценить, ведь когда необходимо найти баг или причину сбоя, сразу обращаются к ним. Подобно тому, как отсутствие улик приводит к нераскрытым делам, отсутствие содержательных логов осложняет диагностику и устранение ошибок, превращая их в затянувшийся или вовсе невыполнимый процесс. Мне приходилось наблюдать, как люди мучились с такими инструментами, как Strace и tcpdump, или развертывали новый код в продакшене во время сбоя лишь затем, чтобы получить больше лог-файлов для выявления проблемы.

Как говорится: “Хорошо подготовиться — половину дела сделать”, так что каждому профессиональному разработчику следует научиться эффективно вести логи и быть готовым к работе с ними. В данной статье мы не только рассмотрим список полезных практик логирования в приложении, но и разберем теоретические основы данного процесса: что записываем, когда и кто этим должен заниматься.

Как осуществляется процесс отладки?

Прежде чем начать разговор о логах, необходимо ответить на два вопроса:

  1. Что такое программа?
  2. Как осуществляется отладка, в которой логи играют важную роль?

Программа как переходы состояний

Программа — это серия переходов между состояниями.

Состояния — это вся информация, которую программа хранит в своей памяти в определенный момент времени, а код программы определяет то, как она переходит от одного состояния к другому. Разработчики, использующие императивные языки программирования, такие как Java, зачастую акцентируют больше внимания на самом процессе (коде), чем состояниях. Однако понимание того, что программа является серией состояний, очень важно, поскольку они существенно ближе к тому, что должна делать программа, а не как.

Допустим, есть робот, задача которого — заполнить бензобак машины. Если мы рассмотрим выполняемые им действия как переходы состояний, то ему необходимо перейти от состояния (бак пустой, в наличии 50 $) к состоянию (бак полный, в наличии 15 $). Если же мы описываем его как процесс, то он должен найти заправку, доставить туда машину и заплатить. Конечно же, процесс имеет большое значение, но состояния дают более точную оценку правильности программы.

Отладка

Отладка — это мысленная реконструкция переходов состояний. Разработчики проигрывают в уме сценарий программы: как она принимает вводные данные, проходит через ряд изменений состояний и осуществляет вывод, а затем определяют, что пошло не так. Во время разработки этот мыслительный процесс подкрепляется использованием отладчика. Однако в продакшене делать это уже гораздо сложнее, поэтому на данном этапе чаще прибегают к помощи логов.

Что записывать в лог ?

Понимая суть процесса отладки, мы с легкостью ответим на этот вопрос:

Логи должны содержать информацию, необходимую для реконструкции переходов состояний.

Невозможно, да и не нужно, фиксировать все состояния во все отрезки времени. Например, полиции достаточно лишь нескольких точных набросков, а не видеоклона, для поимки преступника. Тоже самое относится и к логам: разработчикам нужно только внести в них информацию о том, когда происходит переход в критическое состояние. Кроме того, логи должны содержать ключевые характеристики текущего состояния и причину перехода.

Переход в критическое состояние

Не все переходы состояний стоит записывать в лог. Важно рассмотреть программу как серию изменяемых состояний, разделить их на фазы и затем сосредоточиться на времени, когда выполнение переходит от одной фазы к другой.

Предположим, что существуют 3 фазы запуска приложения:

  • загрузка настроек программы;
  • подключение к зависимостям;
  • запуск сервера.


Запуск приложения с точки зрения переходов состояний

Было бы очень разумно вести логи в начале и конце каждой фазы. Если бы произошла ошибка на этапе подключения к зависимостям и приложение бы зависло, то логи отчетливо показали бы, что после загрузки настроек оно вошло во вторую фазу процесса, не завершив его. Располагая этой информацией, разработчики смогли бы быстро определить проблему.

Ключевые характеристики

Логирование состояний напоминает создание эскизов программы только с учетом ключевых характеристик основ бизнес-логики. Если есть информация закрытого характера, например персональные данные, то ее также нужно записать в лог, но в завуалированном виде.

Причина перехода состояния

Логирование причины перехода состояния чрезвычайно полезно для отладки. Логи должны кратко охватывать содержание предыдущих и следующих состояний, а также объяснять их причины. Они помогают разработчикам получить общую картину и ориентироваться в процессе реконструкции (отладки) выполнения программы.

Пример

Рассмотрим простой пример для обобщения всего сказанного. Предположим, что сервер получает некорректный номер социального страхования, и разработчик намерен внести в лог информацию об этом событии.

Вот несколько анти-шаблонов логов, в которых отсутствуют ключевые характеристики состояния и причины:

  • [2020–04–20T03:36:57+00:00] server.go: Error processing request (Запрос на обработку ошибок)
  • [2020–04–20T03:36:57+00:00] server.go: SSN rejected (Номер социального страхования отклонен)
  • [2020–04–20T03:36:57+00:00] server.go: SSN rejected for user UUID “123e4567-e89b-12d3-a456–426655440000” (Номер социального страхования отклонен для пользователя UUID “123e4567-e89b-12d3-a456–426655440000”)

[2020–04–20T03:36:57+00:00] server.go: Received a SSN request(track id: “e4a49a27–1063–4ab3–9075-cf5faec22a16”) from user uuid “123e4567-e89b-12d3-a456–426655440000”(previous state), rejecting it(next state) because the server is expecting SSN format AAA-GG-SSSS but got **-***(why)

([2020–04–20T03:36:57+00:00] server.go: Получен запрос номера социального страхования (трек id: “e4a49a27–1063–4ab3–9075-cf5faec22a16”) от пользователя user uuid “123e4567-e89b-12d3-a456–426655440000” (предыдущее состояние), запрос отклонен (следующее состояние), так как сервер требует номер социального страхования в формате AAA-GG-SSSS, а получил **-*** (причина)

Кто должен записывать логи?

Типичная ошибка, которую многие допускают, связана с тем, “кто” должен фиксировать информацию. Ведение логов не теми функциями оборачивается дублированием или дефицитом информации.

Программа как уровни абстракции

Большинство грамотно созданных программ подобны пирамиде с уровнями абстракции. Классы/функции верхних уровней разбивают сложную задачу на подзадачи, тогда как классы/функции нижних уровней абстрагируют реализацию подзадач, таких как черные ящики, и предоставляют интерфейсы для вызова верхним уровнем. Эта парадигма облегчает программирование, поскольку каждый уровень сосредоточен на своей логике, не беспокоясь о всевозможных деталях.


Уровни абстракции

Ведите логи только на правильных уровнях

Вернемся к нашему примеру проверки корректности номера социального страхования. Допустим, что логика его проверки обернута в класс Validator следующим образом:

Есть еще другая функция, которая проверяет запрос, обновляющий информацию о пользователе, и вызывает проверку номера социального страхования.

Существует два местоположения (A и B) для записи логов об ошибке проверки номера социального страхования, но только B владеет достаточной для этого информацией . В A программа не знает, ни какой запрос она обрабатывает, ни от какого пользователя он поступает. Логирование просто добавляет деталей. Будет лучше, если validateUserUpdateRequest выбросит ошибку из вызывающего компонента (validateRequest), содержащего больше контекста для лога.

Однако это вовсе не означает, что логирование на нижних уровнях программы совершенно необязательно, особенно когда они не раскрывают ошибки верхним уровням. Например, сетевой уровень может иметь встроенную логику повторных попыток, из чего следует, что верхние уровни не замечают проблем с прерывающимися соединениями. В общем, нижние уровни могут вести логи больше на уровне DEBUG, чем на INFO, в целях сокращения многословности. При необходимости разработчики могут настроить уровень лога для получения большего количества деталей.

Сколько должно быть логов?

Существует очевидное соотношение между объемом логов и их полезностью. Чем более содержательные логи, тем легче реконструировать переходы состояний. Вы можете воспользоваться двумя способами контроля количества логов:

Установите соотношение между логами и рабочей нагрузкой

Для контроля объема логов сначала важно его правильно измерить. Большинство программ имеют 2 типа рабочей нагрузки:

  • получение рабочих элементов (запросов) и последующая реакция на них;
  • запрос рабочих элементов откуда-либо и последующее выполнение действий.

где X можно определить, изучив код. Разработчики должны иметь хорошее представление об X-факторах для своих программ и приводить их в соответствие с возможностями логирования и бюджетом. Вот еще несколько типичных случаев X:

  • 0 < X < 1. Это значит, что логи отбираются выборочно, и не у всех рабочих элементов они есть, например ведётся запись только ошибок или используются другие алгоритмы отбора логов. Это способствует снижению объемов лога, но при этом может ограничить возможности поиска проблемы.
  • X

Используйте уровни логов

Что, если X все еще слишком большой даже после оптимизации? На помощь приходят уровни логов. Если X намного больше, чем 1, то можно поместить логи на уровень DEBUG, тем самым снизив X уровня INFO. В процессе устранения неполадок программа может временно выполняться на этом уровне для предоставления дополнительной информации.

Краткие выводы

Чтобы профессионально писать логи, следует рассматривать программу как серию переходов состояний с уровнями абстракции. Владея теоретическими знаниями, можно ответить на ключевые вопросы о логировании в приложении:

1.Когда писать логи? В момент перехода в критическое состояние.

2.Что записывать в лог? Ключевыехарактеристики текущего состояния и причину перехода состояния.

3.Кто должен записывать логи? Логирование должно происходить на правильном уровне, содержащем достаточно информации.

Давайте разберем реальные случаи, в которых логирование решало бы проблему. Вот пример из моей работы. Есть точки приложений, которые интегрируются с другими сервисами. Я использую логирование этих точек для “алиби”: если интеграция не сработает, будет легко разобраться, с какой стороны возникла проблема. Еще желательно логировать важную информацию, которая сохраняется в базу данных. Например создание пользователя администратора. Это как раз то, что хорошо бы логировать.

Инструменты для логирования в Java

  • log4j
  • JUL — java.util.logging
  • JCL — jakarta commons logging
  • Logback
  • SLF4J — simple logging facade for java

System.err.println

Первоначально был, разумеется, System.err.println (вывод записи в консоль). Его и сейчас используют для быстрого получения лога при дебаге. Конечно, говорить о каких-то настройках здесь не приходится, поэтому просто запомним его и пойдем дальше.

Log4j

Это уже было полноценное решение, которое создавалось из потребностей разработчиков. Получился действительно интересный инструмент, который можно использовать. В силу разных обстоятельств это решение так и не попало в JDK, чем очень расстроило все комьюнити. В log4j были возможности по конфигурации таким образом, чтобы можно было включить логирование в пакете com.example.type и выключить его в подпакете com.example.type.generic . Это позволяло быстро отсечь то, что нужно логировать, от того, что не нужно. Здесь важно отметить, что есть две версии log4j: 1.2.х и 2.х.х, которые несовместимы друг с другом. log4j добавил такое понятие как appender, то есть инструмент, с помощью которого записываются логи и layout — форматирование логов. Это позволяет записывать только то, что нужно и как нужно. Больше о appender поговорим чуть позже.

JUL — java.util.logging

Одно из ключевых преимуществ это решения — JUL включен в JDK (Java development kit). К сожалению, при его разработке за основу взяли не популярный log4j, а решение от IBM, что и повлияло на его развитие. По факту на данный момент JUL есть, но им никто не пользуется. Из “такого себе”: в JUL уровни логирования отличаются от того, что есть в Logback, Log4j, Slf4j, и это ухудшает понимание между ними. Создание логгера более менее похожее. Для этого нужно сделать импорт: Имя класса специально передается для того, чтобы знать, откуда идет логирование. Начиная с Java 8, можно передавать Supplier<String> . Это помогает считать и создавать строку только в тот момент, когда это действительно нужно, а не каждый раз, как это было до этого. Только с выходом Java 8 разработчики решили важные проблемы, после чего JUL по-настоящему стало возможно в использовании. А именно, методы с аргументом Supplier<String> msgSupplier , как показано ниже:

JCL — jakarta commons logging

Из-за того, что долгое время не было промышленного стандарта в логировании и был период, когда многие создавали свой кастомный логгер, решили выпустить JCL — общую обертку, которая использовалась бы над другими. Почему? Когда в проект добавлялись какие-то зависимости, они могли использовать логгер, отличный от логгера на проекте. Из-за этого они транзитивно добавлялись в проект, что создавало реальные проблемы при попытке все это собрать воедино. К сожалению, обертка была очень бедна на функциональность и никаких дополнений не вносила. Наверное, было бы удобно, если бы все использовали JCL для работы. Но на деле так не получалось, поэтому на данный момент применять JCL — не лучшая идея.

Logback

  • улучшена производительность;
  • добавлена нативная поддержка slf4j;
  • расширена опция фильтрации.

SLF4J — simple logging facade for java

Что нужно логировать

  1. Начало/конец работы приложения. Нужно знать, что приложение действительно запустилось, как мы и ожидали, и завершилось так же ожидаемо.
  2. Вопросы безопасности. Здесь хорошо бы логировать попытки подбора пароля, логирование входа важных юзеров и т.д.
  3. Некоторые состояния приложения. Например, переход из одного состояния в другое в бизнес процессе.
  4. Некоторая информация для дебага, с соответственным уровнем логирования.
  5. Некоторые SQL скрипты. Есть реальные случаи, когда это нужно. Опять-таки, умелым образом регулируя уровни, можно добиться отличных результатов.
  6. Выполняемые нити(Thread) могут быть логированы в случаях с проверкой корректной работы.

Популярные ошибки в логировании

  1. Избыток логирования. Не стоит логировать каждый шаг, который чисто теоретически может быть важным. Есть правило: логи могут нагружать работоспособность не более, чем на 10%. Иначе будут проблемы с производительностью.
  2. Логирование всех данных в один файл. Это приведет к тому, что в определенный момент чтение/запись в него будет очень сложной, не говоря о том, что есть ограничения по размеру файлов в определенных системах.
  3. Использование неверных уровней логирования. У каждого уровня логирования есть четкие границы, и их стоит соблюдать. Если граница расплывчатая, можно договориться какой из уровней использовать.

Уровни логирования

  • OFF: никакие логи не записываются, все будут проигнорированы;
  • FATAL: ошибка, после которой приложение уже не сможет работать и будет остановлено, например, JVM out of memory error;
  • ERROR: уровень ошибок, когда есть проблемы, которые нужно решить. Ошибка не останавливает работу приложения в целом. Остальные запросы могут работать корректно;
  • WARN: обозначаются логи, которые содержат предостережение. Произошло неожиданное действие, несмотря на это система устояла и выполнила запрос;
  • INFO: лог, который записывает важные действия в приложении. Это не ошибки, это не предостережение, это ожидаемые действия системы;
  • DEBUG: логи, необходимые для отладки приложения. Для уверенности в том, что система делает именно то, что от нее ожидают, или описания действия системы: “method1 начал работу”;
  • TRACE: менее приоритетные логи для отладки, с наименьшим уровнем логирования;
  • ALL: уровень, при котором будут записаны все логи из системы.

Запись и отправка логов: Appender

  • для записи в файл — решение DailyRollingFileAppender;
  • для получения данных в консоль приложения — ConsoleAppender;
  • для записи логов в базу данных — JDBCAppender;
  • для контроля передачи через TCP/IP — TelnetAppender;
  • для того, чтобы запись логов не била по быстродействию — AsyncAppender.

Узлы логирования

Читайте также: