Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

2.5. Spring boot with Logging

2.5.1. 配置日誌檔案

一般的日誌需求可以通過配置 application.properties實現。

Spring Boot中 日誌預設是輸出到控制台的,這樣是為了方便開發人員,但是在生產環境中應該輸出到日誌檔案中。

配置如下

  • logging.file.path:指定日誌檔案的路徑
  • logging.file.name:日誌的檔案名(預設為spring.log)
[提示]提示

注意:這兩個屬性不能同時配置,只需要配置一個即可。

[提示]提示

舊版本

logging.file,設置檔案,可以是絶對路徑,也可以是相對路徑。如:logging.file=my.log

logging.path,設置目錄,如果 logging.file 沒有設置,會在該目錄下創建spring.log檔案作為預設日誌檔案。

		
logging.file=target/spring.log
#logging.path=
		
			

如果仍不能滿足可以使用 logback.xml 配置日誌。

		
logging.path=/tmp
logging.config=classpath:logback.xml
		
			

2.5.1.1. 日誌輸出級別

		
幾種常見的日誌級別由低到高分為:TRACE < DEBUG < INFO < WARN < ERROR < FATAL
		
			

顯示所有DEBUG信息

			
logging.level.root=DEBUG			
			
			

僅僅顯示 springframework 調試信息

			
logging.level.org.springframework.web=DEBUG			
			
			

僅僅顯示 cn.netkiller.web.TestController 調試信息

			
private static final Logger log = LoggerFactory.getLogger(TestController.class);

log.debug(message);

logging.level.cn.netkiller.web.TestController=DEBUG			
			

			

2.5.1.2. Spring boot 2.1 以後的版本不打印 Mapped 日誌問題

		
logging.level.org.springframework.web=trace		
		
			

2.5.1.3. 禁止控制台輸出日誌

禁止控制台日誌輸出,同時將日誌寫入日誌檔案.

src/main/resources/application.properties

			
logging.path=/tmp
logging.file=/tmp/spring.log
logging.level.root=INFO
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
			
			

src/main/resources/logback.xml

			
$ cat src/main/resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  <include resource="org/springframework/boot/logging/logback/file-appender.xml" />

  <root level="INFO">
    <appender-ref ref="FILE" />
  </root>
</configuration>
			
			

使用 java -jar project-version-xxx.jar 啟動後控制不會再輸出日誌

2.5.1.4. 定製日誌格式

定製日誌格式有兩個配置

  • logging.pattern.console:控制台的輸出格式
  • logging.pattern.file:日誌檔案的輸出格式

分別是控制台的輸出格式和檔案中的日誌輸出格式

舉例

			
logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n			
			
			

格式說明

			
%d{HH:mm:ss.SSS} 日誌輸出時間
%thread 	輸出日誌的進程名字,這在Web應用以及非同步任務處理中很有用
%-5level 	日誌級別,並且使用5個字元靠左對齊
%logger		日誌輸出者的名字
%msg		日誌消息
%n			平台的換行符
			
			

2.5.2. 打印日誌

日誌的用法,首先開發中我們根據實際的需要打印不同級別的日誌。

			
package cn.netkiller.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {

	private static final Logger log = LoggerFactory.getLogger(TestController.class);

	@RequestMapping("/test/log")
	@ResponseBody
	public String log() {
		String message = "Test";
		log.debug(message);
		log.info(message);
		log.warn(message);
		log.error(message);
		log.trace(message);
		return message;
	}
}
			
		

然後通過application.properties配置那些需要顯示,那些不需要,以及顯示的級別是什麼。

2.5.2.1. lombok

			
		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>			
			
			
			
@Slf4j
class DemoApplicationTests {
  @Test
  public void test(){
    log.debug("輸出DEBUG日誌.......");
  }
}			
			
			

2.5.3. logback 配置詳解

配置檔案名預設是:logback-spring.xml,使用其他檔案名通過下面配置項指定即可。

		
logging.config=classpath:logback.xml		
		
		

2.5.3.1. 標準輸出

			
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<include resource="org/springframework/boot/logging/logback/defaults.xml" />
	<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%date{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} : %msg %n</pattern>
		</encoder>
	</appender>
	<root level="INFO">
		<appender-ref ref="STDOUT" />
		<appender-ref ref="FILE" />
	</root>
</configuration>
			
			

2.5.3.2. 分隔日誌

			
<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>logback</contextName>
    <property name="log.path" value="target" />
    <!--輸出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--輸出到檔案-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/spring.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </root>
</configuration>
			
			

2.5.3.3. 按照檔案尺寸分割日誌

