Самый быстрый путь в мире — быть приземленным, эта статья включенаКолонка архитектурных технологийПодпишитесь на лайки, чтобы поделиться.
Проект с открытым исходным кодом:
- Распределенный мониторинг (самый ценный проект 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
Основные классы участия следующие:
LoggingApplicationListenerApplicationStartingEventLogbackLoggingSystemLoggingSystem
Нечего сказать, первое фото
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…