Spring Boot--日誌框架的學習

版本:

  • Spring Boot 2.1.5.RELEASEphp

  • maven 3.2.5html

  • jdk1.8java

1.我選用的日誌框架:

  • 日誌門面(抽象層): SLF4J
  • 日誌實現: Logback

Spring Boot: 底層是Spring框架,Spring框架默認是JCL;react

而Spring Boot選用 SLF4j和Logbackgit


2. SLF4j使用

1) 如何在系統中使用SLF4j

SLF4j的官方手冊github

開發的時候,日誌記錄方法的調用,不用改直接調用日誌的實現類,而是調用日誌抽象層裏的方法;web

  • 導入slf4j的jar和 logback的實現jar
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與其餘日誌框架結合示意圖:spring

2) 遺留問題

雖然我使用的是(slf4j & logback),可是其餘的好比Spring框架用的commons-logging日誌框架, Hibernate用的是jboss-logging日誌框架,等等,太亂了了,因此咱們要 統一日誌記錄,即便別的框架也要和我一塊兒統一使用slf4j進行輸出;apache

官方給出的示意圖:tomcat

邏輯:

  • 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全部依賴關係圖,咱們只看logging相關的:

我用的是2.1.5版本的Spring Boot, 筆者在學習過程當中發現我看的老師視頻裏跟個人版本不同,

這是那位老師的版本:

很明顯跟我不同,不過Spring確定對本身的底層進行了升級;

確切的說不是升級,而是剔除掉了jcl框架的轉換,由於jcl框架最後更新日期是2014年,明顯已通過時

可是基本推理的出來,slf4j的官網圖確實是對SpringBoot1.x版本的示意,可是對個人2.x版本不符, 不過根據個人包名來看,他們的功能是差很少的,都是轉成slf4j;

小總結:

  • 1.SpringBoot底層也是 slf4j+logback的方式j進行日誌記錄;
  • 2.SpringBoot也把其餘日誌都替換成了slf4j;
  • 3.中間替換包;

中間替換包圖示:

4) 若是咱們要引入其餘的框架,必定要把這個框架默認日誌依賴移除掉!

Spring框架默認的日誌框架是: commons-logging;

可是Spring Boot引入spring核心jar包的時候去除了 日誌jar包;

Spring Boot能自動適配全部的日誌,並且底層使用 slf4j+logback的方式記錄日誌,引入其餘框架的時候,只須要把這個框架依賴的日誌排除掉


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,因此只輸出了info 和 比info級別大的日誌;

打開個人yml配置文件:

logging:
 level:
    com.carson: trace
複製代碼

意思是把我 com.carson下的全部包都設置爲 trace 日誌級別

輸出結果:

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>
複製代碼

把上面配置複製一份,放到項目的 resources 裏面,或者自定義配置,命名規範的區別:

  • 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或者properties裏配置一條:

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的包;

  • 而後在 resources 裏 建立一個 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
複製代碼

也就是說,若是像引入其餘日誌框架,只要把之前的框架排除,而後再引入新框架就ok了


我的博客 : aaatao66.github.io/

相關文章
相關標籤/搜索