spring boot集成日志(slf4j+logback)以及其他日志替换spring boot默认log框架

springboot日志集成:

日志实现: logback、log4j、log4j2、 JUL(java.util.longging)

日志抽象层:JCL(jakarta Commons Logging) 、 SLF4J(Simple Logging Facade for java) 、jboss-logging

也就是 抽象层选一个,实现类选一个就成了一个日志框架。

JCL(jakarta Commons Logging): 最后更新 2014年,过时。

jboss-logging:应用场景太少。

SLF4J、Log4J、Logback:出自同一个人编写,就在这里面选了。

Log4j没有Logback 的功能多。

Log4J2:apche小组重新研发的 ,有兼容性问题。

所以我们选择:

日志门面(抽象层):SLF4J

日志实现:LogBack

调用方式:

官方说明:http://www.slf4j.org/manual.html

代码调用示例:

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+Logback原理:

application(应用) 调用SLF4J(抽象层),再调用LogBack实现。

SLF4J+Log4J原理:

application(应用) 调用SLF4J(抽象层),不能直接调用Log4j实现类(原因:Log4j最初根本没想到有slf4j抽象层,所以不兼容),需要加入适配器Adaptation layer,

这个适配器相当于SLF4J调用了他的方法,然后更具他的方法去调用log4j的实现类。

**SLF4J+JUL(java.Uilt.logging)原理: **

application(应用) 调用SLF4J(抽象层),不能直接调用JUL实现类(原因:JUL是临时加入抢占市场的,并没有考虑兼容slf4j抽象层,所以不兼容),和调用log4j一样,需要加入适配器Adaptation layer,适配器再调用JUL的实现类。

SLF4J本身就有简单的实现类:

包名:slf4j-api.jar

加入slf4j-simple.jar: 只有一些简单的实现类,可以直接使用。

加入slf4j-nop.jar: 没有什么实现,但是也可以使用,直接输出到空的文件。

img

每一个日志的实现框架都有自己的配置文件,使用哪个日志的实现类就配置哪个实现类的配置文件。

比如:我们用了slf4j,实现类是logback,所以我们要配置log back的文件。

遗留问题:日志统一

比如: 系统太大了,使用了多个框架,spring自带的Commons logging、hibernate的jboss-logging、mybatis、XXX 等一系列日志。

太杂,而我们现在想用slf4j+logback来作为统一日志。

方法:

看官方说明(http://www.slf4j.org/legacy.html),给出了张图:

在这里插入图片描述

这个图第一部分的意思就是:

原理:

先去掉系统自带的框架Commons-logging,使用中间包(作用:替换原有的日志jar包)jcl-over-slf4j.jar来替换Commons-logging,jcl-over-slf4j再调用SLF4J,SLF4J再调用Logback实现类。

用idea工具在pom.xml右击鼠标,选择Diagrams–>ShowDependencies…可以清楚的看到依赖结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uOo8REoE-1571111198385)(C:\Users\1\AppData\Roaming\Typora\typora-user-images\1571039872501.png)]

springboot与日志的底层关系:

springboot-logging官方手册说明:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html

导入maven:

 	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>

底层依赖关系图:
在这里插入图片描述

spring boot 底层也用的slf4j+logback的方式进行日志记录。

spring boot 把底层的日志都替换成了slf4j

中间包:比如jcl-over-slf4j.jar 里面有org.Commons-logging的包,但它的实现却是slf4j的初始化,也就是调用的还是slf4j。

如果spring boot要引入其他框架比如说Log4J,那么一定要先排除原有的默认日志依赖logback,

spring框架用的是Commons-logging;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QA3PMiLg-1571111198387)(C:\Users\1\AppData\Roaming\Typora\typora-user-images\1571041405599.png)]

2.0版本以前的springboot底层也是这样做的,但是在spring boot 2.0就没有排除了,应该说是没有依赖Commons-logging了能找到的也就只有log4j-to-slf4j、 jul-to-slf4以及logback-classic的jar.

但是统一方法还是一样的,如果要更换其他日志,还是得先排除。在添加自己要集成得日志jar.

springboot默认日志配置:

//logger 为日志记录器  
private static  final Logger log=LoggerFactory.getLogger(Test.class);

用法:

//trace  追踪
log.trace("这是一个trace日志记录");
log.debug("这是一个Debug的测试日志记录");
log.info("这是一个info日志记录");
log.warn("这是一个warn日志记录");
log.error("这是一个error日志记录");

日志级别:

由低到高分别为:trace–>debug–>info–>warn–>error

作用:可以调整日志级别的输出,比如说项目不想看到Debug和info这一类日志信息,那么我们就写成warn,那么就只会输出warn以及warn以上级别的信息。

spring boot 默认日志输出级别为Info,也就是控制台只输出info及info以上的信息。

指定级别:

logging:
	 level.logdemo:   //logdemo 为项目的包名,该包下的所有日志都输出trace级别及以上级别的信息,没有指定的包输出级别的为springboot默认级别Info
		root: trace
		

Logging properties

