1. Обзор
Ведение журнала является мощным средством для понимания и отладки поведения программы во время выполнения. Журналы собирают и сохраняют важные данные и делают их доступными для анализа в любой момент времени.
В этой статье обсуждаются самые популярные фреймворки ведения журналов Java, Log4j 2 и Logback, а также их предшественник Log4j, а также кратко затрагивается SLF4J, фасад ведения журналов, который предоставляет общий интерфейс для различных фреймворков ведения журналов.
2. Включение ведения журнала
Все фреймворки ведения журналов, обсуждаемые в статье, разделяют понятие регистраторов, приложений и макетов. Включение ведения журнала внутри проекта выполняется в три общих шага:
- Добавление необходимых библиотек
- Конфигурация
- Размещение выписок журнала
В следующих разделах обсуждаются шаги для каждой платформы в отдельности.
3. Лог4дж 2
Log4j 2 — это новая и улучшенная версия платформы ведения журналов Log4j. Наиболее убедительным улучшением является возможность асинхронного ведения журнала. Для Log4j 2 требуются следующие библиотеки:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.1</version>
</dependency>
Последнюю версию log4j-api
вы можете найти здесь, а log4j-core
— здесь .
3.1. Конфигурация
Настройка Log4j 2 основана на основном файле конфигурации log4j2.xml
. Первое, что нужно настроить, это appender.
Они определяют, куда будет направляться сообщение журнала. Местом назначения может быть консоль, файл, сокет и т. д.
Log4j 2 имеет множество приложений для разных целей, вы можете найти дополнительную информацию на официальном сайте Log4j 2 .
Давайте посмотрим на простой пример конфигурации:
<Configuration status="debug" name="foreach" packages="">
<Appenders>
<Console name="stdout" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %p %m%n"/>
</Console>
</Appenders>
</Configuration>
Вы можете установить имя для каждого приложения, например, использовать консоль
имен вместо stdout
.
Обратите внимание на элемент PatternLayout
— он определяет, как должно выглядеть сообщение. В нашем примере шаблон задается на основе параметра шаблона
, где %d
определяет шаблон даты, %p
— вывод уровня журнала, %m
— вывод зарегистрированного сообщения и %n
— добавляет символ новой строки. Более подробную информацию о шаблоне вы можете найти на официальной странице Log4j 2 .
Наконец , чтобы включить добавление (или несколько), вам нужно добавить его в раздел <Root> :
<Root level="error">
<AppenderRef ref="STDOUT"/>
</Root>
3.2. Вход в файл
Иногда вам нужно будет использовать ведение журнала в файл, поэтому мы добавим в нашу конфигурацию fout logger:
<Appenders>
<File name="fout" fileName="foreach.log" append="true">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%nw</Pattern>
</PatternLayout>
</File>
</Appenders>
Приложение File
имеет несколько параметров, которые можно настроить:
file
– определяет имя файла лог-файлаappend
— значение по умолчанию для этого параметра равно true, что означает, что по умолчанию приложениеFile
будет добавляться к существующему файлу, а не обрезать его.PatternLayout
, описанный в предыдущем примере.
Чтобы включить File
appender, вам нужно добавить его в раздел <Root> :
<Root level="INFO">
<AppenderRef ref="stdout" />
<AppenderRef ref="fout"/>
</Root>
3.3. Асинхронное ведение журнала
Если вы хотите сделать свой Log4j 2 асинхронным, вам нужно добавить библиотеку разрушителя LMAX в ваш pom.xml
. Разрушитель LMAX — это неблокирующая библиотека межпотокового взаимодействия.
Добавление разрушителя в pom.xml:
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.4</version>
</dependency>
Последнюю версию Disruptor можно найти здесь .
Если вы хотите использовать разрушитель LMAX, вам нужно использовать <asyncRoot>
вместо <Root>
в вашей конфигурации.
<AsyncRoot level="DEBUG">
<AppenderRef ref="stdout" />
<AppenderRef ref="fout"/>
</AsyncRoot>
Или вы можете включить асинхронное ведение журнала, установив для системного свойства Log4jContextSelector
значение org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
.
Вы, конечно, можете прочитать больше о настройке асинхронного логгера Log4j2 и посмотреть некоторые диаграммы производительности на официальной странице Log4j2 .
3.4. Применение
Ниже приведен простой пример, демонстрирующий использование Log4j для ведения журнала:
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class Log4jExample {
private static Logger logger = LogManager.getLogger(Log4jExample.class);
public static void main(String[] args) {
logger.debug("Debug log message");
logger.info("Info log message");
logger.error("Error log message");
}
}
После запуска приложение будет регистрировать следующие сообщения как в консоли, так и в файле с именем foreach.log:
2016-06-16 17:02:13 INFO Info log message
2016-06-16 17:02:13 ERROR Error log message
Если вы повысите уровень корневого журнала до ERROR
:
<level value="ERROR" />
Вывод будет выглядеть следующим образом:
2016-06-16 17:02:13 ERROR Error log message
Как видите, изменение параметра уровня журнала на верхний приводит к тому, что сообщения с более низким уровнем журнала не будут печататься в приложениях.
Метод logger.error
также можно использовать для регистрации произошедшего исключения:
try {
// Here some exception can be thrown
} catch (Exception e) {
logger.error("Error log message", throwable);
}
3.5. Конфигурация уровня пакета
Допустим, вам нужно показать сообщения с уровнем журнала TRACE — например, из определенного пакета, такого как com.foreach.log4j2
:
logger.trace("Trace log message");
Для всех других пакетов вы хотите продолжать регистрировать только сообщения INFO.
Имейте в виду, что TRACE ниже уровня корневого журнала INFO, который мы указали в конфигурации.
Чтобы включить ведение журнала только для одного из пакетов, вам нужно добавить следующий раздел перед <Root>
в ваш log4j2.xml
:
<Logger name="com.foreach.log4j2" level="debug">
<AppenderRef ref="stdout"/>
</Logger>
Это позволит вести журнал для пакета com.foreach.log4j
, и ваш вывод будет выглядеть так:
2016-06-16 17:02:13 TRACE Trace log message
2016-06-16 17:02:13 DEBUG Debug log message
2016-06-16 17:02:13 INFO Info log message
2016-06-16 17:02:13 ERROR Error log message
4. Логбэк
Logback задуман как улучшенная версия Log4j, разработанная тем же разработчиком, который создал Log4j.
Logback также имеет гораздо больше функций по сравнению с Log4j, и многие из них также представлены в Log4j 2. Вот краткий обзор всех преимуществ Logback на официальном сайте .
Начнем с добавления следующей зависимости в pom.xml
:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
Эта зависимость транзитивно подтянет еще две зависимости, logback-core
и slf4j-api
. Обратите внимание, что последнюю версию Logback можно найти здесь .
4.1. Конфигурация
Давайте теперь посмотрим на пример конфигурации Logback:
<configuration>
# Console appender
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
# Pattern of log message for console appender
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n</Pattern>
</layout>
</appender>
# File appender
<appender name="fout" class="ch.qos.logback.core.FileAppender">
<file>foreach.log</file>
<append>false</append>
<encoder>
# Pattern of log message for file appender
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n</pattern>
</encoder>
</appender>
# Override log level for specified package
<logger name="com.foreach.log4j" level="TRACE"/>
<root level="INFO">
<appender-ref ref="stdout" />
<appender-ref ref="fout" />
</root>
</configuration>
Logback использует SLF4J в качестве интерфейса, поэтому вам необходимо импортировать Logger
и LoggerFactory SLF4J.
4.2. SLF4J
SLF4J предоставляет общий интерфейс и абстракцию для большинства фреймворков журналирования Java. Он действует как фасад и предоставляет стандартизированный API для доступа к базовым функциям среды ведения журнала.
Logback использует SLF4J в качестве собственного API для своей функциональности. Ниже приведен пример использования журнала Logback:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log4jExample {
private static Logger logger = LoggerFactory.getLogger(Log4jExample.class);
public static void main(String[] args) {
logger.debug("Debug log message");
logger.info("Info log message");
logger.error("Error log message");
}
}
Вывод останется таким же, как и в предыдущих примерах.
5. Лог4Дж
Наконец, давайте взглянем на почтенный фреймворк журналирования Log4j.
На данный момент он, конечно, устарел, но его стоит обсудить, поскольку он закладывает основу для его более современных преемников.
Многие детали конфигурации соответствуют описанным в разделе Log4j 2.
5.1. Конфигурация
Прежде всего вам нужно добавить библиотеку Log4j в ваши проекты pom.xml:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Здесь вы сможете найти последнюю версию Log4j.
Давайте посмотрим на полный пример простой конфигурации Log4j только с одним приложением консоли:
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="false">
<!--Console appender-->
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss} %p %m%n" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>
<log4j:configuration debug="false">
— это открытый тег всей конфигурации, который имеет одно свойство — debug
. Он определяет, хотите ли вы добавлять отладочную информацию Log4j в журналы.
5.2. Применение
После того, как вы добавили библиотеку и конфигурацию Log4j, вы можете использовать регистратор в своем коде. Давайте рассмотрим простой пример:
import org.apache.log4j.Logger;
public class Log4jExample {
private static Logger logger = Logger.getLogger(Log4jExample.class);
public static void main(String[] args) {
logger.debug("Debug log message");
logger.info("Info log message");
logger.error("Error log message");
}
}
6. Заключение
В этой статье показаны очень простые примеры использования различных фреймворков ведения журналов, таких как Log4j, Log4j2 и Logback. Он охватывает простые примеры конфигурации для всех упомянутых фреймворков.
Примеры, сопровождающие статью, можно найти на GitHub.