一、介紹
1.1 Logback
Logback是由log4j創始人設計的另一個開源日志組件,它分為下面下個模塊:
- logback-core:其它兩個模塊的基礎模塊
- logback-classic:它是log4j的一個改良版本,同時它完整實現了slf4j API使你可以很方便地更換成其它日志系統如log4j或JDK14 Logging
- logback-access:訪問模塊與Servlet容器集成提供通過Http來訪問日志的功能
1.2 日志級別
包括:
TRACE
、DEBUG
、INFO
、WARN
和ERROR
。
1.2.1 TRACE
特別詳細的系統運行完成信息,業務代碼中,不要使用。(除非有特殊用意,否則請使用DEBUG
級別替代)
1.2.2 DEBUG
- 可以填寫所有的想知道的相關信息(但不代表可以隨便寫,
debug
信息要有意義,最好有相關參數); - 生產環境需要關閉
DEBUG
信息 - 如果在生產情況下需要開啟DEBUG,需要使用開關進行管理,不能一直開啟。
1.2.3 INFO
-
系統運行信息
- Service方法中對於系統/業務狀態的變更;
- 主要邏輯中的分步驟。
-
外部接口部分
- 客戶端請求參數(REST/WS);
- 調用第三方時的調用參數和調用結果。
-
說明
- 並不是所有的service都進行出入口打點記錄,單一、簡單service是沒有意義的;
- 對於復雜的業務邏輯,需要進行日志打點,以及埋點記錄,比如電商系統中的下訂單邏輯,以及OrderAction操作(業務狀態變更);
- 對於整個系統的提供出的接口(REST/WS),使用
INFO
記錄入參; - 如果所有的service為SOA架構,那么可以看成是一個外部接口提供方,那么必須記錄入參;
- 調用其他第三方服務時,所有的出參和入參是必須要記錄的(因為你很難追溯第三方模塊發生的問題)。
1.2.4 WARN
-
不應該出現但是不影響程序、當前請求正常運行的異常情況:
- 有容錯機制的時候出現的錯誤情況;
- 找不到配置文件,但是系統能自動創建配置文件;
-
即將接近臨界值的時候,例如:緩存池占用達到警告線;
-
業務異常的記錄,比如:當接口拋出業務異常時,應該記錄此異常。
1.2.5 ERROR
影響到程序正常運行、當前請求正常運行的異常情況:
- 打開配置文件失敗;
- 所有第三方對接的異常(包括第三方返回錯誤碼);
- 所有影響功能使用的異常,包括:
SQLException
和除了業務異常之外的所有異常(RuntimeException
和Exception
)。
不應該出現的情況:
如果進行了拋出異常操作,請不要記錄ERROR
日志,由最終處理方進行處理:
反例(不要這么做):
try{
....
}catch(Exception ex){
String errorMessage=String.format("Error while reading information of user [%s]",userName);
logger.error(errorMessage,ex);
throw new UserServiceException(errorMessage,ex);
}
1.3 SpringBoot 中 logback
SpringBoot
工程自帶logback
和slf4j
的依賴,所以重點放在編寫配置文件上,需要引入什么依賴,日志依賴沖突統統都不需要我們管了;logback
框架會默認加載classpath
下命名為logback-spring
或logback
的配置文件。- 將所有日志都存儲在一個文件中文件大小也隨着應用的運行越來越大並且不好排查問題,正確的做法應該是將
ERROR
日志和其他日志分開,並且不同級別的日志根據時間段進行記錄存儲。
二、logback 配置
2.1 配置文件logback-spring.xml
示例
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- 屬性文件:在配置文件中找到對應的配置項 -->
<springProperty scope="context" name="logPath" source="logging.path"/>
<!-- 輸出到控制台 -->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
</appender>
<!-- 獲取比info級別高(包括info級別)但除error級別的日志 -->
<appender name="INFO-LOG" 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{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</encoder>
<!-- 指定收集策略:滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 指定生成日志保存地址 -->
<fileNamePattern>${logPath}/info.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<appender name="ERROR-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 指定過濾策略 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<!-- 指定日志輸出格式 -->
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</encoder>
<!-- 指定收集策略:滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--指定生成日志保存地址 -->
<fileNamePattern>${logPath}/error.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!-- 異步輸出 -->
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丟失日志.默認的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默認的隊列的深度,該值會影響性能.默認值為256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一個 -->
<appender-ref ref="INFO-LOG"/>
</appender>
<appender name="ASYNC-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丟失日志.默認的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默認的隊列的深度,該值會影響性能.默認值為256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一個 -->
<appender-ref ref="ERROR-LOG"/>
</appender>
<!-- 指定最基礎的日志輸出級別 -->
<root level="info">
<appender-ref ref="CONSOLE-LOG" />
<appender-ref ref="INFO-LOG" />
<appender-ref ref="ERROR-LOG" />
</root>
</configuration>
項目配置文件中配置日志輸出地址
logging:
path: ./logs
2.2 標簽說明
-
<root>
標簽:指定最基礎的日志輸出級別;<appender-ref>
標簽,添加append
-
<appender>
標簽:指定日志的收集策略name
屬性指定appender
命名class
屬性指定輸出策略,通常有兩種,控制台輸出和文件輸出,文件輸出就是將日志進行一個持久化。ConsoleAppender
將日志輸出到控制台。
-
<filter>
標簽:指定過濾策略<level>
:指定過濾的類型。
-
<encoder>
標簽:使用該標簽下的<pattern>
標簽指定日志輸出格式。 -
<rollingPolicy>
標簽:指定收集策略,比如基於時間進行收集-
標簽指定生成日志保存地址,實現了按天分類以及日志的目標了。
-