Ведение журнала в Spring Boot

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Ведение журнала является важной частью всех приложений и приносит пользу не только нам, разработчикам, но и пользователям системы, а также сопровождающим ее. Приложения Spring Boot должны собирать соответствующие данные журнала, чтобы помочь нам диагностировать и устранять проблемы и измерять бизнес-показатели.

Фреймворк Spring Boot предварительно настроен с использованием Logback в качестве реализации по умолчанию в его "компетентном" подходе к Spring Framework. В этой статье рассматриваются различные способы настройки ведения журнала в Spring Boot.

 Пример кода

Эта статья сопровождается примером рабочего кода на GitHub .

Почему важно журналирование

Решения о том, что и где журналировать, часто носят стратегический характер и принимаются с учетом того, что приложение может работать неправильно в реальных средах. Журналы играют ключевую роль, помогая приложению быстро восстанавливаться после любых таких сбоев и возобновлять нормальную работу.

Делаем ошибки в точках интеграции видимыми

Распределенная природа сегодняшних приложений, построенных с использованием микросервисной архитектуры, вводит множество рабочих частей. Таким образом, естественно можно столкнуться с проблемами из-за временных сбоев в любой из инфраструктурных систем.

Журналы исключений, регистрируемые в точках интеграции, позволяют нам обнаружить основную причину прерывания и позволяют нам предпринимать соответствующие действия для восстановления с минимальным влиянием на работу конечного пользователя.

Диагностика функциональных ошибок в производственой системе

Могут быть жалобы клиентов на неправильную сумму транзакции. Чтобы диагностировать это, нам нужно детализировать наши журналы, чтобы найти последовательность операций, начиная с данных запроса при вызове API до данных ответа в конце работы API обработки.

Анализ истории событий

Записи журнала фиксируют трассу выполнения приложения. Мы обращаемся к этим журналам постфактум, чтобы проанализировать любое нормальное или неожиданное поведение приложения для различных задач.

Мы можем узнать количество пользователей, вошедших в систему в течение определенного временного окна, или сколько пользователей активно используют любую недавно выпущенную функцию, что является ценной информацией для планирования изменений для будущих выпусков.

Мониторинг

Инструменты мониторинга отслеживают журналы в режиме реального времени для сбора важных показателей, полезных как для бизнеса, так и для операций, а также могут быть настроены для подачи сигналов тревоги, когда эти показатели превышают определенные пороговые значения. Разработчики используют журналы для отладки и трассировки и даже для записи важных событий для сборки и тестирования в конвейерах CI / CD.

Конфигурация журнала Spring Boot по умолчанию

Конфигурация ведения журнала по умолчанию в Spring Boot - это реализация Logback на уровне информации для записи вывода на консоль.

Давайте посмотрим на это поведение в действии, создав приложение Spring Boot. Мы создаем минимальное приложение только с веб-зависимостью, используя start.spring.io . Затем мы добавляем несколько операторов журнала в файл класса приложения:

@SpringBootApplication
public class SpringLoggerApplication {
    static final Logger log = 
        LoggerFactory.getLogger(SpringLoggerApplication.class);
  
    public static void main(String[] args) {
     log.info("Before Starting application");
     SpringApplication.run(SpringLoggerApplication.class, args);
     log.debug("Starting my application in debug with {} args", args.length);
     log.info("Starting my application with {} args.", args.length);  
    }
  }

После компиляции с помощью Maven или Gradle и запуска полученного файла jar мы можем увидеть, как наши записи журнала печатаются в консоли:

13:21:45.673 [main] INFO io.pratik.springLogger.SpringLoggerApplication - Before Starting application

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.2.RELEASE)
.
.
.
... : Started SpringLoggerApplication in 3.054 seconds (JVM running for 3.726)
... : Starting my application 0

Печатается первый информационный журнал, за ним следует семистрочный баннер Spring, а затем следующий информационный журнал. Записи отладки отключены.

Высокоуровневая конфигурация ведения журнала

Spring Boot предлагает значительную поддержку для настройки ведения журнала в соответствии с нашими требованиями к ведению журнала.

