Самый быстрый путь в мире — быть приземленным, эта статья включенаКолонка архитектурных технологийПодпишитесь на лайки, чтобы поделиться.
Проект с открытым исходным кодом:
- Распределенный мониторинг (самый ценный проект Gitee GVP с открытым исходным кодом):git ee.com/Примадонна Трех мушкетеров…
- Сбор видеопотока камеры:git ee.com/Примадонна Трех мушкетеров…
- Статья на GitHub включала:GitHub.com/Jianglu1989…
**Весенняя коллекция ботинок**
Spring Boot Series (1): Начало работы с SpringApplication
Серия Spring Boot (2) Анализ особенностей конфигурации
Серия Spring Boot (3): подробное объяснение последней версии элегантного завершения работы.
Spring Boot Series (4): подробная динамическая конфигурация журнала
1. Введение
Версия Spring Boot: 2.3.4.RELEASE
Я не знаю, нужны ли вам когда-нибудь какие-либо журналы DEBUG, когда возникает проблема в сети, но в настоящее время я использую INFO.
Если вы хотите включить DEBUG, вам нужно переупаковать релизную версию, но в некоторых сценариях перезапуск может не воспроизвести проблему, что на самом деле является головной болью.
Сегодня мы поговорим о динамической настройке конфигурации журнала под Spring Boot, чтобы ваш уровень журнала мог перемещаться как вам угодно.
Журналы весенней загрузки
Commons Logging на самом деле используется внутри Spring Boot, а механизм загрузки конфигурации, основанный на Spring Boot, предоставляет нам несколько методов журналирования Java Util Logging, Log4j2 и Logback.
Logback является его фреймворком по умолчанию, и заменять его без особой необходимости не рекомендуется. (не говоря уже о производительности)
формат журнала
Не стоит недооценивать формат, это важная вещь в практическом применении.
Я не знаю, есть ли в вашей компании базовый компонент единого журнала, конечно, нет файла конфигурации единого журнала.
Подумайте о том, если ваш формат журнала неоднороден, если каждый проект имеет свой собственный стиль, как вы попросите своего партнера по эксплуатации и обслуживанию помочь вам сегментировать журнал? Вызвать полицию для вас? Это действительно обычное письмо до смерти, полностью полагающееся на любовь, чтобы генерировать электричество. (Например, Loghub, который мы используем, не унифицирован и будет убит эксплуатацией и обслуживанием)
Давайте посмотрим на нашу конфигурацию формата журнала, здесь только PATTERN
-|%d{yyyy-MM-dd HH:mm:ss.SSS}|%-5level|%X{tid}|%thread|%logger{36}.%M:%L-%msg%n
Сначала объясните каждое место:
-
%d{yyyy-MM-dd HH:mm:ss.SSS}
:время -
%-5level
: уровень журнала -
%X{tid}
: наш собственный идентификатор распределенной трассировки -
%thread
: нить -
%logger{36}.%M:%L
: Полное имя класса (36 — самый длинный символ).Информация Номер строки -
%msg%n
: вывод информации о новой строке
Я не знаю, можете ли вы понять, что есть предыдущий-|
за что? На самом деле, это облегчает различение журналов новой строки, таких как информация о стеке исключений, во время обычной сегментации.
несколько очков знаний
Давайте поговорим о нескольких других моментах, используемых Spring Boot, давайте перейдем к сути
-
Здесь Logback не имеет уровня FATAL и классифицируется как ERROR.
-
допустимый
application.properties
внутренняя конфигурацияdebug=true
Чтобы включить режим отладки, вы также можете настроитьtrace=true
Включить режим трассировки -
может снова
application.properties
используется вlogging.level.<logger-name>=<level>
Этот формат используется для настройки различных уровней журнала, таких какorg.hibernate
уровень установлен на ОШИБКАlogging.level.org.hibernate=error
-
Концепция группы журналов, если такая конфигурация раздражает, вы можете установить группу, чтобы настроить ее как единое целое. Такие как:
logging.group.tomcat=org.apache.catalina, org.apache.coyote
Уровень конфигурации TRACElogging.level.tomcat=TRACE
-
Если вы используете файл конфигурации Logback, официально рекомендуется использовать
logback-spring.xml
такое имя, если вы используетеlogback.xml
Таким образом, должна возникнуть проблема с инициализацией журнала Spring. -
Если вы управляете конфигурацией ведения журнала, но не хотите использовать logback.xml в качестве имени конфигурации Logback, вы можете указать пользовательское имя в файле конфигурации application.properties через свойство logging.config:
logging.config=classpath:xxx-log.xml
2. Динамически изменять уровень журнала
Поговорим о том, как приложение Spring Boot в рабочем состоянии изменяет уровень динамического логирования
Spring Boot Actuator
Привод должен знать название Spring Boot, информацию о мониторинге, аудите, измерениях и так далее. Грамотное завершение работы, проверка работоспособности и информация журнала, которую мы используем, реализуются с помощью этой штуки.
После того, как мы используем Actuator, мы можем использовать его REST-интерфейс Logger для работы с нашими журналами, есть следующие три
-
GET http://127.0.0.1:6080/actuator/loggers
Возвращает всю информацию об уровне журнала текущего приложения (независимо от того, что вы хотите) -
GET http://127.0.0.1:6080/actuator/loggers/{name}
Возвращает уровень журнала {name} -
POST http://127.0.0.1:6080/actuator/loggers/{name}
Параметры конфигурации{"configuredLevel":"INFO","effectiveLevel":"INFO"}
Изменить уровень журнала
Динамически изменять уровни с помощью механизма актуатора
1), полагаться на необходимую конфигурацию Spring Boot Actuator (при наследовании родительской версии не требуется)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
2), файл конфигурации
#注意,这里我只开启了loggers,health两个Actuator
management.endpoints.web.exposure.include=loggers,health
management.endpoint.loggers.enabled=true
3), создайте контроллер
@RestController
@RequestMapping("/log")
public class TestLogController {
private Logger log = LoggerFactory.getLogger(TestLogController.class);
@GetMapping
public String log() {
log.trace("This is a TRACE level message");
log.debug("This is a DEBUG level message");
log.info("This is an INFO level message");
log.warn("This is a WARN level message");
log.error("This is an ERROR level message");
return "See the log for details";
}
}
4), запустить приложение
На данный момент, после запуска приложения, если вы используете IDEA, вы можете увидеть следующее сопоставление, есть три интерфейса REST для регистратора.
5), тест
В этот момент я сначала выполняюGET http://127.0.0.1:6080/log
, консоль выводит следующую информацию
2020-10-15 23:14:51.204 INFO 52628 --- [nio-6080-exec-7] c.q.chapter1.failure.TestLogController : This is an INFO level message
2020-10-15 23:14:51.220 WARN 52628 --- [nio-6080-exec-7] c.q.chapter1.failure.TestLogController : This is a WARN level message
2020-10-15 23:14:51.221 ERROR 52628 --- [nio-6080-exec-7] c.q.chapter1.failure.TestLogController : This is an ERROR level message
В этот момент мы выполняемGET http://127.0.0.1:6080/actuator/loggers/ROOT
вернуть{"configuredLevel":"INFO","effectiveLevel":"INFO"}
, что означает, что уровень журнала нашего приложения в это время — INFO, а ROOT представляет собой корневой узел.
6), изменить уровень
На данный момент мы не хотим больше смотреть на информацию INFO, и если мы хотим изменить уровень журнала всего приложения на WARN, давайте выполнимPOST http://127.0.0.1:6080/actuator/loggers/ROOT
Параметры{"configuredLevel":"TRACE","effectiveLevel":"TRACE"}
В этот момент мы выполнимGET http://127.0.0.1:6080/log
, консоль выводит следующую информацию
2020-10-15 23:24:11.481 TRACE 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController : This is a TRACE level message
2020-10-15 23:24:11.481 DEBUG 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController : This is a DEBUG level message
2020-10-15 23:24:11.481 INFO 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController : This is an INFO level message
2020-10-15 23:24:11.481 WARN 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController : This is a WARN level message
2020-10-15 23:24:11.481 ERROR 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController : This is an ERROR level message
другие методы
-
Сканирование файла конфигурации: это уровень модификации функции автоматического сканирования журнала.
logback-spring.xml
включи<configuration scan="true" scanPeriod="15 seconds">
динамическая модификацияlogback-spring.xml
Назначение внутреннего уровня журнала, если вам интересно, можете попробовать сами. -
Артас Динамическая модификация
-
Привязка конфигурации удаленного центра, например Apollo, для достижения уровня динамической модификации
3. Принцип реализации
Здесь мы в основном используемSpring Boot Actuator Log
, поэтому мы также говорим о его принципе.
Загрузка конечных точек
Сначала начнем с зависимостиspring-boot-actuator
найти нашLoggersEndpoint
(Все актуаторы имеют этот номер), как показано на рисунке:
Друзья, знакомые с механизмом загрузки Spring Boot, знают, что за каждой конечной точкой привода должен стоять еще одинxxxEndpointAutoConfiguration
Давайте загрузим Endpoint для нас.
И эти механизмы загрузки хранятся вspring-boot-actuator-autoconfigure
, в котором находимLoggersEndpointAutoConfiguration
для погрузкиLoggersEndpoint
класс конфигурации.
Давайте взглянем на его ядро:
@Bean
@ConditionalOnBean(LoggingSystem.class)
@Conditional(OnEnabledLoggingSystemCondition.class)
@ConditionalOnMissingBean
public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem,
ObjectProvider<LoggerGroups> springBootLoggerGroups) {
return new LoggersEndpoint(loggingSystem, springBootLoggerGroups.getIfAvailable(LoggerGroups::new));
}
Можно увидеть два важных параметра:
- LoggingSystem: абстрактный класс верхнего уровня.
- springBootLoggerGroups: сохраняет текущие данные группы журналов.
Обобщить:
1. Мы зависим отspring-boot-starter-actuator
После пакета, это зависит отspring-boot-actuator-autoconfigure
2. Запустите сканированиеspring-boot-actuator-autoconfigure
внизMETA-INF/spring.factories
час,LoggersEndpointAutoConfiguration
будет загружен в
3.LoggersEndpointAutoConfiguration
объявил сноваLoggersEndpoin
и назначитьLoggingSystem
а такжеspringBootLoggerGroups
как его параметр
4. После старта проекта проходимLoggersEndpoint
Интерфейс для доступа к данным журнала
LoggingSystem
Отношение наследования LoggingSystem
Из вышесказанного можно понятьLoggingSystem
Это ядро управления операциями с журналами, поэтому давайте сначала взглянем на его диаграммы.
Вы можете сразу увидеть отношения наследования,LogbackLoggingSystem
Это наш мастер, хотя мастер нам известен, как именно загружается наша LoggingSystem?
Загрузка LoggingSystem
Основные классы участия следующие:
LoggingApplicationListener
ApplicationStartingEvent
LogbackLoggingSystem
LoggingSystem
Нечего сказать, первое фото
1. Использование приложенияSpringApplication.run(Chapter1Application.class, args);
запускать
2. Отправить стартовое событиеApplicationStartingEvent
,ApplicationEnvironmentPreparedEvent
Ждать
3.LoggingApplicationListener
Получение событий для распространения событий
4.LoggingApplicationListener
получать событияApplicationStartingEvent
5.LoggingApplicationListener
позвони внутрьonApplicationStartingEvent(ApplicationStartingEvent event)
метод, используйте LoggingSystem.get(classloader) для инициализации LoggingSystem.
6. Затем позвонитеLogbackLoggingSystem.beforeInitialize()
(потому что здесь мы используем logback)
7.LoggingApplicationListener
получать событияApplicationEnvironmentPreparedEvent
8,LoggingApplicationListener
позвони внутрьonApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event)
метод
9,onApplicationEnvironmentPreparedEvent
перечислитьinitialize(ConfigurableEnvironment environment, ClassLoader classLoader)
метод, инициализирует систему ведения журнала в соответствии с конфигурацией переменной среды.
LoggersEndpoint
Наконец, давайте взглянем на LoggersEndpoint.Для удобства толкования я не буду копировать все это здесь.Где вам нужно выбрать?
Сначала взгляните на наши три интерфейса для операций с журналами:
-
GET /actuator/loggers
вести перепискуpublic Map<String, Object> loggers()
метод -
GET /actuator/loggers/{name}
вести перепискуpublic LoggerLevels loggerLevels(@Selector String name)
метод -
POST /actuator/loggers/{name}
вести перепискуpublic void configureLogLevel(@Selector String name, @Nullable LogLevel configuredLevel)
метод
возьми один здесьpublic Map<String, Object> loggers()
Способ примерный, остальные почти такие же
@ReadOperation
public LoggerLevels loggerLevels(@Selector String name) {
Assert.notNull(name, "Name must not be null");
LoggerGroup group = this.loggerGroups.get(name);
if (group != null) {
return new GroupLoggerLevels(group.getConfiguredLevel(), group.getMembers());
}
LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(name);
return (configuration != null) ? new SingleLoggerLevels(configuration) : null;
}
Код на самом деле очень простой, поэтому нет необходимости его слишком много интерпретировать.
В-четвертых, болтовня
Фактически, журналы очень важны для наших системных приложений, а также являются важными учетными данными для устранения неполадок. Согласно нашему опыту, журнал нашей системы может лучше всего достигать нескольких пунктов:
-
Унификация формата журнала
-
Лучше всего предоставить единый компонент журнала, например, мы используем общедоступный компонент logback-spring.xml. Если нам нужно изменить некоторые функции журнала, такие как добавление журналов APM и т. Д., Нам нужно изменить только одну точку, и все состояния журнала нашей системы изменятся.
-
Лучше всего использовать динамическую настройку и настроить конфигурацию журнала, например Apollo
Самый быстрый путь в мире — быть приземленным, эта статья включенаКолонка архитектурных технологийПодпишитесь на лайки, чтобы поделиться.
Проект с открытым исходным кодом:
- Распределенный мониторинг (самый ценный проект Gitee GVP с открытым исходным кодом):git ee.com/Примадонна Трех мушкетеров…
- Сбор видеопотока камеры:git ee.com/Примадонна Трех мушкетеров…
- Статья на GitHub включала:GitHub.com/Jianglu1989…