5 minute read

Log4J — это популярный фреймворк для логирования с открытым исходным кодом, написанный на Java. Log4j широко используется в различных приложениях на Java. Более того, он является потокобезопасным, быстрым и предоставляет иерархию именованных логгеров. Log4j распространяется под лицензией Apache Software License с открытым исходным кодом.

Версия Log4j 1.x достигла конца своего жизненного цикла 5 августа 2015 года. Поэтому на сегодняшний день Log4j2 является последним обновлением Log4j.

В этом руководстве мы изучим Log4j и как настроить основные компоненты Log4j с помощью файла log4j.properties в Java.

1. Настройка Maven

Для начала нам понадобится зависимость log4j-core в нашем файле pom.xml:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.24.1</version>
</dependency>

2. API Log4j

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

API Log4j имеет многослойную архитектуру, которая предоставляет два типа объектов в фреймворке Log4j — основные объекты и вспомогательные объекты.

3. Компоненты Log4j

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

4.1. Логгер

Объект Logger отвечает за представление информации о логировании. Это первый обязательный уровень в архитектуре Log4j. Класс Logger определён в пакете org.apache.log4j.

Как правило, мы создаём один экземпляр Logger для каждого класса приложения, чтобы логировать важные события, относящиеся к этому классу. Также мы обычно создаём этот экземпляр в начале класса, используя статический фабричный метод, который принимает имя класса в качестве параметра:

private static final Logger logger = Logger.getLogger(JavaClass.class.getName());

Затем мы можем использовать различные методы класса Logger для логирования или вывода важных событий в зависимости от их категорий. Эти методы включают trace(), debug(), info(), warn(), error(), fatal(). Эти методы определяют уровень запроса на логирование.

Приоритетный порядок методов Logger: TRACE < DEBUG < INFO < WARN < ERROR < FATAL. Таким образом, эти методы выводят лог-сообщения в зависимости от уровня логгера, установленного в файле log4j.properties. Это означает, что если мы установим уровень логгера как INFO, то все события INFO, WARN, ERROR и FATAL будут записаны в лог.

4.2. Аппендер

Аппендер обозначает назначение вывода логов. Мы можем выводить логи в несколько предпочтительных мест с помощью Log4j, таких как консоль, файлы, удалённый сокет-сервер, база данных и т. д. Мы называем эти выходные назначения аппендерами. Более того, мы можем прикрепить несколько аппендеров к логгеру.

Аппендеры работают в соответствии с правилом аддитивности аппендеров. Это правило гласит, что вывод лог-сообщения любого логгера будет направлен ко всем его аппендерам и его предкам — аппендерам, которые находятся выше в иерархии.

Log4j имеет несколько аппендеров, определённых для файлов, консольных выводов, GUI-компонентов, удалённых сокет-серверов, JMS и т. д.

4.3. Макет

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

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

Мы также рассмотрим несколько символов преобразования через примеры в следующих разделах.

5. Файл log4j.properties

Мы можем настроить Log4j с помощью XML или файла свойств. Файл log4j.properties хранит конфигурации в виде пар “ключ-значение”.

Имя файла конфигурации свойств log4j по умолчанию — log4j.properties. Логгер ищет это имя файла в CLASSPATH. Однако, если нам нужно использовать другое имя конфигурационного файла, мы можем установить его с помощью системного свойства log4j.configuration.

Файл log4j.properties содержит спецификации аппендеров, их имена и типы, а также шаблоны макетов. Он также содержит спецификации о корневом логгере по умолчанию и его уровнях логирования.

6. Синтаксис файла log4j.properties

В общем файле log4j.properties мы определяем следующие конфигурации:

  • Корневой логгер и его уровень. Мы также предоставляем имя для аппендера здесь.
  • Затем мы назначаем действительный аппендер для определённого имени аппендера.
  • Наконец, мы определяем макет, цель, уровень и т. д. для определённого аппендера.

Давайте посмотрим на синтаксис общего файла log4j.properties:

# Корневой логгер с именем аппендера
log4j.rootLogger = DEBUG, NAME

