Подключение и конфигурирование logger в прикладном приложении#
Подключение logback для Java приложений#
Для интеграции с сервисом Журналирования рекомендуем использовать slf4j, его реализацию logback. В файл pom.xml проекта необходимо добавить следующие зависимости на logback.
Подключить зависимости#
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
</dependency>
Сконфигурировать logback#
В проекте с конфигурациями дистрибутива по пути k8s/base/configmaps/ необходимо добавить конфигурацию logback, в виде configMap (пример logback-xml.yaml) со следующим содержимым:
apiVersion: "v1"
kind: "ConfigMap"
metadata:
name: "logback-xml"
data:
logback.xml: |-
<configuration debug="true" scan="true" scanPeriod="30 seconds">
<property scope="context" resource="env.properties"/>
<appender name="JSON" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<fieldName>serverEventDatetime</fieldName>
<pattern>[UNIX_TIMESTAMP_AS_NUMBER]</pattern>
</timestamp>
<logLevel>
<fieldName>level</fieldName>
</logLevel>
<loggerName>
<fieldName>logger</fieldName>
</loggerName>
<threadName>
<fieldName>threadName</fieldName>
</threadName>
<message/>
<stackTrace>
<fieldName>stackTrace</fieldName>
<throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
<maxDepthPerThrowable>30</maxDepthPerThrowable>
<maxLength>4096</maxLength>
<rootCauseFirst>true</rootCauseFirst>
</throwableConverter>
</stackTrace>
<pattern>
<omitEmptyFields>true</omitEmptyFields>
<pattern>
{
"application": "${spring.application.name}"
}
</pattern>
</pattern>
<mdc>
<excludeMdcKeyName>serverEventDatetime</excludeMdcKeyName>
<excludeMdcKeyName>level</excludeMdcKeyName>
<excludeMdcKeyName>logger</excludeMdcKeyName>
<excludeMdcKeyName>threadName</excludeMdcKeyName>
</mdc>
</providers>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>/fluent-bit/etc/logs/log_%d{yyyy-MM-dd}_%i.json</fileNamePattern>
<maxFileSize>5MB</maxFileSize>
<maxHistory>5</maxHistory>
<totalSizeCap>50MB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date %level [%thread] %logger{5} - %msg %n %xEx</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="JSON"/>
</root>
</configuration>
Здесь Logback сконфигурирован с двумя appender - STDOUT и JSON.
STDOUT – позволяет увидеть логи в консоли Kuberbetes или терминале разработчика, при отладке локально.
JSON – это файловый appender, который пишет логи в формате JSON, что удобно для дальнейшей обработки и записи в различные системы (Kafka, Elasticsearch, etc.).
В качестве json-encoder в appender используется реализация от Logstash - <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">.
Его задача - сформировать записи логов в формате JSON.
Добавить дополнительную информацию#
По желанию, в записи логов можно добавить дополнительные атрибуты, для упрощения процедуры поиска, для этого надо изменить или дополнить конфигурацию LoggingEventCompositeJsonEncoder.
Пример добавления статичного атрибута приложения, для идентификации его логов. Данные атрибуты указываются в секции pattern в файле logback-xml.yaml:
<pattern>
<omitEmptyFields>true</omitEmptyFields>
<pattern>
{
"application": "${spring.application.name}"
}
</pattern>
</pattern>
В файле application.properties из папки проекта src/main/resources для этого можно задать значение:
spring.application.name=DemoApplication
В таком случае все записи логов будут содержать атрибут application со значением "DemoApplication" Аналогичным способом можно добавлять и другие атрибуты, например, версию приложения и т.п.
Настроить ротацию логов#
Рекомендуется придерживаться следующих ограничений:
ограничить размеры файлов логов, чтобы избежать ситуаций с переполнением дискового пространства.
выполнять запись логов в разные файлы последовательно, что обеспечивает их плавную обработку fluent-bit и снизит риск потери логов при высокой интенсивности записи.
ограничить количество файлов для записи логов, таким образом, по мере заполнения, старые файлы будут постепенно удаляться, логи будут писаться в новые, по принципу очереди. Такая политика ротации настраивается следующим образом в файле logback-xml.yaml:
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/log_%d{yyyy-MM-dd}_%i.json</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>5</maxHistory>
<totalSizeCap>250MB</totalSizeCap>
</rollingPolicy>
где:
maxFileSize - максимальный размер файла, по достижению которого создается новый файл, а старый в последствии удалится, по мере накопления общего объема всех файлов логов, установленного в totalSizeCap.
В этом примере будет создано и все время поддерживаться не более 5 файлов размером до 50 MB.
При гибкой настройке этих параметров, можно минимально нивелировать потерю их fluent-bit-ом.
Настроить диагностику#
Перечень параметров для диагностики проблем в logback.xml :
configuration debug="true" - включает OnConsoleStatusListener для вывода данных о состоянии logger, что бывает нужно при диагностике проблем logback-а.
Включение данного режима не оказывает влияния на уровень логов Java.
Данный режим позволяет выводить в STDOUT информацию о работе logger logback в приложении, такую как:
конфигурация logger и ее изменения
факты ротации файлов с логами
ошибки в работе logger
Данная информация позволяет диагностировать проблемы, которые могут возникать в промышленной эксплуатации в части логирования.
Настроить runtime обновление конфигурации#
scan="true" - позволяет включить перечитывание конфигурации logback.xml и автоматической реконфигурации logback в runtime,
что позволит без перезагрузки приложения изменить конфигурацию (например, понизить или повысить уровень логов по какому-либо пакету)
По умолчанию конфигурационный файл будет сканироваться с интервалом 1 минута. Параметром
scanPeriod="30 seconds" меняется временной интервал перечитывания конфигурации logger.
В разделе <providers/> LoggingEventCompositeJsonEncoder в элементе <timestamp/> задается имя поля для времени события лога - servertEventDatetime
в формате [UNIX_TIMESTAMP_AS_NUMBER] - миллисекундах с unix epoch.
Для приложений на других языках программирования#
Для приложений на других языках программирования рекомендуется использовать следующие библиотеки:
python: python-json-logger
go: simplejson