Java開發統一日志格式
- 1、日志配置
- 2、 日志使用原則
1、日志配置
<?xml version="1.0" encoding="UTF-8"?>
<!--控制台輸出 -->
<appender name="STDOUT-APPENDER" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</Pattern>
</encoder>
</appender>
<!-- 用來儲存輸出所有級别的日志 -->
<appender name="DEFAULT-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.base}/${log.moduleName}-default.log</File>
<!-- 滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/history/default/${log.moduleName}- default-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!-- 檔案輸出日志 (檔案大小政策進行檔案輸出,超過指定大小對檔案備份) -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 日志輸出的檔案的格式 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
</layout>
</appender>
<!-- 隻用儲存輸出ERROR級别的日志 -->
<appender name="ERROR-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.base}/${log.moduleName}-error.log</File>
<!-- 滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/history/error/${log.moduleName}- error-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
</layout>
<!-- 下面為配置隻輸出error級别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 隻用儲存輸出WARN級别的日志 -->
<appender name="WARN-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.base}/${log.moduleName}-warn.log</File>
<!-- 滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/history/warn/${log.moduleName}-warn-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
</layout>
<!-- 下面為配置隻輸出warn級别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 隻用儲存輸出DEBUG級别的日志 -->
<appender name="DEBUG-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.base}/${log.moduleName}-debug.log</File>
<!-- 滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/history/debug/${log.moduleName}- debug-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
</layout>
<!-- 下面為配置隻輸出debug級别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 隻用儲存輸出INFO級别的日志 -->
<appender name="INFO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.base}/${log.moduleName}-info.log</File>
<!-- 滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/history/info/${log.moduleName}-info-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
</layout>
<!-- 下面為配置隻輸出info級别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 隻用儲存輸出TRACE級别的日志 -->
<appender name="TRACE-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.base}/${log.moduleName}-trace.log</File>
<!-- 滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/history/trace/${log.moduleName}- trace-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %-5p - [%c]:%L.%method:%L - %msg%n</pattern>
</layout>
<!-- 下面為配置隻輸出trace級别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>TRACE</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 不丢失日志.預設的,如果隊列的80%已滿,則會丢棄TRACT、DEBUG、INFO級别的日志 -->
<!-- 更改預設的隊列的深度,該值會影響性能.預設值為256 -->
<!-- 添加附加的appender,最多隻能添加一個 -->
<appender name="ASYNC-DEFAULT-APPENDER" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="DEFAULT-APPENDER" />
</appender>
<!-- 為某個包下的所有類的指定Appender 這裡也可以指定類名稱例如:com.xinniu -->
<logger name="com.xinniu" additivity="false">
<level value="${log.other.level}" />
<appender-ref ref="STDOUT-APPENDER" />
<appender-ref ref="ASYNC-DEFAULT-APPENDER" />
<appender-ref ref="ERROR-APPENDER" />
<appender-ref ref="WARN-APPENDER" />
${log.appender.xniniu}
<appender-ref ref="DEFAULT-APPENDER" />
</logger>
<!-- root将級别為${log.root.level}及大于${log.root.level}的日志資訊交給已經配置好的名為“Console”的appender處理,“Console”appender将資訊列印到Console,其它同理 -->
<root level="${log.root.level}">
<appender-ref ref="STDOUT-APPENDER" />
<appender-ref ref="ASYNC-DEFAULT-APPENDER" />
<appender-ref ref="ERROR-APPENDER" />
<appender-ref ref="WARN-APPENDER" />
${log.appender.root}
<appender-ref ref="DEFAULT-APPENDER" />
</root>
PS:此配置檔案除了會按照日志級别分别列印到${log.moduleName}-error.log、${log.moduleName}-info.log等日志檔案中,同時為了友善線下環境控制台檢視日志,定位問題,該配置也會在控制台列印一份日志,建議線上環境關閉掉控制台日志。
2、 日志使用原則
1、日志列印統一使用logback
2、開發環境、測試環境和灰階環境日志級别可以根據需要配置成info或debug級别,線上環境需要配置成info級别。
3、将不同級别的日志分别列印到不同的日志檔案中 l o g . m o d u l e N a m e − e r r o r . l o g 、 {log.moduleName}-error.log、 log.moduleName−error.log、{log.moduleName}-warn.log、 l o g . m o d u l e N a m e − i n f o . l o g 、 {log.moduleName}-info.log、 log.moduleName−info.log、{log.moduleName}-debug.log等。
4、本系統對外的接口入參、出參必須列印出來,日志級别為info。
5、本系統中調用本系統外接口時必須列印入參、出參,日志級别為info。
6、系統中關鍵邏輯、容易出錯的邏輯處需要列印日志,友善開發和線上環境排查問題,日志級别為info。
7、所有try…catch的地方都需要列印錯誤日志。
8、錯誤日志列印時一定要把堆棧列印出來(沒有堆棧時可不列印,另外自定義的異常不要列印堆棧資訊),友善排查問題時定位原因。例如LOGGER.error(“服務端接口: 根據合同ID擷取交易流水清單getListByContractId,params:{} 異常為:”, contractId, e);
9、日志列印時要将敏感字段脫敏或加密。
10、除錯誤日志以外(錯誤日志請參考第7、8條),其他日志列印用花括号{}占位符,不要用加号+的形式拼接字元串。例如LOGGER.info(“服務端接口: 根據合同ID擷取交易流水清單getListByContractId,params:{}”, contractId);
11、不要使用e.printStackTrace();
12、除測試代碼外嚴禁使用System.out.println()、System.gc()