Skip to content

SpringBoot开发中如何选用日志框架呢? 出于性能等原因,Logback 目前是springboot应用日志的标配; 当然有时候在生产环境中也会考虑和三方中间件采用统一处理方式。@anarkh

  • SpringBoot入门 - 添加Logback日志
  • 日志框架的基础
  • 关于日志框架(日志门面)
  • 配置时考虑点
  • 实现范例
  • 综合范例
  • 在配置前可以参考如下文章
  • 參考文档

日志框架的基础

在学习这块时需要一些日志框架的发展和基础,同时了解日志配置时考虑的因素。

关于日志框架(日志门面)

Java日志库是最能体现Java库在进化中的渊源关系的,在理解时重点理解日志框架本身日志门面 ,以及比较好的实践等。要关注其历史渊源和设计(比如桥接),而具体在使用时查询接口即可, 否则会陷入JUL(Java Util Log), JCL(Commons Logging), Log4j, SLF4J, Logback,Log4j2傻傻分不清楚的境地。

关于日志框架(日志门面)这篇文章有过详细的介绍。

常用开发库 - 日志类库详解

配置时考虑点

在配置日志时需要考虑哪些因素?

  • 支持日志路径,日志level等配置
  • 日志控制配置通过application.yml下发
  • 按天生成日志,当天的日志>50MB回滚
  • 最多保存10天日志
  • 生成的日志中Pattern自定义
  • Pattern中添加用户自定义的MDC字段,比如用户信息(当前日志是由哪个用户的请求产生),request信息。此种方式可以通过AOP切面控制,在MDC中添加requestID,在spring-logback.xml中配置Pattern。
  • 根据不同的运行环境设置Profile - dev,test,product
  • 对控制台,Err和全量日志分别配置
  • 对第三方包路径日志控制

实现范例

如下两个例子基本包含了上述的考虑点:

综合范例

  • application.yml
json
logging:
  level:
    root: debug
  path: C:/data/logs/springboot-logback-demo
server:
  port: 8080
spring:
  application:
    name: springboot-logback-demo
debug: false
  • Spring-logback.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    
    <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="/data/logs/springboot-logback-demo"/>

    
    <springProperty scope="context" name="LOG_ROOT_LEVEL" source="logging.level.root" defaultValue="DEBUG"/>

    
    <springProperty scope="context" name="STDOUT" source="log.stdout" defaultValue="STDOUT"/>

    
    <property name="LOG_PREFIX" value="spring-boot-logback" />

    
    <property name="LOG_CHARSET" value="UTF-8" />

    
    <property name="LOG_DIR" value="${LOG_HOME}/%d{yyyyMMdd}" />

    
    <property name="LOG_MSG" value="- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | --> %msg|%n "/>

    
    <property name="MAX_FILE_SIZE" value="50MB" />

    
    <property name="MAX_HISTORY" value="10"/>

    
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_MSG}</pattern>
        </layout>
    </appender>

    
    <appender name="0" class="ch.qos.logback.core.rolling.RollingFileAppender">
    </appender>

    
    <appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <File>${LOG_HOME}/all_${LOG_PREFIX}.log</File>

        
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            
            <FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}%i.log</FileNamePattern>

            
            <MaxHistory>${MAX_HISTORY}</MaxHistory>

            
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>

        </rollingPolicy>

        
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_MSG}</pattern>
        </layout>
    </appender>

    
    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <OnMismatch>DENY</OnMismatch>
            <OnMatch>ACCEPT</OnMatch>
        </filter>
        
        <File>${LOG_HOME}/err_${LOG_PREFIX}.log</File>

        
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            
            <FileNamePattern>${LOG_DIR}/err_${LOG_PREFIX}%i.log</FileNamePattern>

            
            <MaxHistory>${MAX_HISTORY}</MaxHistory>

            
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>

        
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_MSG}</Pattern>
        </layout>
    </appender>

    
    <logger name="org.springframework"     level="ERROR" />
    <logger name="org.apache.commons"      level="ERROR" />
    <logger name="org.apache.zookeeper"    level="ERROR"  />
    <logger name="com.alibaba.dubbo.monitor" level="ERROR"/>
    <logger name="com.alibaba.dubbo.remoting" level="ERROR" />

    
    <root level="${LOG_ROOT_LEVEL}">

        
        <appender-ref ref="${STDOUT}"/>

        
        <appender-ref ref="FILE_ALL"/>

        
        <appender-ref ref="FILE_ERROR"/>
    </root>

</configuration>

Profile 相关的配置可以参考:

xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    
     
     <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">   
    	<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">   
      		<fileNamePattern>logs/springboot-logback-demo.%d{yyyy-MM-dd}.log</fileNamePattern>   
      		<maxHistory>30</maxHistory>  
    	</rollingPolicy>   
    	<encoder>   
      		<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>   
    	</encoder>  
  	</appender> 
   
    
	<logger name="org.springframework.web" level="INFO"/>
		<root level="INFO">
		<appender-ref ref="FILE" />
	</root>

    
    <springProfile name="test,prod">
        <logger name="org.springframework.web" level="INFO"/>
        <logger name="com.anarkh.springboot" level="INFO"/>
        <root level="INFO">
        	<appender-ref ref="FILE" />
        </root>
    </springProfile>
  	 
</configuration>

在配置前可以参考如下文章

https://www.cnblogs.com/warking/p/5710303.html

參考文档

  • Logback官网

https://logback.qos.ch/manual/layouts.html#conversionWord

  • Logback官网 文档

https://logback.qos.ch/manual/index.html

  • Logback中Encoder Pattern
xml
<encoder>
	<pattern>%d{HH:mm:ss} [%thread][%X{traceId}] %-5level %logger{36} - %msg%n</pattern>
</encoder>

https://logback.qos.ch/manual/layouts.html#conversionWord