按日期分割檔案

			
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  <include resource="org/springframework/boot/logging/logback/file-appender.xml" />

<appender name="dailyRollingFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <File>logs/spring.log</File>
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!-- daily rollover -->
    <FileNamePattern>spring.%d{yyyy-MM-dd}.log</FileNamePattern>
    <!-- keep 30 days' worth of history -->
    <maxHistory>60</maxHistory>         
  </rollingPolicy>
  <encoder>
    <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg %n</Pattern>
  </encoder>        
</appender>

  <root level="INFO">
    <appender-ref ref="FILE" />
	<appender-ref ref="dailyRollingFileAppender" />	
  </root>
</configuration>
			
			
			

通過級別分割日誌將 info, error, debug 分割到指定檔案中。

			
<configuration scan="true" scanPeriod="10 seconds">
     <!-- 控制台日誌輸出-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d %p (%file:%line\)- %m%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!-- info日誌輸出-->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d %p (%file:%line\)- %m%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <File>${LOG_PATH}/www.netkiller.cn.info.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/www.netkiller.cn.info-%d{yyyyMMdd}.log.%i
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
            </Pattern>
        </layout>
    </appender>
    <!-- debug 日誌輸出-->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d %p (%file:%line\)- %m%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <File>${LOG_PATH}/www.netkiller.cn.debug.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/www.netkiller.cn.debug-%d{yyyyMMdd}.log.%i
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
            </Pattern>
        </layout>
    </appender>

      <!--error 日誌輸出配置 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d %p (%file:%line\)- %m%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <File>${LOG_PATH}/www.netkiller.cn.error.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/www.netkiller.cn.error-%d{yyyyMMdd}.log.%i</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern>
        </layout>
    </appender>

    <root level="DEBUG">
        <!--
        <appender-ref ref="STDOUT" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="ERROR_FILE" />
        <appender-ref ref="DEBUG_FILE" />
        -->
        <appender-ref ref="ERROR_FILE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="DEBUG_FILE" />
    </root>

</configuration>			
			
			

2.5.3.4. 指定Class過濾日誌

			
    <logger name="cn.netkiller.controller"/>
    
    <logger name="cn.netkiller.controller.HomeController" level="WARN" additivity="false">
        <appender-ref ref="console"/>
    </logger>
			
			

2.5.3.5. 日誌寫入 MongoDB

			

			
			

2.5.3.6. configuration 屬性配置

			
scan:當此屬性設置為true時,配置檔案如果發生改變,將會被重新加載,預設值為true。
scanPeriod:設置監測配置檔案是否有修改的時間間隔,如果沒有給出時間單位,預設單位是毫秒。當scan為true時,此屬性生效。預設的時間間隔為1分鐘。
debug:當此屬性設置為true時,將打印出logback內部日誌信息,實時查看logback運行狀態。預設值為false。			
			
			

2.5.3.7. contextName 設置上下文名稱

			

每個logger都關聯到logger上下文,預設上下文名稱為“default”。但可以使用設置成其他名字,用於區分不同應用程序的記錄。設置後可以通過%contextName來打印日誌上下文名稱。
<contextName>logback</contextName>			
			
			

2.5.3.8. property 設置變數

			
用來定義變數值的標籤, 有兩個屬性,name和value;其中name的值是變數的名稱,value的值時變數定義的值。通過定義的值會被插入到logger上下文中。定義變數後,可以使“${}”來使用變數。

<property name="log.path" value="/tmp" />
			
			

2.5.3.9. encoder 日誌格式設置

			
<encoder>表示對日誌進行編碼:

%d{HH: mm:ss.SSS}——日誌輸出時間
%thread——輸出日誌的進程名字,這在Web應用以及非同步任務處理中很有用
%-5level——日誌級別,並且使用5個字元靠左對齊
%logger{36}——日誌輸出者的名字
%msg——日誌消息
%n——平台的換行符			
			
			

2.5.3.10. RollingFileAppender

			
上例中<fileNamePattern>${log.path}/logback.%d{yyyy-MM-dd}.log</fileNamePattern>定義了日誌的切分方式——把每一天的日誌歸檔到一個檔案中,同理,可以使用%d{yyyy-MM-dd_HH-mm}來定義精確到分的日誌切分方式。
<maxHistory>30</maxHistory>表示只保留最近30天的日誌,以防止日誌填滿整個磁碟空間。
<totalSizeCap>1GB</totalSizeCap>用來指定日誌檔案的上限大小,例如設置為1GB的話,那麼到了這個值,就會刪除舊的日誌。