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>

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