Посібник для розробників Java

Однією з найважливіших частин процесу розробки програмного забезпечення є належне ведення журналів. З великою кількістю доступних фреймворків журналювання Java важливо вибрати той, який простий у використанні. Водночас обрана вами структура повинна мати високу продуктивність, розширювані функції та можливість налаштування. Log4j2 — це безкоштовна бібліотека журналювання Java, яка відповідає всім вимогам.

Інтеграція Log4j2 з будь-якою програмою розблокує такі параметри, як розширена фільтрація, підтримка Java 8 лямбда, пошук властивостей і спеціальні рівні журналу. Давайте розглянемо, як ви можете додати Log4j2 до своїх проектів і які функції допоможуть вам залишатися на висоті вашої гри.

Що таке Log4j2?

Ведення журналів — це метод збору корисної інформації, відомої як журнали, на яку можна посилатися та аналізувати її пізніше. Ви можете використовувати журнали для швидкого налагодження коду програми. Журнали програм допомагають зрозуміти потік коду та вирішувати проблеми та помилки виробництва.

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

Log4j2 — одна з найпопулярніших бібліотек журналювання Java. Це наступник дуже впливової бібліотеки Log4j. Log4j2, розроблений Apache Software Foundation і є частиною Apache Logging Services, є безкоштовним програмним забезпеченням із відкритим вихідним кодом (FOSS), що поширюється за ліцензією Apache, версія 2.0.

Log4j2 побудований на міцній основі оригінального Log4j. Існують переваги використання Logger перед простими операторами друку System.out.println(). Це включає контроль над тим, які повідомлення відображати, уникаючи інших повідомлень журналу. Наявність належних журналів має вирішальне значення у виробничому середовищі, де недоступні налагоджувачі.

Як додати Log4j2 до вашого проекту?

Існує кілька способів додати Log4j2 до вашого проекту Java. Бажано мати Java 8 або новішої версії, щоб використовувати всі функції Log4j2.

Давайте обговоримо різні методи, за допомогою яких ви можете додати Log4j2 залежно від ваших вимог.

Додавання Log4j2 до проектів за допомогою Apache Maven

Якщо ваш проект використовує Apache Maven як систему збірки, залежності Log4j2 потрібно додати до файлу pom.xml.

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.20.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.20.0</version>
  </dependency>
</dependencies>

Щоб полегшити підтримку однакової версії для різних артефактів, у Log4j2 є файл pom.xml зі списку матеріалів (BOM). Якщо ви додаєте його під керуванням залежностями, вам не потрібно окремо додавати версії.

<!-- Add the BOM to the dependencyManagement -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-bom</artifactId>
      <version>2.20.0</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>

<!-- Once the BOM is added, the versions are not required -->
<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
  </dependency>
</dependencies>

Додавання Log4j2 до проектів за допомогою Apache Gradle

Якщо ви використовуєте Apache Gradle як інструмент збірки, ви можете додати залежності Log4j2 до свого файлу build.gradle.

dependencies {
  implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
  implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
}

Якщо ви використовуєте Gradle версії 5.0 або новішої, ви можете імпортувати специфікацію матеріалів (BOM) Log4j2 Maven, щоб підтримувати узгоджені версії залежностей. Цього можна досягти, додавши наступне до вашого файлу build.gradle.

dependencies {
  implementation platform('org.apache.logging.log4j:log4j-bom:2.20.0')

  implementation 'org.apache.logging.log4j:log4j-api'
  runtimeOnly 'org.apache.logging.log4j:log4j-core'
}

Для Gradle версій 2.8-4.10 немає можливості для прямого імпорту Maven BOM. Вам потрібно додати додатковий плагін для функції керування залежностями.

