Logback - DmitryGontarenko/usefultricks GitHub Wiki
- Для начала необходимо подключить зависимости:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
- Создать файл с именем logback.xml в папке src/main/resoures (путь по умолчанию).
Структура документа описана в этом разделе.
Здесь есть пример конфигурации для вывод логов в консоль и запись в файл. - Настроить параметры логгирование можно так же через application.yml:
logging:
config: classpath:logback.xml
level:
root: error
Конфигурирование logback.
Для более подробного ознакомления с данном темой рекомендуется обратиться к документации.
С помощью тэга property
можно объявить переменную:
<property name="log_pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
Подстановка переменных может происходить в любом месте файла конфигурации, где можно установить значение:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${log_pattern}</Pattern>
...
</appender>
В случае, если переменная не объявлена, можно указать значение по умолчанию с помощью оператора :-
, например:
<file>${log_path:-DEFAULT_DIR}/log-file.log</file>
Возможно вынести переменные в отдельный файл
Для этого создадим файл variables.properties
:
log_path=LOG_DIR
И подключим его в файле конфигураций logback.xml
:
<property resource="variables.properties" />
Мы так же можем подключить конфигурацию из другого файла.
Для этого создадим еще один файл-конфигураций includedLogback.xml
. Его содержимое обязательно должно содержаться в тегах <include>
:
<included>
<appender name="INCLUDED_FILE_HTML" class="ch.qos.logback.core.FileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%d{HH:mm:ss}%thread%level%logger%msg%mdc</pattern>
</layout>
</encoder>
<file>LOGGING_RECORDS/included_log-file.html</file>
</appender>
</included>
И подключим созданный файл в основном файле-конфигураций logback.xml
:
<include resource="includedLogback.xml"/>
Базовая структура файла-конфигураций показана на рисунке:
Appender
уже описаны в этом разделе
С помощью logger
можно настраивать логгирование конкретных пакетов/классов, вне зависимости от настроек "корневого" логгирования, например:
<logger name="org.springframework" level="off"/>
<logger name="liquibase" level="info" additivity="false">
<appender-ref ref="FILE" />
</logger>
В данном примере все логи с именем org.springframework отключены.
При добавлении свойства appender-ref
в консоль будет по прежнему выводиться все сообщения с уровнем INFO, но в файл по данному сценарию будут записываться только логи с именем пакета liquibase.
Свойство addictivity=false
указывает на то, что логирование будет идти только по выбранному сценарию, отдельно от основного потока. В данном случае все логи, связанные с пакетом liquibase, будут записаны в файл, но в консоли выводиться не будут.
root
корневой логгер, он поддерживает настройку только атрибута уровня. Иерархия уровней такова: TRACE < DEBUG < INFO < WARN < ERROR (ALL, OFF)
. Каждый последующий уровень включает в себя предыдущий. Корневой уровень по умолчанию DEBUG
. Сценарии конфигураций (appender) можно подключать с помощью тега appender-ref
, например:
<root level="error">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
В данном примере в консоль и файл будут выводиться только логи уровня error
.
Appenders - это сценарий конфигурации для логгирования.
В таком сценарии можно настраивать вывод логов в консоль, сохранения их в файлы с различными расширениями или в БД, а так же отправку по электронной почте.
Для более подробного ознакомления с данном темой рекомендуется обратиться к документации.
Данный сценарий служит для вывода логов в консоль.
Пример:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${log_pattern_console}</Pattern>
</layout>
</appender>
Данный сценарий служит для сохранения логов в файл.
Пример:
<appender name="FILE_HTML" class="ch.qos.logback.core.FileAppender">
<file>log-file.html</file>
<append>false</append>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%d{HH:mm:ss}%thread%level%logger%msg%mdc</pattern>
</layout>
</encoder>
</appender>
В данном примере используется HTML-макет, паттерн для такого макета должен быть без пробелов и символов разделения, иначе для каждого символа будет создан отдельный столбец.Так же есть возможно подключить свой собственный CSS.
Данный сценарий служит для сохранения логов в файлы, отличия его от предыдущего сценария в том, что он автоматически создает новые лог-файлы, в зависимости от настроенных параметров.
Пример:
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>log-file.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>log-file-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>5</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${log_pattern}</pattern>
</encoder>
</appender>
rollingPolicy
условия, при которых запись начнется в новый файл
fileNamePattern
- файл будет генерироваться снова для каждого периода указанного в значение fileNamePattern, паттерн по умолчанию для %d:yyy-MM-dd, можно указать несколько спецификаторов d{}, но только одна из них может быть использован для периода ролловера, все остальные должны быть помечены параметром aux, например: %d{yyyy/MM, aux}.
maxHistory
это свойство контролирует максимальное количество сохраняемых лог-файлов и должно применяться первым, пример: если указать ежемесячный ролловер %d{yyyy-MM} и maxHistory=6, то файлы старше 6 месяцев будут удалены, т.е. для ежедневного ролловера в течении одного месяца, необходимо будет указать %d{yyyy-MM-dd} и maxHistory=30
maxFileSize
each archived file, size max 10MB.
totalSizeCap
контролирует общий размер всех лог-файлов, при превышении заданного размера, самые старые файлы будут удаляться, данное свойство должно применяться вторым, после maxHistory.
maxFileSize
устанавливает максимальный размер для каждого лог-файла в отдельности.
%i
является обязательным при использовании свойства maxFileSize. Каждый раз, когда текущий лог-файл будет достигать максимального значения до окончания текущего периода времени, он будет архивироваться с нарастающим индексом, начиная с 0
Данный сценарий служит для сохранения логов в базу данных, до использования этого сценария должны быть созданы три таблицы. Пример скрипта для создания этих таблиц в БД можно посмотреть по пути logback-classic/src/main/java/ch/qos/logback/classic/db/script folder
Пример (в данном случае используются настройки соединения для PostgrSQL):
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>org.postgresql.Driver</driverClass>
<url>jdbc:postgresql://localhost:5432/usfl</url>
<user>postgres</user>
<password>123</password>
</connectionSource>
</appender>
append
если true:добавление логов в коней существующего файла, в противном случае false, по умолчанию имеет свойство true
file
указывается имя и путь до файла, если файл или родительский каталог не существует, они будут созданы автоматически
encode
- имя класса кодировщика. По умолчанию это класс PatternLayoutEncoder. Encoder отвечает за преобразование событий в байтовый массив, а так же запись этого массива в OutputStream
layout
- имя класса для создания макета.
С помощью настройки макетов (Layout) можно настраивать преобразование входящих логов.
Для более подробного ознакомления с данном темой рекомендуется обратиться к документации.
Пример:
<property name="log_pattern" value="%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n"/>
<property name="log_pattern_console" value="%-65(%d{HH:mm:ss.SSS} [%thread] %highlight(%.-1level) %cyan(%-36logger{36})) - %replace(%msg){'INTO [a-z_]+', 'xxxx'}%n"/>
Разберем слова-преобразователи (conversion words) подробнее:
%d{pattern,timezone}
используется для вывода даты логгирования. Синтаксис шаблона совместим с форматом java.text.SimpleDateFormat. При отстутствии шаблона используется шаблон ISO8601. Параметр timezone
указывает часовой пояс. При отсутствии параметра будет указан часовой пояс по умолчанию для хост-платформы Java.
%relative
выводит количество миллисекунд, прошедших с момента запуска приложения дл создания события логгирования.
%thread
- выводит имя логгируемого потока.
%level
- выводит уровень события логгирования (info/debug/error/trace/warn).
%msg
- выводит сообщение, связанное с событием логгирование.
%n
- символ разделителя строк (иначе все сообщения будут в одно строку).
%
- символ, которым отмечаются слова преобразователи.
%contextName
- наименование сценария конфигурации. По умолчанию default. Позволяет различить логгирование одних и тех же классов разными сценариями. Назначить новое имя для сценария можно с внутри тега <contextName>value</contextName>
.
%logger{length}
- выводит имя объекта логгирования. Этот оператор принимает целое число в качестве параметра. Алгоритм сокращает имя объекта без значительной потери смысла, 0 - приведет к тому, что имя класса будет напечатано без префикса имени пакета, а по умолчанию имя будет напечатано полностью.
Например, если %logger{5}
, результат будет (1), если %logger{36}
, то (2):
l.e.j.JdbcExecutor (1)
liquibase.executor.jvm.JdbcExecutor (2)
%-5logger
- выравнивание по ширине на указанное количество символов (включая символы самого уровня логгирования). -5 - выравнивание по правому краю, 5 - по левому.
%-1.logger
- усечение уровня логгирование до указанного количества символов. Т.е. в данном случае уровень логгирование будет сокращен до одного символа: T, D, I, W, или E.
replace(p){r,t})
- где r
регулярное выражение, которое будет изменено на значение t
в строке p
.
В данном примере имена всех таблиц в логах (при добавлении в них каких-либо данных) будут маскироваться значением 'xxxx':
%replace(%msg){'INTO [a-z_]+', 'xxxx'}%n
В logback можно группировать подшаблоны и применять к ним директивы форматирования с помощью заключения в скобки. Например, сделаем отступ равный 30 символам перед выводом уровня логгирования:
%-30(%d{HH:mm:ss} [%thread]) %-5level ...
%highlight(%level)
- автоматически устанавливает цвет для уровней логгирования error: bold-red, warn: red, info: blue.
%cyan()
- цветовая группировка, позволят изменить цвет выбранного шаблона. Имеет несколько разных цветов.
<evaluator>
- при выполнении заданного условия выводит информацию о вызывающем классе на консоль.
...%m$n%caller{depth, evaluator}
- применить evaluator для паттерна логгирования.
Так же можно подавить трасировку ислючений заданного типа:
...%m%n%ex{depth, evaluator}
- применить evaluator для паттерна логирования.
<evaluator name="DISP_CALLER_EVAL">
<expression>
logger.contains("com.accenture") &
message.contains("Hello there")
</expression>
</evaluator>
<evaluator name="DISP_EX_EVAL">
<expression>
throwable != null & throwable instanceof
com.accenture.usefultricks.exception.CustomException
</expression>
</evaluator>
public void evaluators() {
LOGGER.info("Hello there");
for (int i = 0; i < 3; i++) {
if (i == 1) {
LOGGER.info("logging statement " + i, new CustomException("do not display"));
} else {
LOGGER.info("logging statement " + i, new Exception("display"));
}
}
}
outputPatternAsHeader
- это свойство выводит используемый шаблон в начале журнала логов, по умолчанию false. Пример:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<outputPatternAsHeader>true</outputPatternAsHeader>
...
</appender>
В начале логов будет выведено:
#logback.classic pattern: %d{HH:mm:ss.SSS} [%thread] %.-1level %logger{36} - %msg%n
Добавить свое слово-преобразователь %nanos
.
Для начала создадим Java-класс и расширим его классом ClassicConverter
:
public class CustomLogback extends ClassicConverter {
private long start = System.nanoTime();
/**
* Данными метод возвращает количество наносекунд, прошедших с
* момента его создания.
*/
@Override
public String convert(ILoggingEvent iLoggingEvent) {
long nowInNanos = System.nanoTime();
return Long.toString(nowInNanos - start);
}
}
Теперь добавим в файл конфигураций:
<conversionRule conversionWord="nanos"
converterClass="com.accenture.usefultricks.logback.CustomLogback" />
Готово!
Для сценария конфигурации (appender) можно задавать различного рода фильтры.
Для более подробного ознакомления с данном темой рекомендуется обратиться к документации.
Можно создать собственный фильтр, для этого необходимо расширить свой класс абстрактным классом Filter.
Пример:
public class FilterLogback extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent iLoggingEvent) {
if (iLoggingEvent.getMessage().contains("Custom error")) {
return FilterReply.ACCEPT;
} else {
return FilterReply.NEUTRAL;
}
}
}
В данном примере метод decide вернет ACCEPT, если в сообщении события будет содержаться строка "Custom error" и NEUTRAL в остальных случаях.
Далее необходимо подключить созданный фильтр к файлу конфигураций:
Пример:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="com.accenture.usefultricks.logback.FilterLogback" />
...
</appender>
Фильтрация происходит на основе точного соответствия уровня события логгирования.
Пример:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
...
</appender>
Отфильтровывает все события которые равны или ниже указанного, все события выше по иерархии будут отклонены (DENY)
Пример:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
...
</appender>
Принимает блок языка Java, который возвращает логическое значение. В примере, если выражение "return message.contains("Custom")" вернет true, то все записи, содержащие такое сообщение, будут удалены (DENY)
Пример:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator>
<expression>return message.contains("Custom");</expression>
</evaluator>
<OnMatch>DENY</OnMatch>
<OnMismatch>NEUTRAL</OnMismatch>
</filter>
...
</appender>