Spring Boot — изучение фреймворка ведения журналов

Java

Версия:

  • Spring Boot 2.1.5.RELEASE

  • maven 3.2.5

  • jdk1.8

1. Фреймворк логирования, который я выбираю:

  • Бревенчатый фасад (абстрактный слой): SLF4J
  • Реализация журнала: Logback

Spring Boot: нижний уровень — это среда Spring, а среда Spring по умолчанию использует JCL;

И Spring Boot выбирает SLF4j и Logback


2. Использование SLF4j

1) Как использовать SLF4J в системе

Официальное руководство SLF4j

При разработке вызов метода ведения журнала не требует изменения класса реализации, непосредственно вызывающего журнал, а вызывает метод в слое абстракции журнала;

  • Импортируйте банку slf4j и реализацию jar logback.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

Схематическая диаграмма объединения SLF4j с другими фреймворками ведения журналов:

2) Унаследованные проблемы

Хотя я использую (slf4j и logback), другие, такие как среда Spring, используютcommons-loggingФреймворк ведения журнала, который использует Hibernatejboss-loggingСтруктура ведения журналов и так далее настолько запутана, что мы собираемсяУнифицированное ведение журнала, даже если другие фреймворки захотят использовать slf4j вместе со мной для вывода;

Официальная принципиальная схема:

логика:

  • 1. Исключить другие фреймворки логов в системе;
  • 2. Структура ведения ведения журнала для замены исходного промежуточного соединения (красный в корзине);
  • 3. Импортируйте другие реализации slf4j

3. Связь с журналом Spring Boot

На самом деле этот пакет зависит от этого:

	<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
      <version>2.1.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>

существуетфайл pomЩелчок правой кнопкой мыши:

Все графы зависимостей SpringBoot мы смотрим только на логирование:

Я использую версию Spring Boot 2.1.5.В процессе обучения автор обнаружил, что видео преподавателя, которое я смотрел, отличается от моей версии.

Вот версия учителя:

Очевидно, не так, как я, но Spring, должно быть, обновил свой нижний слой;

Точнее не апгрейд, а конверсия фреймворка jcl исключается, т.к. дата последнего обновления фреймворка jcl 2014, что явно устарело

Но исходя из основных рассуждений, официальная карта сайта slf4j действительно является указанием на версию SpringBoot1.x, но она не совпадает с моей версией 2.x, а по названию моего пакета их функции схожи, они все преобразован в slf4j;

краткое содержание:

  • 1. Нижний уровень SpringBoot также slf4j+logback для логирования;
  • 2. SpringBoot также заменяет другие логи на slf4j;
  • 3. Промежуточный сменный пакет;

Иллюстрация промежуточного сменного пакета:

4) Если мы хотим ввести другие фреймворки, обязательно удалим зависимость журнала по умолчанию от этого фреймворка!

Среда ведения журнала по умолчанию в среде Spring: commons-logging;

Однако, когда Spring Boot представил пакет jar ядра spring, пакет log jar был удален;

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


4. Использование журнала

Тестовый класс:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootLoggingApplicationTests {
    // 日志记录器记录器
    Logger logger = LoggerFactory.getLogger(getClass());
    @Test
    public void contextLoads() {
        // 日志的级别
        // 由低到高 trace < debug < info < warn < error

        logger.trace("这是trace日志..");
        logger.debug("这是debug调试日志..");
        logger.info("这是info日志..");
        logger.warn("这是warn日志...");
        logger.error("这是error错误日志");
    }

}

Рабочий вывод:

2019-07-02 19:22:35.980  INFO 8404 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是info日志..
2019-07-02 19:22:35.981  WARN 8404 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是warn日志...
2019-07-02 19:22:35.981 ERROR 8404 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是error错误日志

То есть уровень журнала SpringBoot по умолчанию равенinfo, поэтому выводятся только информация и журналы, превышающие уровень информации;

Откройте мой файл конфигурации yml:

logging:
  level:
    com.carson: trace

Это означает установить все пакеты под моим com.carson на уровень журнала трассировки.

Выходной результат:

2019-07-02 19:29:17.406 TRACE 7076 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是trace日志..
2019-07-02 19:29:17.407 DEBUG 7076 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是debug调试日志..
2019-07-02 19:29:17.407  INFO 7076 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是info日志..
2019-07-02 19:29:17.408  WARN 7076 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是warn日志...
2019-07-02 19:29:17.408 ERROR 7076 --- [           main] c.c.s.SpringBootLoggingApplicationTests  : 这是error错误日志

4.1 Детали файла конфигурации:

logging.level.com.carson= trace
# path: 只创建任意一个文件夹, SpringBoot会默认生成一个 spring.log 作为日志文件
logging.path= F:/spring/log
# file: 指定一个路径和文件把 日志输出到 指定文件里
logging.file= F:/springboot.log
# pattern.console: 控制台输出的日志格式
logging.pattern.console= %d{yyyy‐MM‐dd} === [%thread] === %‐5level === %logger{50} ==== %msg%n
#   pattern.file : 指定文件中日志的输出格式
logging.pattern.file= %d{yyyy‐MM‐dd} === [%thread] === %‐5level === %logger{50} ==== %msg%n