На высоком уровне мы можем изменить параметры командной строки или добавить свойства application.properties(или application.yml), чтобы настроить некоторые функции ведения журнала.

Настройка уровня журнала с помощью параметра командной строки

Иногда нам необходимо просмотреть подробные журналы для устранения неполадок в поведении приложения. Для этого мы отправляем желаемый уровень журнала в качестве аргумента при запуске нашего приложения.

java -jar target/springLogger-0.0.1-SNAPSHOT.jar --trace

Это начнет вывод журналов уровня трассировки, отладки, информации, предупреждений и ошибок.

Настройка ведения журнала на уровне пакета

В большинстве случаев нас больше интересует вывод журнала написанного нами кода, а не вывод журнала из таких фреймворков, как Spring. Мы контролируем ведение журнала, указывая имена пакетов в переменной окружения log.level.<package-name>:

java \\
  -jar target/springLogger-0.0.1-SNAPSHOT.jar \\
  -Dlogging.level.org.springframework=ERROR \\
  -Dlogging.level.io.pratik=TRACE

В качестве альтернативы мы можем указать наш пакет в application.properties:

logging.level.org.springframework=ERROR 
logging.level.io.app=TRACE

Журналирование в файл

Мы можем записывать наши журналы в файл, установив только одно из свойств logging.file.nameили logging.file.pathв нашем application.properties. По умолчанию для вывода в файл установлен уровень журнала info.

# Output to a file named application.log. 
logging.file.name=application.log
# Output to a file named spring.log in path /Users
logging.file.path=/Users

Если заданы оба свойства, только logging.file.nameвступает в силу.

Обратите внимание, что название этих свойств изменилось в Spring 2.2 и далее, но в официальной документации это еще не отражено. Наш пример работает с версией 2.3.2.RELEASE.

Помимо имени файла, мы можем переопределить шаблон ведения журнала по умолчанию с помощью свойства logging.pattern.file:

# Logging pattern for file
logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%

Другие свойства, связанные с файлом журнала:

Свойство

Что это значит

Значение, если не установлено

logging.file.max-size

максимальный общий размер архива журнала до ротации файла

10 Mb

logging.file.max-history

сколько дней должны храниться файлы ротации журналов

7 дней

logging.file.total-size-cap

общий размер архивов журналов. Резервные копии удаляются, когда общий размер архивов журналов превышает этот порог.

не указано

logging.file.clean-history-on-start

принудительная очистка архива журнала при запуске приложения

ложный

Мы можем применить ту же настройку в отдельном файле конфигурации, как мы увидим в следующем разделе.

Отключение баннера

Spring баннер в верхней части файла журнала не добавляет никакой информации. Мы можем отключить баннер, установив для свойства значение off в application.properties:

spring.main.banner-mode=off 

Изменение цвета вывода журнала в консоли

Мы можем отображать вывод с цветовой кодировкой ANSI, установив spring.output.ansi.enabledсвойство. Возможные значения: ВСЕГДА, ОБНАРУЖЕНИЕ и НИКОГДА.

spring.output.ansi.enabled=ALWAYS

По умолчанию для свойства spring.output.ansi.enabledустановлено DETECTзначение. Цветной вывод действует только в том случае, если целевой терминал поддерживает коды ANSI.

Переключение реализации журналирования

Logback стартер является частью стартера Spring Boot по умолчанию. Мы можем заменить его на реализации log4j или java util, включив их стартеры и исключив стартер по умолчанию spring-boot-starter-loging в pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Низкоуровневая конфигурация ведения журнала в logback-spring.xml

Мы можем изолировать конфигурацию журнала из приложения, указав конфигурацию logback.xmlили logback-spring.xmlв XML или заводной синтаксиса. Spring рекомендует использовать logback-spring.xmlили, logback-spring.groovyпотому что они более мощные.

Конфигурация по умолчанию состоит из appenderэлемента внутри корневого configurationтега. Шаблон указывается внутри encoderэлемента:

<configuration >
  <include
    resource="/org/springframework/boot/logging/logback/base.xml" />
  <appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
      </pattern>
    </encoder>
  </appender>