logging.file logging.path Example 描述(Description
(没有) (没有) 仅控制台记录。
特定档案 (没有) my.log 写入指定的日志文件。名称可以是确切位置,也可以是相对于当前目录的位置。
(没有) 具体目录 /var/log 写入spring.log指定的目录。名称可以是确切位置,也可以是相对于当前目录的位置

日志文件达到10 MB时会旋转,并且与控制台输出一样,默认情况下会记录ERROR-level,WARN-level和INFO-level消息。可以使用该logging.file.max-size属性更改大小限制。除非logging.file.max-history已设置属性,否则以前旋转的文件将无限期存档。

指定日志文件存放路径:

logging.file:

logging:
	 level.logdemo:  
		root: trace
	 file: E:\\IDEA_project\\logdemo\\logs\\info.log

logging.path:

logging:
	 level.logdemo:  
		root: trace
	 path:/spring/log  
	 //这里"/"是Linux下的绝对路径, 表示在当前磁盘路径下创建spring文件夹 ,在spring文件夹下创建log文件夹,默认文件的是spring.log

logging.file和logging.path:二者不能同时使用,如若同时使用,则只有logging.file生效

logging:
    level.logdemo:
      root: INFO
#      org:
#        springframework:
#          hibernate: ERROR
#          web: DEBUG
#logging.file和logging.path二者不能同时使用,如若同时使用,则只有logging.file生效
    file: E:\\IDEA_project\\logdemo\\logs\\info.log
	pattern:
	 #在控制台输出的格式
      console:
      #指定文件中的输出格式:
      file:
	



日志输出格式:

%d: 日期时间

%thread或%t: 线程名

%-5level或%5p: 级别从左显示5个字符宽

%logger{50}: logger名字最长50个字符,否在按照句点分割

%msg : 日志消息

%n: 换行

自定义日志配置:

给类路径下放上每个日志框架自己的配置文件,springboot就不会启动默认的配置了。

Logging System Customization
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

logback.xml: 直接就被日志框架识别

logback-spring.xml: 日志框架不自动识别并加载,spring boot2.0好像可以自动识别并加载,

注意:由于xml文件配置的加载要优先于application.yml,logback-spring.xml会找不到配置的文件存放地址,所以不能在yml里面配置日志存放的位置。

Logback扩展:

在使用logback-spring.xml作为配置文件,可以使用log back的高级功能。

由于标准logback.xml配置文件加载太早,因此不能在其中使用扩展名。您需要使用logback-spring.xml或定义一个logging.config属性。

ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

使用logback-spring.xml作为配置文件则我们可以使用高级功能:springProfile 这个配置

<springProfile name="staging">
	<!-- configuration to be enabled when the "staging" profile is active -->
    <!-当“staging(临时或者测试环境)”配置文件处于活动状态时要启用的配置-> 
</springProfile>
    
<springProfile  name = " dev | staging" > 
	<!-要在激活“dev(开发环境)”或“staging”配置文件时启用配置-> 
</ springProfile>

<springProfile  name = "!production" > 
	<!-当“poduction(生产环境)”配置文件未激活时要启用的配置-> 
</ springProfile>

当然先要设置开发环境:

server:
  port: 8080
  servlet:
      context-path: /logdemo
#logging:
  # pattern:
  #        level.com: Info
   #       console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){blue} %clr(%-5level) %clr([%t]){magenta}     %clr(----){faint}  %clr(%-40.40logger{39}){cyan} %clr(:){blue} %m%n"
   #       file:  "%d{yyyy-MM-dd HH:mm:ss.SSS}{faint} %-5level [%t]    ----  %-40.40logger{39} : %m%n"
  # file: E:\\IDEA_project\\logdemo\\logs\\info.log
spring:
  profiles.:
   active: dev    #设置为开发环境dev,或者 是生产环境production

个人自定义完整配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="E:\\IDEA_project\\logdemo\\logs\\" />
    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){blue} %clr(%-5level) %clr([%t]){magenta}     %clr(----){faint}  %clr(%-40.40logger{39}){cyan} %clr(:){blue} %m%n</pattern>
        </encoder>
    </appender>

    <appender name="stdout" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}Info-%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}{faint} %-5level [%t]    ----  %-40.40logger{39} : %m%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
  <!--  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
            <maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
        </rollingPolicy>
    </appender>-->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="stdout" />
        <!--<appender-ref ref="FILE" />-->
    </root>
</configuration>

分级日志文件存放配置:

<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="E:\\IDEA_project\\logdemo\\logs\\" />
 <springProfile  name = "!dev">
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%t]     ----  %-40.40logger{39}: %m%n</pattern>
            </encoder>
        </appender>
    </springProfile>
   <springProfile  name = "dev" >
        <!--要在激活“dev(开发环境)”或“staging”配置文件时启用配置-->
        <!-- 彩色日志 -->
        <!-- 彩色日志依赖的渲染类 -->
        <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
        <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
        <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){blue} %clr(%-5level) %clr([%t]){magenta}     %clr(----){faint}  %clr(%-40.40logger{39}){cyan} %clr(:){blue} %m%n</pattern>
            </encoder>
        </appender>
    </springProfile>
    <!-- Console 输出设置 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 不用彩色控制台输出 -->
    <!-- 控制台输出 -->
    <!--<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">-->
    <!--<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">-->
    <!--<!–格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符–>-->
    <!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>-->
    <!--</encoder>-->
    <!--</appender>-->
    <!-- 按照每天生成日志文件 -->
    <!--info-->
    <appender name="DAYINFO"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/Info-%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!--error appender-->
    <appender name="DAYERROR"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/Error-%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <!--这里设置日志级别为error-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!--warning appender-->
    <appender name="DAYWARN"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/Warning-%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <!--这里设置日志级别为error-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="DAYINFO" />
        <appender-ref ref="DAYERROR" />
        <appender-ref ref="DAYWARN" />
    </root>
</configuration>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章