понедельник, 14 января 2019 г.

Логирование в Spring Boot с Logback

В интернете полно информации о разных фреймворках логирования. Но, в основном, она ограничивается настройкой и запуском простого "Hello World!".

Если нужно получить что-то большее, чем "Hello World!", бывает непросто разобраться в конфигурировании соответствующих логеров.

В силу "исторических" причин я выбрал Logback - он используется в Spring Boot в качестве логера по умолчанию, не нужно подключать дополнительные зависимости, разрешать конфликты с другими логерами и т.д. Есть Spring Boot - есть логер.

При разработке одного из проектов нужно было решить следующие задачи:
- логирование в консоль;
- логирование в файл;
- логирование в файл в формате JSON;
- логирование в системный журнал /var/log/syslog.
Logback справился со всеми этими задачами.

Что и как конфигурировал.
1) В файле pom.xml необходимо подключить дополнительные зависимости для логирования в формате JSON:

    <dependency>
      <groupId>ch.qos.logback.contrib</groupId>
      <artifactId>logback-json-classic</artifactId>
      <version>${logback.contrib.version}</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback.contrib</groupId>
      <artifactId>logback-jackson</artifactId>
      <version>${logback.contrib.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>

2) В директории src/main/resources/ создать файл конфигурации logback-spring.xml. Согласно документации по Spring, рекомендуется задать именно такое имя конфигурационного файла. Если назвать файл logback.xml, как это советует документация по Logback, то могут возникнуть неочевидные проблемы с подхватыванием логером файла конфигурации.
В файле конфигурации указываем следующее:


<configuration>

<!--Аппендер для записи в файл-->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>log/my_application.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>log/my_application.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--Сохранять файлы логов за последние 7 дней. Общий размер файлов не должен превышать 3GB-->
            <MaxHistory>7</MaxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>

<!--Аппендер для записи в другой файл в формате JSON-->
    <appender name="JSON" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>log/my_application.json</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>log/my_application.%d{yyyy-MM-dd}.json</FileNamePattern>
            <MaxHistory>7</MaxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
                <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
                <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
                <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                    <prettyPrint>true</prettyPrint>
                </jsonFormatter>
                <appendLineSeparator>true</appendLineSeparator>
            </layout>
        </encoder>
<!--Ниже можно переопределить уровень логирования по умолчанию-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level> 
        </filter>
    </appender>
    
<!--Аппендер для записи сообщений в системный журнал /var/log/syslog.
Чтобы сообщения начали писаться в системный журнал, нужно:
1\ раскомментировать следующие строки в файле /etc/rsyslog.conf:
        module(load="imudp")
        input(type="imudp" port="514")
2\ перезапустить сервис rsyslog:
        sudo service rsyslog restart
-->
    <appender name="UDP_APPENDER" class="ch.qos.logback.classic.net.SyslogAppender">
        <syslogHost>localhost</syslogHost>
        <facility>LOCAL0</facility>
<!--Здесь можно указать в суфиксе сообщения название своего приложения, чтобы отличить его записи в системном журнале от сообщений других приложений-->
        <suffixPattern>[my_application] [%thread] %-5level %logger{35} - %msg%n</suffixPattern>
    </appender>

<!--Аппендер для вывода сообщений в консоль-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
<!--Указываем логеру выводить в консоль раскрашенные сообщения-->
            <pattern>%cyan(%date{yyyy-MM-dd HH:mm:ss}) [%thread] %highlight(%-5level) %green(%logger{35}) - %msg%n</pattern>
        </encoder>
    </appender>

<!--Уровни логирования по умолчанию для аппендеров -->
    <root level="INFO">
        <appender-ref ref="FILE"/>
        <appender-ref ref="JSON"/>
        <appender-ref ref="UDP_APPENDER"/>
        <appender-ref ref="CONSOLE"/>
    </root>

</configuration>

После запуска приложения лог-файлы появятся в директории log/ в корне проекта.