plugins {
  id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

dependencyManagement {
  imports {
    mavenBom 'org.apache.logging.log4j:log4j-bom:2.20.0'
  }
}

dependencies {
  implementation 'org.apache.logging.log4j:log4j-api'
  runtimeOnly 'org.apache.logging.log4j:log4j-core'
}

Додавання Log4j2 до автономних програм без інструменту збірки

Якщо ваш проект не має інструменту збірки, ви можете завантажити необхідну версію артефакту Log4j2 з офіційної сторінки завантаження Log4j2.

Після того, як ви їх завантажите, вам потрібно переконатися, що шлях до класів вашої програми містить такі jar-файли.

  • log4j-api-2.20.0.jar
  • log4j-core-2.20.0.jar
  Виправте помилку повного завантаження диска Google Chrome

Які компоненти входять до складу Log4j2?

Щоб зрозуміти особливості Log4j2 і якомога повніше використовувати його можливості, важливо зрозуміти, як працює Log4j2. Під поверхнею кілька будівельних блоків складають Log4j2. Поговоримо про них по черзі.

#1. LoggerContext

LoggerContext є центральною одиницею системи журналювання. Він містить усі реєстратори, запитані в програмі. Він також містить посилання на конфігурацію.

#2. Конфігурація

Конфігурація містить всю інформацію, необхідну для системи реєстрації. Це включає в себе реєстратори, додатки, фільтри тощо. У Log4j2 ви можете визначити конфігурацію за допомогою різних форматів файлів, таких як XML, JSON і YAML, а також програмно через Log4j2 API.

Автоматичне перезавантаження відбувається кожного разу, коли будь-яка властивість змінюється в конфігурації. Отже, перезапуск програми не потрібен.

#3. Лісоруб

Основним компонентом системи Log4j2 є Logger. Логери отримуються в коді програми за допомогою оператора LogManager.getLogger() і використовуються для створення журналів. Повідомлення журналу можуть генеруватися на різних рівнях серйозності, наприклад, налагодження, інформація, попередження, помилка та фатальний.

#4. LoggerConfig

LoggerConfig відповідає за поведінку конкретного Logger. Він визначає поведінку та налаштування для реєстрації подій, згенерованих цим конкретним реєстратором. Це дозволяє конфігурувати різні рівні журналювання, налаштовувати дописувачі та застосовувати фільтри.

#5. фільтр

Ви можете вибірково обробляти події журналу в Log4j2 за допомогою фільтрів. Фільтри застосовуються на основі конкретних критеріїв. Ви можете застосувати ці фільтри до реєстраторів або доповнювачів. Фільтри контролюють, які події журналу можуть проходити через конвеєр журналювання для подальшої обробки. За допомогою фільтрів поведінку журналювання можна точно налаштувати, забезпечуючи обробку лише відповідних журналів.

#6. Appender

Призначення будь-якого повідомлення журналу визначається Appender. Один реєстратор може мати кілька Appenders. Подія журналу буде надіслана всім Appenders для даного Logger. Log4j2 має багато попередньо налаштованих додатків. Наприклад, ConsoleAppender використовується для реєстрації повідомлень на консоль, а FileAppender використовується для виведення повідомлень у файл. Кожному Appender потрібен власний макет, який визначає, як виглядатиме остаточне повідомлення журналу.

#7. Макет

У Log4j2 макет використовується для визначення того, як виглядатиме остаточне повідомлення журналу. Макет пов’язаний із Appender. У той час як Appender визначає призначення виводу, Layout описує, як буде виведено повідомлення.

Топ-5 особливостей Log4j2

Log4j2 має багато функцій, і це те, що відрізняє його від інших доступних фреймворків журналювання Java. Від наявності асинхронних реєстраторів до підтримки лямбда Java 8, Log4j2 має перевагу над іншими. Давайте обговоримо деякі помітні особливості цього фреймворку.

#1. Розширення функціональних можливостей за допомогою плагінів

У Log4j 1.x для створення розширень потрібно було багато модифікувати код. Log4j2 вирішує проблему розширюваності, запроваджуючи систему плагінів.

Ви можете оголосити новий плагін, використовуючи анотацію @Plugin у своєму класі. Використовуючи можливості плагінів, ви можете створювати власні компоненти, такі як фільтри та додатки. Компоненти сторонніх виробників також можна легко додати до бібліотеки.

#2. Підтримка Java 8 Lambda

З випуском Log4j2 версії 2.4 була представлена ​​підтримка лямбда-виразів Java 8. За допомогою лямбда-виразів ви можете визначати свою логіку ведення журналу вбудовано. Це зменшує потребу в багаторядкових перевірках або анонімних внутрішніх класах. Це також гарантує, що дорогі методи не будуть виконуватися без потреби. Таким чином, не тільки код стає чистішим і легшим для читання, але також зменшуються накладні витрати на систему.

Давайте розглянемо приклад, коли ви реєструєте результат дорогої операції, але лише якщо ввімкнено рівень налагодження. До підтримки лямбда-виразів це виконувалося за допомогою наведеного нижче коду:

if (logger.isDebugEnabled()) {
    logger.debug("The output of the given operation is: {}", expensiveOperation());
}

Наявність кількох таких випадків використання зайво призведе до умовних перевірок. Однак за допомогою Log42 ту саму дію можна виконати наступним чином:

logger.debug("The output of the given operation is: {}", () -> expensiveOperation()

Метод exprensiveOperation() оцінюється, лише якщо ввімкнено рівень налагодження. Немає необхідності в будь-яких явних перевірках.

  Топ-18 найкращих програм для контролю швидкості вентилятора

#3. Асинхронні реєстратори

Кожна подія журналу є операцією вводу-виводу, що збільшує накладні витрати на систему. Щоб пом’якшити це, Log4j2 представляє асинхронні реєстратори, які працюють в окремому потоці від потоку програми. Під час використання асинхронних реєстраторів потік, що викликає, негайно отримує назад контроль після виклику методу logger.log().

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

#4. Безсміттєва рубка

У Java збирання сміття – це процес, за допомогою якого невикористані об’єкти в програмі автоматично очищаються. Хоча вам не потрібно вручну виконувати цю операцію, збирання сміття має свої накладні витрати.

Якщо ваша програма створює забагато об’єктів за короткий проміжок часу, процес збирання сміття може зайняти більше системних ресурсів, ніж необхідно. Кілька бібліотек журналювання, включаючи попередні версії Log4j, створюють багато тимчасових об’єктів під час процесу журналювання. Згодом підвищений тиск на збирач сміття впливає на продуктивність системи.

Починаючи з версії 2.6, Log4j2 працює в режимі «без сміття». Це типова поведінка. Таким чином об’єкти використовуються повторно, а створення тимчасових значно скорочується.

Наступні зображення демонструють, як Log4j2 версії 2.6 пом’якшує проблему непотрібних об’єктів порівняно з Log4j2 версії 2.5.

У Log4j2 версії 2.5 під час процесу журналювання створюється багато тимчасових об’єктів; Джерело: apache.org

У Log4j2.6 немає тимчасових об’єктів, створених під час процесу журналювання; Джерело: apache.org

#5. Пошуки

У log4j2 ви можете додавати контекстну інформацію до своїх журналів за допомогою пошуку. Використовуючи їх, ви можете додавати дані з різних джерел, наприклад властивостей системи, змінних середовища або користувальницьких значень. Таким чином, ви можете включити відповідну інформацію, яка динамічно витягується, що робить журнали більш корисними.

Давайте розглянемо приклад, коли ви хочете зареєструвати ідентифікатор сеансу користувача з усіма рядками журналу. Це дозволить вам шукати всі журнали, які відповідають ідентифікатору сеансу.

Шляхом грубої сили для цього було б явно додати ідентифікатор сеансу окремо, що стає важко підтримувати. Незабаром ви можете забути додати його, таким чином втративши цінну інформацію.

logger.info("The user data has been fetched for session id {}", sessionId);
...
logger.info("The transaction has been processed for session id {}", sessionId);
...
logger.info("Request has been successfully processed for session id {}", sessionId);

Кращим способом зробити це було б скористатися пошуком контекстної карти. Ідентифікатор сеансу можна додати до контексту потоку в коді програми. Потім це значення можна використовувати в конфігурації Log4j2. Таким чином усувається необхідність явного згадування про це в повідомленнях журналу.

ThreadContext.put("sessionId", sessionId);

Щойно значення додано, його можна використати у Lookup за допомогою ключового слова ctx.

<File name="Application" fileName="application.log">
  <PatternLayout>
    <pattern>%d %p %c{1.} [%t] $${ctx:sessionId} %m%n</pattern>
  </PatternLayout>
</File>

Як створити власні рівні журналу в Log4j2?

Рівні журналу в Log4j2 використовуються для класифікації подій журналу на основі їх серйозності або важливості. Ви можете контролювати рівень журналу під час реєстрації повідомлення в коді програми.

Наприклад, logger.debug() додає рівень DEBUG. Відповідно, logger.error() додає рівень ПОМИЛКИ. Це визначає, які повідомлення зрештою відображатимуться у виводі. Ви можете налаштувати рівень журналу у файлі конфігурації.

Попередньо налаштовані рівні журналу в Log4j2 та їхні відповідні значення згадані нижче.

OFF0FATAL100ERROR200WARN300INFO400DEBUG500TRACE600ALLМАКС. ЗНАЧЕННЯ

Якщо для рівня журналу встановлено певний рівень, тоді виводяться всі рядки журналу для цього відповідного значення та рядки вище (з меншим значенням). Інші ігноруються.

Наприклад, якщо ви встановите рівень журналу як WARN, тоді відображатимуться повідомлення WARN, ERROR і FATAL. Будь-який рядок журналу з іншим рівнем буде проігноровано. Це особливо корисно, коли ви запускаєте той самий код у різних середовищах.

  Як видалити віджети з центру сповіщень на Mac

Можливо, ви захочете встановити рівень журналу на INFO або DEBUG під час запуску коду у вашому середовищі розробки. Це дозволить вам бачити більше журналів і допоможе в процесі розробки. Однак під час роботи у виробничому середовищі ви захочете встановити значення ERROR. Таким чином, ви зможете зосередитися на пошуку проблеми в разі виникнення будь-якої аномалії та не переглядати непотрібні рядки журналу.

Може статися, що ви захочете додати свій власний рівень журналу на додаток до попередньо налаштованих. Log4j2 дозволяє зробити це легко. Давайте подивимося, як ви можете додати власні рівні журналу та використовувати їх у своїй програмі.

#1. Додавання спеціального рівня журналу за допомогою файлу конфігурації

Ви можете додати власні рівні журналу, оголосивши їх у файлі конфігурації.

У прикладі нижче настроюваний рівень журналу під назвою NOTICE було визначено зі значенням 450. Це розміщує його між INFO (зі значенням 400) і DEBUG (зі значенням 500). Це означає, що якщо встановлено рівень NOTICE, то повідомлення INFO будуть реєструватися, але повідомлення DEBUG будуть пропущені.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <CustomLevels>
    <CustomLevel name="NOTICE" intLevel="450" />
  </CustomLevels>
 
  <Appenders>
    <File name="MyFile" fileName="logs/app.log">
      <PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
    </File>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="MyFile" level="NOTICE" />
    </Root>
  </Loggers>
</Configuration>

#2. Додавання спеціального рівня журналу в код

Крім оголошення їх у файлі конфігурації, ви можете визначити власні власні рівні журналу у своєму коді.

final Level VERBOSE = Level.forName("VERBOSE", 550);

Це створить новий рівень журналу під назвою VERBOSE. Цей рівень журналу знаходитиметься між DEBUG (зі значенням 500) і TRACE (зі значенням 600). Якщо для реєстратора встановлено рівень VERBOSE, усі повідомлення журналу VERBOSE і вище будуть реєструватися, включаючи DEBUG. Однак повідомлення TRACE будуть пропущені.

#3. Використання спеціального рівня журналу в коді

Перш ніж використовувати власні рівні журналу, їх потрібно оголосити. Ви можете оголосити їх у файлі конфігурації або у своєму коді. Після оголошення ви можете вільно ними користуватися.

У цьому прикладі коду показано, як можна оголосити спеціальний рівень під назвою NOTICE, а потім використовувати його.

final Level NOTICE = Level.forName("NOTICE", 550);

final Logger logger = LogManager.getLogger();
logger.log(NOTICE, "a notice level message");

Хоча це створить необхідне повідомлення з новоствореним рівнем, може стати громіздким завжди проходити рівень явно. На щастя, ви можете створити вихідний код, щоб отримати допоміжні методи для реєстрації ваших користувацьких рівнів. Використовуючи те саме, ви зможете використовувати свій власний метод logger.notice() подібно до того, як ви використовуєте logger.debug() або logger.error().

Log4j2 поставляється з утилітою, яка допомагає вам створювати власні розширені журнали. Наступна команда створює файл Java під назвою CustomLogger.java. Цей файл містить наявні методи журналу, а також нещодавно створені методи для рівня NOTICE.

java -cp log4j-core-2.20.0.jar org.apache.logging.log4j.core.tools.ExtendedLoggerGenerator 
        com.example.CustomLogger NOTICE=450 > com/example/CustomLogger.java

Після створення файлу ви можете використовувати клас у своєму коді для створення нових реєстраторів. Ці реєстратори міститимуть додаткові методи для вашого спеціального рівня журналу. Таким чином ви можете розширити функціональність своїх реєстраторів.

final Logger logger = CustomLogger.create(ValueFirstSmsSender.class);

//this new method is similar to using logger.debug()
logger.notice("a notice level message");

Висновок

Log4j2 — це дуже потужна структура журналювання Java, яка пропонує широкий спектр функцій, конфігурацій, покращень продуктивності тощо. Оскільки журнали є дуже важливою частиною процесу розробки програмного забезпечення, наявність надійної структури, як-от Log4j2, покращує можливості програми.

Гнучкість і розширюваність Log4j2 дозволяють належним чином фіксувати події, що відбуваються у вашій програмі. Згодом це дає вам можливість думати про журнали як про потужний інструмент для налагодження та аудиту. З усіма своїми функціями та вдосконаленнями Log4j2 виділяється та робить себе кращим вибором у різноманітних програмних проектах.

Вас також можуть зацікавити ці Java IDE та онлайн-компілятори.