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

2021-03-23 11:15 更新

\1. 【強(qiáng)制】應(yīng)用中不可直接使用日志系統(tǒng)(Log4jLogback)中的 API,而應(yīng)依賴使用日志框架(SLF4J、JCL--Jakarta Commons Logging)中的 API,使用門面模式的日志框架,有利于維護(hù)和各個(gè)類的日志處理方式統(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. 【強(qiáng)制】所有日志文件至少保存 15 天,因?yàn)橛行┊惓>邆湟浴爸堋睘轭l次發(fā)生的特點(diǎn)。對(duì)于

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

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

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

\4. 【強(qiáng)制】應(yīng)用中的擴(kuò)展日志(如打點(diǎn)、臨時(shí)監(jiān)控、訪問日志等)命名方式:

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

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

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

mppserver_monitor_timeZoneConvert.log

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

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

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

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

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

  • 正例:

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

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

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

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

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

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

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

10.【強(qiáng)制】日志打印時(shí)禁止直接用 JSON 工具將對(duì)象轉(zhuǎn)換成 String。

  • 說明:如果對(duì)象里某些 get 方法被覆寫,存在拋出異常的情況,則可能會(huì)因?yàn)榇蛴∪罩径绊懻I(yè)務(wù)流程的執(zhí)行。

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

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

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

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

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

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

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)