SpringBoot 日志配置


常見的框架日志有:log4j,log4j2,logback,common-logging(JCL),java-util-logging(JUL)和slf4j等。

而日志框架主要分兩類:

  • 日志門面(抽象)如:jboss-logging,slf4j,JCL
  • 日志實現(實現)如:log4j,log4j2,logback,JUL

對於日志實現,JUL實現簡陋,很多地方被開發者吐槽,所以排除;log4j和logback是同一個作者開發的,且logback是log4j的升級版,比log4j會更好點,排除log4j;log4j2不是log4j的升級版,因為太過於優秀,部分框架對其的支持有限,所以排除。

所以日志實現選中logback。

對於日志門面,jboss-logging很久未更新,而slf4j的作者就是log4j和logback的作者,所以選用slf4j和logback會比較合得來....

所以日志門面選用slf4j。並且在springboot中也是使用的 slf4j + logback。

簡單使用

首先導入slf4j的jar包和logback的jar包

在開發的時候,日志記錄方法的調用不應該直接調用日志的實現類,而是調用日志抽象層里面的方法。

參考官方文檔:https://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

在系統中,自己使用了slf4j+logback,但是Spring默認的是commons-logging;如果集成Hibernate,他又自帶了jboss-logging;如果集成mybatis,他又有自己的日志系統。

想統一日志框架,都使用slf4j輸出日志,可以參考slf4j官網 https://www.slf4j.org/legacy.html

legacy

slf4j提供了解決方案:

  1. 將系統中的其他日志框架排除出去(刪除其他日志框架的jar包,如:commons-logging日志的jar包等);

  2. 然后使用中間包來替代原有的日志框架(如上圖的jcl-over-slf4j.jar replaces commons-logging.jar,log4j-over-slf4j.jar replaces log4j.jar等);

  3. 導入slf4j其他日志包的實現;

    那些中間包實際上提供了原有包的功能,但是也對slf4j進行了實現。就像log4j-to-slf4j.jar下面的路徑還是和log4j一樣,但是里面的日志記錄的功能使用的是slf4j:

    1566057101545

Spring Boot的日志關系

新建一個springboot項目,然后打開pom文件,查看依賴(右鍵>Diagrams>Show...)

看到SpringBoot依賴spring-boot-starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.1.7.RELEASE</version>
    <scope>compile</scope>
</dependency>

而spring-boot-starter依賴spring-boot-starter-logging,所以springboot使用它來做日志功能。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
    <version>2.1.7.RELEASE</version>
    <scope>compile</scope>
</dependency>

看一下spring-boot-starter-logging:

所以springboot底層是使用slf4j+logback的方式進行日志記錄的,並把其他日志替換成了slf4j;

使用和配置

  1. 修改日志級別
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 SpringBoot03LoggingApplicationTests {
    Logger logger = LoggerFactory.getLogger(SpringBoot03LoggingApplicationTests.class);
    @Test
    public void contextLoads() {
        //日記級別:
        //從低到高:trace<debug<info<warn<error
        //可以調整輸出的日志級別;日志就只在這個級別和之后的高級別生效
        logger.trace("這是trace日志");
        logger.debug("這是debug日志");  //調試日志
        //springboot默認的日志級別是info,所以運行時只會打印info級別和高於info級別的日志信息
        logger.info("這是info日志");  //
        logger.warn("這是warn日志");  //警告日志
        logger.error("這是error日志"); //錯誤日志
    }
}

所以打印是:

但是可以通過properties等配置文件修改日志級別:

logging.level.com.wangd = trace

修改指定位置文件的日志級別后打印如下:

  1. 生成日志文件

    指定logging.file

logging.level.com.wangd = trace

# 不指定路徑和文件的情況下,只在控制台打印日志信息
# 若指定了logging.file,而無論是否指定logging.path,都只在指定文件中保存日志信息,而不會在路徑中保存日志
# 對於logging.path,若指定了目錄,則會在這個目錄中自動生成spring.log保存日志信息
#logging.path=/spring/log
logging.file=spring.log

指定logging.path=/spring/log

logging.level.com.wangd = trace

# 不指定路徑和文件的情況下,只在控制台打印日志信息
# 若指定了logging.file,而無論是否指定logging.path,都只在指定文件中保存日志信息,而不會在路徑中保存日志
# 對於logging.path,若指定了目錄,則會在當前磁盤的這個目錄中自動生成spring.log保存日志信息
logging.path=/spring/log
#logging.file=spring.log

  1. 修改日志輸出格式

    # 日志輸出格式:
    # %d:日期時間
    # %thread:線程名
    # %-5level:級別從左顯示5個字符寬度
    # %logger{50}:表示logger名字最長50個字符,否則按照句點切割
    # %msg:日志消息
    # %n:換行符
    
    # 在控制台輸出日志的格式
    logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-2level %logger{5} - %msg%n
    # 在日志文件中輸出日志的格式
    logging.pattern.file=%d{yyyy-MM-dd} === [%thread] %-5level %logger{50} - %msg%n
    
  2. 使用@Slf4j注解

    在使用類名的時候,每個類都需要自己編寫

    Logger mLogger = LoggerFactory.getLogger(XXX.class);
    

    會很不方便,所以可以通過一個注解(@Slf4j)來幫我們實現,該注解就可以幫我們自動創建一個 log對象。

    但是 如果使用 @Slf4j 注解 需要兩點,

    1. 安裝lombok插件,參考idea安裝插件

    2. 添加 lombok的依賴

    <!--添加lombok依賴-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    

    就可以使用@Slf4j注解了。

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @Slf4j
    public class SpringBoot03LoggingApplicationTests {
        @Test
        public void contextLoads() {
            log.info("這是info日志");  //
            log.warn("這是warn日志");  //警告日志
            log.error("這是error日志"); //錯誤日志
        }
    }  
    
  3. 指定日志配置文件

  • logback.xml可以被日志框架直接識別;

  • logback-spring.xml無法被日志框架識別,但是可以由springboot識別,可以使用springboot的高級Profile功能。

    <!-- 如在logback-spring.xml中加入-->
    <springProfile name="dev">
     	 <!-- 可以指定某段配置只在某個環境下生效-->
     	 <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level [%thread] [%logger{100}.%method:%line] - %msg%n</pattern>
    </springProfile>,
    
    <!--然后修改properties配置文件的profile為dev-->
    spring.profiles.active=dev
    就可以在啟動環境為dev時,日志打印的格式為對應配置的格式
    

所以logback[-spring].xml,格式需要自己查詢。

另外logback.xml文件中配置了springProfile的話,運行會報錯。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <springProfile name="dev">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%d -- %msg%n</pattern>
            </layout>
        </springProfile>
        <springProfile name="test">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%d -----== %msg%n</pattern>
            </layout>
        </springProfile>
    </appender>

    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--要攔截的日志級別-->
            <level>ERROR</level>
            <!--如果匹配,則禁止-->
            <onMatch>DENY</onMatch>
            <!--如果不匹配,則允許記錄-->
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <pattern>%d -- %msg%n</pattern>
        </encoder>
        <!--滾動策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路徑-->
            <fileNamePattern>d:/info-%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--添加 范圍 過濾-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>%d -- %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>d:/error-%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog" />
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>
</configuration>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM