Logger. Подключение Logger'а

Logger. Подключение Logger'а

Дорогу осилит идущий

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


Логгеры

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

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

Также может быть различным место записи логов: консоль, файл, таблица в БД или даже отправка по почте.

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

На самом деле, в Java есть встроенный логгер, доступный без внешних библиотек. Его классы расположены в пакете java.util.logging. Но по ряду исторических причин он не популярен и вместо него используются иные решения.


Спецификация

Поскольку библиотек-логгеров несколько, в свое время была разработана стандартная спецификация (или, вернее сказать, верхнеуровневый интерфейс) для логгеров в Java - SLF4J (Simple Logging Facade for Java). 

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

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

Ниже представлена схема, демонстрирующая это (и заодно обозначающая два наиболее популярных на данный момент логгера):

К слову, логгер из java.util.logging тоже соответствует интерфейсу SLF4J.


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

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

Уровень логирования - степень важности (или критичности) конкретного сообщения в рамках системы. Наличие таких уровней позволяет определить, какие сообщения требуется записывать, а какие - игнорировать в рамках конкретного запуска системы, конкретного окружения или по иным признакам.

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

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

Итак, стандартные уровни логирования в рамках SLF4J и шпаргалка по определению уровня конкретного сообщения:

На практике, безусловно, далеко не все используют все 6 уровней логирования, зачастую оставляя только INFO, WARN и ERROR или даже INFO и ERROR

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


Подключение логгера в проект

Код примера вместе с комментариями и уже выкачанными JAR-файлами логгера можно найти здесь: https://github.com/KFalcon2022/logger-sample.

Фактическая конфигурация находится в файле log4j2.properties, комментарии к ней - в log4j2.properties.example.

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


Поиск и добавление JAR

Первое, что нам необходимо сделать - найти JAR-файлы интересующей нас библиотеки. Мы будем подключать логгер log4j2.

На сайте разработчика можно скачать архив с последними актуальными версиями JAR’ников: https://logging.apache.org/log4j/2.x/download.html (см. Binary distribution files -> Binaries).

По той же ссылке (продублирую с якорем) можно увидеть пометку, что для CLASSPATH* необходимо использовать два JAR-файла: log4j-api-{version}.jar и log4j-core-{version}.jar.

* CLASSPATH - переменная окружения (возможно, вы помните другую подобную переменную - JAVA_HOME), которая хранит список путей к JAR-файлам. Именно в файлах по этим путям JVM будет искать интересующие ее классы, если не найдет их в стандартной библиотеке. Перебор JAR’ников будет происходить в порядке, заданном в списке.

Итак, для удобства выделим директорию, где будут лежать все библиотеки. Я ее создал в рамках проекта, но логичнее это делать вне его - ведь одни и те же библиотеки могут быть нужны разным проектам. Логично хранить все это богатство в одном месте. Так в моем примере появляется директория lib.


Настройка CLASSPATH и индексации в IDEA

Далее необязательный пункт, но он сделает вашу работу комфортнее:

IDEA->Ваш проект->File->Project Structure->Modules->Dependensies

Здесь можно добавить (на “+”) пути к библиотекам. 

Во-первых, это автоматически добавит их в CLASSPATH при запуске проекта (альтернатива(!) - прописывать CLASSPATH при запуске приложения через консоль или в настройках запуска в IDEA). Во-вторых, позволит IDEA проиндексировать добавленные библиотеки и использовать их при автодополнении кода (и просто перестать ругаться на “незнакомые” классы в коде).


Конфигурация логгера

Теперь библиотека добавлена в проект. Но нужно сконфигурировать сам логгер - сказать, что, как и куда ему писать.

log4j2 предоставляет несколько вариантов для конфигурации: XML, JSON, YAML или properties файлы или же программно в Java (в нескольких вариациях).

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

Я выбрал properties-файл - на мой взгляд, этот формат легче всего читать новичкам. Но в дальнейшем рекомендую использовать XML или YAML конфигурацию. Оба эти формата вам придется изучить хотя бы на базовом уровне. К счастью, это происходит легко и непринужденно в процессе работы.

С конфигурацией могут возникнуть проблемы. С одной стороны, есть исчерпывающая документация: https://logging.apache.org/log4j/2.x/manual/configuration.html

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

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