# Назначаем NAME действительный аппендер
log4j.appender.NAME = org.apache.log4j.FileAppender

# Определяем макет для NAME
log4j.appender.NAME.layout=org.apache.log4j.PatternLayout
log4j.appender.NAME.layout.conversionPattern=%m%n

Здесь NAME — это имя аппендера. Как уже обсуждалось ранее, мы можем прикрепить несколько аппендеров к логгеру, чтобы направлять логи в разные назначения.

7. Примеры

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

7.1. Пример программы

Давайте начнём с примерного приложения, которое логирует некоторые сообщения:

import org.apache.log4j.Logger;

public class Log4jExample {

    private static Logger logger = Logger.getLogger(Log4jExample.class);

    public static void main(String[] args) throws InterruptedException {
        for(int i = 1; i <= 2000; i++) {
            logger.info("This is the " + i + " time I say 'Hello World'.");
            Thread.sleep(100);
        }
    }
}

Приложение простое — оно записывает некоторые сообщения в цикле с короткой задержкой между итерациями. В нём 2,000 итераций, и в каждой итерации есть пауза в 100 мс. Таким образом, выполнение должно занять около трёх с половиной минут. Мы будем использовать это приложение в наших примерах ниже.

7.2. Логирование в консоль

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

# Корневой логгер
log4j.rootLogger=INFO, stdout

# Направляем лог-сообщения в stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

Здесь мы определили файл log4j.properties со следующими спецификациями:

  • Мы установили уровень корневого логгера как INFO. Это означает, что все лог-события с уровнем INFO и выше будут записываться. Мы также задали имя для аппендера как stdout.
  • Поскольку мы хотим направить логи в консоль, мы назначили аппендер как org.apache.log4j.ConsoleAppender и цель как System.out.
  • Наконец, мы указали формат для PatternLayout, в котором хотим выводить логи, используя ConversionPattern.

Давайте также разберём значение каждого из символов преобразования в ConversionPattern, которые мы использовали:

  • %d добавляет временную метку в заданном формате.
  • %-5p добавляет информацию об уровне логирования к каждому лог-сообщению. Это означает, что приоритет события логирования должен быть выровнен по левому краю с шириной в пять символов.
  • %c{1} выводит квалифицированное имя класса, опционально за которым следуют имена пакетов (квалификатор точности), то есть логирует конкретное лог-сообщение.
  • %L выводит номер строки конкретного лог-события.
  • %m выводит фактическое лог-сообщение.
  • %n добавляет новую строку после каждого лог-сообщения.

Таким образом, когда мы запускаем наше примерное приложение, мы получаем следующие строки, напечатанные в консоли:

2023-08-01 00:27:25 INFO Log4jExample:15 - This is the 1 time I say 'Hello World'.
...
...
2023-08-01 00:27:25 INFO Log4jExample:15 - This is the 2000 time I say 'Hello World'.

Документация для класса PatternLayout объясняет больше о символах преобразования, которые мы можем использовать в зависимости от наших нужд.

7.3. Несколько назначений

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

# Корневой логгер
log4j.rootLogger=INFO, file, stdout

# Перенаправление в файл
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\\Baeldung\\app.log
log4j.appender.file.MaxFileSize=5KB
log4j.appender.file.MaxBackupIndex=2
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Перенаправление в консоль
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

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

В нашем примере выше мы использовали RollingFileAppender, который прокручивает лог-файлы на основе как размера, так и количества лог-файлов, используя параметры MaxFileSize и MaxBackupIndex. Таким образом, лог-файл будет прокручиваться, когда его размер достигнет 5 КБ, и мы будем хранить максимум два прокрученных лог-файла в качестве резервной копии.

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

31/01/2024  10:28    138 app.log
31/01/2024  10:28  5.281 app.log.1
31/01/2024  10:28  5.281 app.log.2

8. Заключение

В этой статье мы рассмотрели Log4j и его три компонента — логгеры, аппендеры и макеты. Мы также поняли синтаксис файла log4j.properties и некоторые простые примеры конфигурации файла log4j.properties.

оригинал

Updated: