暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring Boot 配置日志系统

鹰击太空 2021-06-28
718

在一个项目中,日志是一个必不可少的组件。日志能帮助开发人员更好的调试程序,可以帮助运维人员查看的当前应用运行的状态。而在我们的Spring Boot
的应用中默认使用的是Logback
Logbacklog4j
框架的作者开发的新一代日志框架,它效率更高、能够适应诸多的运行环境。因为是一个作者,所以更好的支持SLF4J
。日志可以通过配置使用控制台或者文件输出日志内容。

演示环境

  • IntelliJ IDEA 2018.2.1 (Community Edition)

  • Maven 3.5.4

  • Spring Boot 2.1.1.RELEASE

了解Spring Boot
默认日志

SLF4J(Simple Logging Facade For Java)是一个针对于各类Java日志框架的统一抽象。Java日志框架有很多比如常用的有java.util.logging
, log4j
, logback
commons-logging
Spring
框架使用的是Jakarta Commons Logging API (JCL)
。而SLF4J
定义了统一的日志抽象接口,而真正的日志实现,则是看我们引入了哪些日志的实现。也有出现在SLF4J
的之前的日志框架,比如:java.util.logging
log4j
等。这些框架并没有实现SLF4J
的接口,当我们使用的框架的默认日志实现不同的话,很容易造成错乱。所以这个时候就出现了很多的过度包。比如:

  • java.util.logging
    --jul-to-slf4j.jar

  • log4j
    --log4j-to-slf4j.jar

  • commons-logging
    --jcl-over-slf4j.jar

有了这些过度的包,我们就可以通过调用SLF4J
的API来调用任一日志实现,不会出现日志框架冲突等问题,我们的项目中只需要一个SLF4J
的实现即可。

Logbacklog4j框架的作者开发的新一代日志框架,它效率更高、能够适应诸多的运行环境,同时天然支持SLF4J

1、Spring Boot
日志的依赖关系

我们的spring-boot-starter
依赖了spring-boot-starter-logging
,这个spring-boot-starter-logging
就是整合了SLF4J
Logback
。所以我们可以说Spring Boot
默认使用的是Logback
作日志实现。并且日志的默认等级是INFO
,可以在这儿spring-boot-2.1.1.RELEASE.jar!/org/springframework/boot/logging/logback/base.xml
文件中看到。

2、Spring Boot
日志实现的优先级

我们的Spring Boot
的源码中,在这个类中定义了日志实现方式的获取org.springframework.boot.logging.LoggingSystem
,我们来读一下源码:

public abstract class LoggingSystem {

private static final Map<String, String> SYSTEMS;

static {
Map<String, String> systems = new LinkedHashMap<>();
systems.put("ch.qos.logback.core.Appender",
"org.springframework.boot.logging.logback.LogbackLoggingSystem");
systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
"org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
systems.put("java.util.logging.LogManager",
"org.springframework.boot.logging.java.JavaLoggingSystem");
SYSTEMS = Collections.unmodifiableMap(systems);
}
   
  public static LoggingSystem get(ClassLoader classLoader) {
String loggingSystem = System.getProperty(SYSTEM_PROPERTY);
if (StringUtils.hasLength(loggingSystem)) {
if (NONE.equals(loggingSystem)) {
return new NoOpLoggingSystem();
}
return get(classLoader, loggingSystem);
}
return SYSTEMS.entrySet().stream()
.filter((entry) -> ClassUtils.isPresent(entry.getKey(), classLoader))
.map((entry) -> get(classLoader, entry.getValue())).findFirst()
.orElseThrow(() -> new IllegalStateException(
"No suitable logging system located"));
}
}

这里Spring Boot
默认添加了三种的日志实现logback
log4j2
jul
。然后这些被加载进了一个Map
中,在获取日志系统的方法中,使用findFirst()
来获取日志系统。所以我们这里可以大胆的说Spring Boot
日志级别是logback>log4j2>jul

这里只摘取了部分源码,作为分析使用。

配置Spring Boot
的日志

在这里Spring Boot
给我们提供了根据配置文件来修改默认配置。

1、根据propreties
文件配置

日志的默认级别是INFO
,如果想使用DEBUG
级别的日志,只需要在配置文件中添加:

debug=true

控制日志等级,可以指定root
的日志等级,还可以指定具体包的日志等级:

logging.level.root=INFO
logging.level.xin.jerome=DEBUG

也可以对包进行分组后,在进行控制日志等级:

logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat
logging.level.tomcat=TRACE

将日志输出到具体的文件,默认文件大小10MB
,也可以指定绝对路径:

logging.file=xxx.log
logging.file=/var/log/xxx.log

将日志文件输出到具体的路径下,默认创建spring.log
文件(仅logback
支持):

logging.path=/var/log

控制日志文件的大小(仅logback
支持):

logging.file.max-size=1MB

控制日志文件存档的最大值(仅logback
支持):

logging.file.max-history=30

格式化控制台输出(仅logback
支持):

logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n

格式化文件输出(仅logback
支持):

logging.pattern.file=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n

格式化日志日期输出(仅logback
支持):

logging.pattern.dateformat=yyyy-MM-dd HH:mm:ss.SSS

2、根据xml
配置文件配置

由于日志服务一般都在ApplicationContext创建前就初始化了,它并不是必须通过Spring的配置文件控制。因此通过系统属性和传统的Spring Boot外部配置文件依然可以很好的支持日志控制和管理。

根据不同的日志系统,按如下规则组织配置文件名,就能被正确加载:

  • Logback:logback-spring.xml
    , logback-spring.groovy
    , logback.xml
    , logback.groovy

  • Log4j2:log4j2-spring.xml
    , log4j2.xml

  • JDK (Java Util Logging):logging.properties

上面是默认的命名规则,并且放在src/main/resources
下面即可。

当然使用配置的方式指定我们配置文件的位置:

logging.config=classpath:logback.xml

Spring Boot
官方推荐优先使用带有-spring
的文件名作为你的日志配置(如使用logback-spring.xml
,而不是logback.xml
),命名为logback-spring.xml
的日志配置文件,Spring Boot
可以为它添加一些Spring Boot
特有的配置项,由Spring Boot
解析日志配置,可以使用Profile功能,根据不同的环境配置不同的输出。看下面文件定义:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" scanPeriod="60 seconds" debug="false">

   <property name="LOG_HOME" value="E:\\log" />
   <property name="fileName" value="spring-boot-logback"></property>

   <appender name="consoleLogAppender" class="ch.qos.logback.core.ConsoleAppender">
       <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="fileLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
       <file>${LOG_HOME}/${fileName}.log</file>
       <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
           <fileNamePattern>${LOG_HOME}/${fileName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
           <MaxHistory>365</MaxHistory>
           <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
               <maxFileSize>10MB</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="xin.jerome" level="debug" />
   <logger name="org.springframework" level="debug" additivity="false"></logger>

   <root level="info">
       <appender-ref ref="consoleLogAppender" />
       <appender-ref ref="fileLogAppender" />
   </root>
</configuration>

解析一下这个配置文件,首先根节点<configuration>
:

  • scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。

  • scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。

  • debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

定义属性变量<property/>
:

<!-- 定义日志的根目录 -->
<property name="LOG_HOME" value="E:\\log" />
<!-- 定义日志文件名称 -->
<property name="fileName" value="spring-boot-logback"></property>

格式化日志输出节点<appender>
,其中ch.qos.logback.core.ConsoleAppender
表示控制台的输出,ch.qos.logback.core.rolling.RollingFileAppender
表示已滚动的方式输出到日志文件。

  • <file>
    标签作用是指定日志文件的所在位置。

  • <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    决定 RollingFileAppender
    的行为,涉及文件移动和重命名。

  • <fileNamePattern>
    滚动时产生的文件的存放位置及文件名称。

  • <MaxHistory>
    控制保留的归档文件的最大数量。

  • <maxFileSize>
    控制日志文件的大小,当超过这个大小后开始滚动。

  • <layout>#<pattern>
    日志输出格式:

  1. %d表示日期时间。

  2. %thread表示线程名。

  3. %-5level:级别从左显示5个字符宽度。

  4. %logger{50} 表示logger名字最长50个字符,否则按照句点分割。

  5. %msg:日志消息。

  6. %n是换行符。

日志对象结点<logger>
,主要用于存放日志对象,也可以定义日志类型、级别:

  • name:表示匹配的logger类型前缀,也就是包的前半部分。

  • level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR。

  • additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,

  1. false:表示只用当前logger的appender-ref。

  2. true:表示当前logger的appender-ref和rootLogger的appender-ref都有效

<root>
结点,root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。

在控制台日志输出的时候使用了<springProfile>
结点,可以与Spring Boot
配置的Profile
来结合使用,来控制不同环境的日志输出。

总结

经过我们上面的分析和演示,实现了Spring Boot
默认的日志框架logback
的配置使用。探究了Spring Boot
默认实现日志系统的优先级;以及通过简单的配置文件对Spring Boot
的日志系统进行了简单的改造,以及通过官方推荐的logback-spring.xml
文件,自定义我们的日志系统。

具体的代码可以参考GitHub:spring-boot-demo-logback小节。


文章转载自鹰击太空,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论