Обзор
В приложениях Java журналы обычно делятся на следующие пять уровней:
- сообщение об ошибке ОШИБКА
- ПРЕДУПРЕЖДАЮЩЕЕ предупреждающее сообщение
- Информация Общая информация
- Информация о отладке отладки
- TRACE информация об отслеживании
Spring Boot использует Apache Commons Logging в качестве внутренней среды ведения журнала, которая представляет собой просто интерфейс ведения журнала.В практических приложениях для этого интерфейса необходимо указать соответствующую реализацию ведения журнала.
Реализацией журналов SpringBt по умолчанию является Java Util Logging, пакет журналов, поставляемый с JDK. Кроме того, SpringBt также поддерживает популярные реализации журналов, такие как Log4J и Logback.
унифицировать вышеперечисленноереализация журналав совокупности именуемыеСтруктура ведения журнала
Давайте практиковать это!
Примечание:Эта статья была впервые опубликована на моем официальном аккаунтеCodeSheep,МожетНажмитеилисканированиеследующеебудь остороженЗаходи подписывайся ↓ ↓ ↓
Использование плагина ведения журнала Spring Boot
- Сначала добавьте конфигурацию в файл application.properties:
logging.level.root=INFO
- Контроллерная часть кода выглядит следующим образом:
package com.hansonwang99.controller;
import com.hansonwang99.K8sresctrlApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/testlogging")
public class LoggingTestController {
private static Logger logger = LoggerFactory.getLogger(K8sresctrlApplication.class);
@GetMapping("/hello")
public String hello() {
logger.info("test logging...");
return "hello";
}
}
- результат операции
Поскольку уровень журнала установлен на INFO, информация журнала, содержащая INFO и выше, будет распечатана.
Здесь видно, что большинство журналов INFO поступают из самой среды SpringBt.Если мы хотим их заблокировать, мы можем сначала установить уровень журнала в ERROR, чтобы собственная информация INFO платформы не печаталась. Затем установите для конкретного пакета в приложении журнал уровня DEBUG, чтобы вы могли видеть только журналы уровня DEBUG и выше в соответствующем пакете.
- Управление уровнем журнала определенного пакета
Измените конфигурацию в application.yml
logging:
level:
root: error
com.hansonwang99.controller: debug
Очевидно, установите корневой уровень журнала на ERROR, затем установите корневой уровень журнала на ERROR.com.hansonwang99.controller
Уровень журнала пакета установлен на DEBUG, то есть: сначала отключить все, а затем разрешить отдельные методы настройки
- код контроллера
package com.hansonwang99.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/testlogging")
public class LoggingTestController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@GetMapping("/hello")
public String hello() {
logger.info("test logging...");
return "hello";
}
}
- результат операции
Видно, что логи уровня INFO самого фреймворка все скрыты, а логи в указанном пакете выводятся плавно по уровням.
- вывод лога в файл
logging:
level:
root: error
com.hansonwang99.controller: debug
file: ${user.home}/logs/hello.log
- результат операции
Используя Spring Boot Logging, мы обнаружили, что хотя журнал был выведен в файл, копия все равно будет напечатана в консоли.org.slf4j.Logger
нет способа решить эту проблему
Интегрированная среда ведения журналов Log4J.
- Добавьте зависимости в 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>
- Добавьте в каталог ресурсов
log4j2.xml
файл со следующим содержимым:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appenders>
<File name="file" fileName="${sys:user.home}/logs/hello2.log">
<PatternLayout pattern="%d{HH:mm:ss,SSS} %p %c (%L) - %m%n"/>
</File>
</appenders>
<loggers>
<root level="ERROR">
<appender-ref ref="file"/>
</root>
<logger name="com.hansonwang99.controller" level="DEBUG" />
</loggers>
</configuration>
- Весь остальной код остается прежним
Запустив программу, мы обнаруживаем, что в консоли нет вывода журнала, но есть содержимое в файле hello2.log, чего мы и ожидали:
И формат журнала иpattern="%d{HH:mm:ss,SSS} %p %c (%L) - %m%n"
соответствует формату, определенному в
Log4j дальнейшая практика
- Конфигурация 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>
- конфигурация log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="warn">
<properties>
<Property name="app_name">springboot-web</Property>
<Property name="log_path">logs/${app_name}</Property>
</properties>
<appenders>
<console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d][%t][%p][%l] %m%n" />
</console>
<RollingFile name="RollingFileInfo" fileName="${log_path}/info.log"
filePattern="${log_path}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz">
<Filters>
<ThresholdFilter level="INFO" />
<ThresholdFilter level="WARN" onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
<Policies>
<!-- 归档每天的文件 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<!-- 限制单个文件大小 -->
<SizeBasedTriggeringPolicy size="2 MB" />
</Policies>
<!-- 限制每天文件个数 -->
<DefaultRolloverStrategy compressionLevel="0" max="10"/>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${log_path}/warn.log"
filePattern="${log_path}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
<Filters>
<ThresholdFilter level="WARN" />
<ThresholdFilter level="ERROR" onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
<Policies>
<!-- 归档每天的文件 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<!-- 限制单个文件大小 -->
<SizeBasedTriggeringPolicy size="2 MB" />
</Policies>
<!-- 限制每天文件个数 -->
<DefaultRolloverStrategy compressionLevel="0" max="10"/>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${log_path}/error.log"
filePattern="${log_path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
<ThresholdFilter level="ERROR" />
<PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
<Policies>
<!-- 归档每天的文件 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<!-- 限制单个文件大小 -->
<SizeBasedTriggeringPolicy size="2 MB" />
</Policies>
<!-- 限制每天文件个数 -->
<DefaultRolloverStrategy compressionLevel="0" max="10"/>
</RollingFile>
</appenders>
<loggers>
<root level="info">
<appender-ref ref="Console" />
<appender-ref ref="RollingFileInfo" />
<appender-ref ref="RollingFileWarn" />
<appender-ref ref="RollingFileError" />
</root>
</loggers>
</configuration>
- Код контроллера:
package com.hansonwang99.controller;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/testlogging")
public class LoggingTestController {
private final Logger logger = LogManager.getLogger(this.getClass());
@GetMapping("/hello")
public String hello() {
for(int i=0;i<10_0000;i++){
logger.info("info execute index method");
logger.warn("warn execute index method");
logger.error("error execute index method");
}
return "My First SpringBoot Application";
}
}
- результат операции
Журналы будут храниться в разных файлах в соответствии с разными уровнями.Когда размер файла журнала превышает 2 МБ, он будет сжат и сохранен в нескольких файлах.Размер файла журнала в производственной среде рекомендуется настроить на 20-50 МБ.
постскриптум
Дополнительные статьи автора о SpringBt находятся здесь:
- Мониторинг приложений Spring Boot на практике
- Приложения SpringBoot развертываются во внешнем контейнере Tomcat.
- Практика поисковой системы ElasticSearch в SpringBt
- Предварительное изучение совместного программирования Kotlin+SpringBoot
- Практика ведения журнала Spring Boot
- Элегантное кодирование SpringBoot: благословение Ломбока
Если вам интересно, вы также можете уделить время прочтению некоторых статей автора о контейнеризации и микросервисах:
- Используйте стек технологий K8S для создания личного частного облака Серийная статья
- Подробная конфигурация сервера Nginx из списка конфигураций
- Строительство центра мониторинга визуализации контейнеров Docker
- Использование ELK для создания контейнерного центра журналов приложений Docker
- Практика фреймворка RPC: Apache Thrift
- Практика фреймворка RPC: Google gRPC
- Построение микросервисного центра отслеживания цепочки вызовов
- Контейнеры Docker обмениваются данными между хостами
- Предварительное исследование кластера Docker Swarm
- Несколько рекомендаций по эффективному написанию Dockerfile