4.2 Укажите конфигурацию

структура регистрации именование файлов
Logback logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

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

  • logback-spring.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">
    <!-- 定义日志的根目录 -->
    <property name="LOG_HOME" value="/app/log" />
    <!-- 定义日志文件名称 -->
    <property name="appName" value="atguigu-springboot"></property>
    <!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--
        日志输出格式:
			%d表示日期时间,
			%thread表示线程名,
			%-5level:级别从左显示5个字符宽度
			%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
			%msg:日志消息,
			%n是换行符
        -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
            <springProfile name="!dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
        </layout>
    </appender>

    <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 指定日志文件的名称 -->
        <file>${LOG_HOME}/${appName}.log</file>
        <!--
        当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
        TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--
            滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
            %i:当文件大小超过maxFileSize时,按照i进行文件滚动
            -->
            <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <!--
            可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
            且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,
            那些为了归档而创建的目录也会被删除。
            -->
            <MaxHistory>365</MaxHistory>
            <!--
            当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy
            -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 日志输出格式: -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
        </layout>
    </appender>

    <!--
		logger主要用于存放日志对象,也可以定义日志类型、级别
		name:表示匹配的logger类型前缀,也就是包的前半部分
		level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
		additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,
		false:表示只用当前logger的appender-ref,true:
		表示当前logger的appender-ref和rootLogger的appender-ref都有效
    -->
    <!-- hibernate logger -->
    <logger name="com.atguigu" level="debug" />
    <!-- Spring framework logger -->
    <logger name="org.springframework" level="debug" additivity="false"></logger>



    <!--
    root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,
    要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。
    -->
    <root level="info">
        <appender-ref ref="stdout" />
        <appender-ref ref="appLogAppender" />
    </root>
</configuration>

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

  • logback.xml: напрямую распознается фреймворком ведения журнала.

  • Но если вы назовете его logback-spring.xml (рекомендуется): среда ведения журнала не загружает элементы конфигурации журнала напрямую, и вы можете использовать расширенную функцию SpringBoot для анализа журнала с помощью SpringBoot.

<springProfile name="prod">
	<!-- 是不是 prod 环境 -->
</springProfile>

<springProfile name="dev | prod">
	<!--  dev 和 prod 都会执行 -->
</springProfile>

<springProfile name="!dev">
	<!-- 如果不是 dev环境 -->
</springProfile>

То есть в конфигурационном файле только что:

<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--
        日志输出格式:
			%d表示日期时间,
			%thread表示线程名,
			%-5level:级别从左显示5个字符宽度
			%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
			%msg:日志消息,
			%n是换行符
        -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
            <springProfile name="!dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
        </layout>
    </appender>

Вы можете настроить его в своем yml или свойствах:

spring.profiles.active= prod

установить операционную среду

4.3 Использование log4j

На самом деле, SpringBoot официально нам немного помог.:

Name Description Pom
spring-boot-starter-jetty Starter for using Jetty as the embedded servlet container. An alternative to spring-boot-starter-tomcat Pom
spring-boot-starter-log4j2 Starter for using Log4j2 for logging. An alternative to spring-boot-starter-logging Pom
spring-boot-starter-logging Starter for logging using Logback. Default logging starter Pom
spring-boot-starter-reactor-netty Starter for using Reactor Netty as the embedded reactive HTTP server. Pom
spring-boot-starter-tomcat Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web Pom
spring-boot-starter-undertow Starter for using Undertow as the embedded servlet container. An alternative to spring-boot-starter-tomcat Pom

Просто импортируйте, какой пакет вы хотите использовать, какую структуру журнала.Например, если я хочу использовать log4j2, я сначала поставлю пакет по умолчанию.spring-boot-starter-loggingИсключено, метод исключения следующий:

  • Затем в файле pom:
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>

Импортируйте пакет log4j2;

  • Затем создайте файл конфигурации log4j в ресурсах, и имя файла — это то, что я только что сказал:

содержание:

### set log levels ###
log4j.rootLogger = debug ,  stdout ,  D ,  E

### 输出到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} ===== %5p %c{ 1 }:%L - %m%n

#### 输出到日志文件 ###
#log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#log4j.appender.D.File = logs/log.log
#log4j.appender.D.Append = true
#log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志
#log4j.appender.D.layout = org.apache.log4j.PatternLayout
#log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
#
#### 保存异常信息到单独文件 ###
#log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#log4j.appender.D.File = logs/error.log ## 异常日志文件名
#log4j.appender.D.Append = true
#log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!!
#log4j.appender.D.layout = org.apache.log4j.PatternLayout
#log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

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


личный блог:aaatao66.github.io/