</configuration>

Ведение журнала с конфигурацией Logback

Если мы установим для debugсвойства в configurationтеге значение true, мы сможем увидеть значения конфигурации логбэка во время запуска приложения.

<configuration debug="true">

Запуск нашего приложения с этим параметром дает результат, содержащий значения конфигурации Logback, используемого в приложении:

...- About to instantiate appender of type [...ConsoleAppender]
...- About to instantiate appender of type [...RollingFileAppender]
..SizeAndTimeBasedRollingPolicy.. - setting totalSizeCap to 0 Bytes
..SizeAndTimeBasedRollingPolicy.. - ..limited to [10 MB] each.
..SizeAndTimeBasedRollingPolicy.. Will use gz compression
..SizeAndTimeBasedRollingPolicy..use the pattern /var/folders/
..RootLoggerAction - Setting level of ROOT logger to INFO

Отслеживание запросов через микросервисы

Отладка и отслеживание в приложениях микросервисов является сложной задачей, поскольку микросервисы развертываются и запускаются независимо, в результате чего их журналы распределяются во множестве отдельных компонентов.

Мы можем сопоставить наши журналы и запросы трассировки между микросервисами, добавив информацию отслеживания в шаблон ведения журнала в logback-spring.xml. Пожалуйста, ознакомьтесь с трассировкой в ​​распределенных системах для более подробного объяснения распределенной трассировки.

Агрегирование журналов на сервере журналов

Журналы из разных микросервисов можно собирать в центральном месте. Для Spring Boot нам нужно выводить журналы в формате, совместимом с программным обеспечением агрегирования журналов. Давайте посмотрим на приложение, настроенное для Logstash:

  <appender name="LOGSTASH"
    class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>localhost:4560</destination>
    <encoder charset="UTF-8"
      class="net.logstash.logback.encoder.LogstashEncoder" />
  </appender>

Здесь LogstashEncoderжурналы кодируются в формате JSON и отправляются на сервер журналов по адресу localhost:4560. Затем мы можем применить различные инструменты визуализации к журналам запросов.

Настройка ведения журнала для разных сред

У нас часто используются разные форматы журналов для локальной и производственной среды выполнения. Профили Spring - это элегантный способ реализовать различное ведение журнала для каждой среды. В этой статье вы можете сослаться на очень хороший пример использования ведения журнала для конкретной среды .

Использование Lombok для ссылки на реализацию журналирования

Просто как подсказка, чтобы сэкономить время на вводе: мы можем использовать аннотацию Lombok, Slf4jчтобы указать ссылку на на реализацию журналирования:

@Service
@Slf4j
public class UserService {
  public String getUser(final String userID) {
    log.info("Service: Fetching user with id {}", userID);
  }
}

Вывод

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

Эти методы также необходимо будет внедрить с помощью сочетания экспертных оценок и автоматизированных инструментов контроля качества кода. Все вместе взятые гарантирует, что при возникновении производственных ошибок у нас будет максимум информации для диагностики.

Вы можете найти весь исходный код, использованный в статье на Github .

Источник: https://habr.com/ru/post/521950/


Интересные статьи

Интересные статьи

Часто на практике возникает необходимость централизованной обработки исключений в рамках контроллера или даже всего приложения. В данной статье разберём основные возможности, которые пр...
В продолжении одной из тем, поднятых в публикации Александра Ершова (Ustas) «Нейросетевой визуальный поиск», предлагаю читателям Хабра погрузиться в мир концепции Н.М. Амосова, ее -мо...
Что бы разбавить зубодробительную математику лекций Козлова Олега Степановича "Управление в технических системах", публикуем здесь пример применения знаний из этих лекций на...
Меня зовут Стас Кириллов, я ведущий разработчик в группе ML-платформ в Яндексе. Мы занимаемся разработкой инструментов машинного обучения, поддержкой и развитием инфраструктуры для них. Ниже — мо...
Сегодняшний Netflix заточен на изменение поведения посредством сторителлинга. Этому есть три причины.