Java開發(fā) 日志規(guī)約

2021-03-23 11:15 更新

\1. 【強制】應用中不可直接使用日志系統(tǒng)(Log4j、Logback)中的 API,而應依賴使用日志框架(SLF4J、JCL--Jakarta Commons Logging)中的 API,使用門面模式的日志框架,有利于維護和各個類的日志處理方式統(tǒng)一。

  • 說明:日志框架(SLF4J、JCL--Jakarta Commons Logging)的使用方式(推薦使用 SLF4J)使用 SLF4J:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Test.class);

使用 JCL:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private static final Log log = LogFactory.getLog(Test.class);

\2. 【強制】所有日志文件至少保存 15 天,因為有些異常具備以“周”為頻次發(fā)生的特點。對于

當天日志,以“應用名.log”來保存,保存在/home/admin/應用名/logs/目錄下,過往日志格式為: {logname}.log.{保存日期},日期格式:yyyy-MM-dd

  • 正例:以 aap 應用為例,日志保存在/home/admin/aapserver/logs/aap.log,歷史日志名稱為aap.log.2021-03-23

\3. 【強制】根據(jù)國家法律,網(wǎng)絡(luò)運行狀態(tài)、網(wǎng)絡(luò)安全事件、個人敏感信息操作等相關(guān)記錄,留存的日志不少于六個月,并且進行網(wǎng)絡(luò)多機備份。

\4. 【強制】應用中的擴展日志(如打點、臨時監(jiān)控、訪問日志等)命名方式:

appName_logType_logName.log。logType:日志類型,如 stats/monitor/access等;logName:日志描述。這種命名的好處:通過文件名就可知道日志文件屬于什么應用,什么類型,什么目的,也有利于歸類查找。

  • 說明:推薦對日志進行分類,如將錯誤日志和業(yè)務(wù)日志分開存放,便于開發(fā)人員查看,也便于通過日志對系統(tǒng)進行及時監(jiān)控。

  • 正例:mppserver 應用中單獨監(jiān)控時區(qū)轉(zhuǎn)換異常,如:

mppserver_monitor_timeZoneConvert.log

\5. 【強制】在日志輸出時,字符串變量之間的拼接使用占位符的方式。

說明:因為 String 字符串的拼接會使用 StringBuilderappend()方式,有一定的性能損耗。使用占位符僅是替換動作,可以有效提升性能。

  • 正例:logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);

\6. 【強制】對于 trace/debug/info 級別的日志輸出,必須進行日志級別的開關(guān)判斷。

  • 說明:雖然在 debug(參數(shù))的方法體內(nèi)第一行代碼 isDisabled(Level.DEBUG_INT)為真時(Slf4j 的常見實現(xiàn)Log4j 和 Logback),就直接 return,但是參數(shù)可能會進行字符串拼接運算。此外,如果 debug(getName())這種參數(shù)內(nèi)有 getName() 方法調(diào)用,無謂浪費方法調(diào)用的開銷。

  • 正例:

// 如果判斷為真,那么可以輸出 trace 和 debug 級別的日志
if (logger.isDebugEnabled()) {
    logger.debug("Current ID is: {} and name is: {}", id, getName());
}

\7. 【強制】避免重復打印日志,浪費磁盤空間,務(wù)必在日志配置文件中設(shè)置 additivity=false。

  • 正例:<logger name="com.taobao.dubbo.config" additivity="false">

\8. 【強制】生產(chǎn)環(huán)境禁止直接使用 System.outSystem.err 輸出日志或使用e.printStackTrace() 打印異常堆棧。

  • 說明:標準日志輸出與標準錯誤輸出文件每次 Jboss 重啟時才滾動,如果大量輸出送往這兩個文件,容易造成文件大小超過操作系統(tǒng)大小限制。

\9. 【強制】異常信息應該包括兩類信息:案發(fā)現(xiàn)場信息和異常堆棧信息。如果不處理,那么通過關(guān)鍵字 throws 往上拋出。

  • 正例:logger.error("inputParams:{} and errorMessage:{}", 各類參數(shù)或者對象 toString(), e.getMessage(), e);

10.【強制】日志打印時禁止直接用 JSON 工具將對象轉(zhuǎn)換成 String

  • 說明:如果對象里某些 get 方法被覆寫,存在拋出異常的情況,則可能會因為打印日志而影響正常業(yè)務(wù)流程的執(zhí)行。

  • 正例:打印日志時僅打印出業(yè)務(wù)相關(guān)屬性值或者調(diào)用其對象的 toString() 方法。

11.【推薦】謹慎地記錄日志。生產(chǎn)環(huán)境禁止輸出 debug 日志;有選擇地輸出 info 日志;如果使用 warn 來記錄剛上線時的業(yè)務(wù)行為信息,一定要注意日志輸出量的問題,避免把服務(wù)器磁盤撐爆,并記得及時刪除這些觀察日志。

  • 說明:大量地輸出無效日志,不利于系統(tǒng)性能提升,也不利于快速定位錯誤點。記錄日志時請思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問題排查帶來好處?

12.【推薦】可以使用 warn 日志級別來記錄用戶輸入?yún)?shù)錯誤的情況,避免用戶投訴時,無所適從。如非必要,請不要在此場景打出 error 級別,避免頻繁報警。

  • 說明:注意日志輸出的級別,error 級別只記錄系統(tǒng)邏輯出錯、異?;蛘咧匾腻e誤信息。

13.【推薦】盡量用英文來描述日志錯誤信息,如果日志中的錯誤信息用英文描述不清楚的話使用中文描述即可,否則容易產(chǎn)生歧義。

  • 說明:國際化團隊或海外部署的服務(wù)器由于字符集問題,使用全英文來注釋和描述日志錯誤信息。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號