Как правило, используется несколько ресурсов логирования одновременно: консоль, RollingFile (то, что описано выше) и, опционально, какие-то дополнительные варианты записи.

Файл конфигурации обычно размещается в ресурсах проекта.


Создание объекта логгера в классе

Итак. Библиотеки подключены, конфигурация есть. Осталось написать код, использующий логгер. 

Если вы посмотрите в пример, увидите такую запись:

private final static Logger log = LogManager.getLogger(Main.class);

Это создание объекта логгера для конкретного класса, название класса - Main выступит именем этого логгера. В целом, можно сделать и один объект на приложение или не привязывать к классу, параметром можно передать и строковый литерал - т.е. можно и в рамках одного класса использовать несколько объектов логгера.

Но плюс такого подхода выше в том, что имя логгера можно прописать в сообщении лога (в паттере из примера - %logger{36}). Таким образом указывая прямо в логе из какого класса было отправлено сообщение.

Также вы можете увидеть методы логгера - нас сейчас интересуют только методы с названиями, идентичными уровням логирования. Именно они позволяют прописать лог с определенным уровнем. И именно от выбора метода (и минимального уровня логирования в конфиге) будет зависеть запишется ваше сообщение (в нашем случае - в консоль) или будет проигнорировано.

Собственно, кажется, что все есть. Код написан, конфиг подложен, библиотеки подключены. Но если вы запустите приложение на данном этапе - скорее всего, увидите только сообщения с уровнем логирования ERROR и FATAL. И с форматом сообщения, отличным от описанного в паттерне.


Настройка окружения

Дело в том, что log4j2 не знает о нашем конфиге. И поэтому использует конфигурацию по умолчанию.

Указать ему, какой файл использовать в качестве конфигурации, мы можем с помощью системной переменной “log4j2.configurationFile”.

Можно это сделать программно через System.setProperty(), что неудобно - это не гибко, ведь жестко фиксируется на уровне кода. Да и записывать объект логгера в константу не получится - ведь нам необходимо, чтобы конфиг применился до того, как будет создан объект логгера. 

Хорошая новость в том, что можно указать системную переменную на этапе запуска приложения. В IDEA можно открыть конфигурацию запуска и внести нужные изменения через GUI.

Альтернатива - запускать через консоль и прописывать параметры в ней же (не забываем там же прописывать CLASSPATH).

Демонстрация для IDEA:


Флаг -D у команды java означает установку с системного параметра в формате <name>=<value>.

После применения этих параметров запуск должен пройти в штатном режиме.

Поздравляю, вы подключили логгер в проект!


Заключение

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

Ответов может быть несколько:

  • Документация. Обычно наиболее исчерпывающий, если  вам нужно подключить, сконфигурировать и начать использовать новую библиотеку или фреймворк. Если повезет - будет дружелюбная дока с примерами приложений, удобный гайдом и прочим. Если повезет меньше - будет подробная, но неудобная для быстрого сайта документация. Если совсем не повезло - будет readme на GitHub’е библиотеки или исследование ее исходного кода. Это об официальных источниках информации;
  • Различные туториалы и статьи. Видео от индусов на ютуб, Baeldung и прочие авторские статьи - ваши лучшие друзья. Скорее всего, будет утрировано, в сравнении с документацией, но намного быстрее. А уже после запуска по туториалу можно искать в документации нужные инструменты для кастомизации под ваши нужды;
  • Stackoverflow, Jira разработчков библиотеки, Issues проекта на GitHub и другие форумы и открытые площадки. Чаще всего подходит для решения конкретных проблем и ошибок с библиотекой.

Как правило, эти три пункта закрывают проблему подключения и настройки любой популярной библиотеки. 

На случай же непопулярной или неподдерживаемой, но очень-очень нужной - не убирайте далеко икону для молитв и лопату для раскапывания исходного кода. И то, и другое вам еще пригодится. Благо, это достаточно редкий сценарий.


С теорией на сегодня все!

Переходим к практике:

Задача

Выполните подключение Log4j2 в рамках собственного проекта.


Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)

Канал: https://t.me/ViamSupervadetVadens

Мой тг: https://t.me/ironicMotherfucker

 

Дорогу осилит идущий!

Report Page