Logback - DmitryGontarenko/usefultricks GitHub Wiki

Dependency

Connection Logback

  1. Для начала необходимо подключить зависимости:
        <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>
  1. Создать файл с именем logback.xml в папке src/main/resoures (путь по умолчанию).
    Структура документа описана в этом разделе.
    Здесь есть пример конфигурации для вывод логов в консоль и запись в файл.
  2. Настроить параметры логгирование можно так же через application.yml:
logging:
  config: classpath:logback.xml
  level:
    root: error

Configuration

Rewiew

Конфигурирование 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"/>

Базовая структура файла-конфигураций показана на рисунке:
configurationBasicSyntax
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

Rewiew

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 - имя класса для создания макета.

Layouts

Review

С помощью настройки макетов (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") &amp;
            message.contains("Hello there")
        </expression>
    </evaluator>
    <evaluator name="DISP_EX_EVAL">
        <expression>
            throwable != null &amp; 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" />

Готово!

Filters

Review

Для сценария конфигурации (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>
⚠️ **GitHub.com Fallback** ⚠️