日誌--列印規範
日誌
記錄應用系統日誌主要有三個原因: 記錄操作軌跡, 監控系統執行狀況, 回溯系統故障。
- 記錄操作行為及操作軌跡資料
可以資料化地分析使用者偏好,有助於優化業務邏輯,為使用者提供個性化的服務, 例如: 通過access.log 記錄使用者的操作頻度和跳轉連結,有助於分析使用者的後續行為。 - 監控系統執行狀況
是指對伺服器使用狀態, 如記憶體,CPU等使用情況;應用執行情況,如相應時間,QPS 等互動狀態; 應用錯誤資訊,如空指標,SQL 異常等的監控。 - 回溯系統故障
當系統發生線上問題時,完整的現場日誌有助於工程師快速定位問題。 例如,當系統記憶體溢位時,如果日誌系統記錄了問題發生現場的堆資訊,就可以通過這個日誌分析時什麼物件在大量產生並且沒有釋放記憶體, 回溯系統故障,從而定位問題。
日誌規範
推薦的日誌檔案命名方式為: appName_logType_logName.log 。其中,logType為日誌型別,推薦分類有 stats(統計),monitor(監控),visit(訪問)等; logName 為日誌描述。
這種命名的好處就是通過檔名就可以知道檔案屬於什麼應用,什麼型別,什麼目的,也有利於歸類查詢。例如,mppserver 應用中單獨監控時區轉換異常的日誌檔案定義為: mppserver_monitor_timeZoneConvert.log 。
日誌的級別
針對不同的場景,日誌被分為五種不同的級別,按照重要程度由低到高排序:
DEBUG 級別日誌
記錄對除錯程式有幫助的資訊。INFO 級別日誌
用來記錄程式執行現場,雖然此處未發生錯誤,但是對排查其他錯誤具有指導意義。WARN 級別日誌
也可以用來記錄程式執行現場, 但是更偏向於表明此處有出現潛在錯誤的可能。ERROR 級別日誌
表明當前程式執行發生了錯誤,需要被關注,但是當前發生的錯誤,沒有影響系統的繼續執行。FATAL 級別日誌
表明當前程式執行出現了嚴重的錯誤事件,並且將會導致應用程式中斷。
- 預先判斷日誌級別
對DEBUG ,INFO 級別的日誌,必須使用條件輸出或者使用佔位符的方式列印。該約定綜合考慮了程式的執行效率和日誌列印需求。
// 使用條件判斷形式
if(logger.isDebugEnabled()){
logger.debug("Percessing trade with id: "+ id + "and symbol: "+symbol);
}
// 使用佔位符形式
logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);
- 避免無效日誌列印
生產環境禁止輸出DEBUG 日誌且有選擇地輸出 INFO 日誌。
使用 INFO ,WARN 級別來記錄業務行為資訊時,一定要控制日誌輸出量,以免磁碟空間不足,同時要為日誌檔案設定合理的生命週期,及時清理過期日誌。
避免重複列印,務必在日誌配置檔案中設定additivity=false
, 示例:
<logger name="com.taobao.ecrm.member.config" additivity = "false">
-
區別對待錯誤日誌
WARN, ERROR 都是與錯誤有關的日誌級別,但不要一發生錯誤就籠統的輸出ERROR 級別日誌. 一些業務異常時可以通過引導重試就能恢復正常的, 例如 使用者輸入引數錯誤.在這種情況下,記錄日誌是為了在使用者諮詢時可以還原現場,如果輸出為ERROR 級別就表示一旦出現就需要人為介入, 這顯然是不合理的,所以,ERROR級別只記錄系統邏輯錯誤,異常或者違反重要的業務規則,其他錯誤都可以歸為 WARN 級別. -
保證記錄內容完整
日誌記錄的內容包括現場上下文資訊與異常堆疊資訊, 所以列印時需要注意以下兩點:
(1) 記錄異常時一定要輸出異常堆疊, 例如 logger.error(“xxx”+e.getMessage(),e);
(2) 日誌中如果輸出物件例項,要確保例項類重寫了 toString 方法,否則只會輸出物件的 hashCode值,沒有實際意義.
綜上所述, 記錄日誌時一定請思考三個問題:
① 日誌是否有人看
② 看到這條日誌能做什麼
③ 能不能提升問題排除效率
日誌框架
log4j, logback , jdk-logging, slf4j, commons-logging等框架;
日誌框架分為三大部分,包括日誌門面, 日誌介面卡, 日誌庫;
利用門面設計模式, 即 Facade 來進行解耦, 使日誌使用變得更加簡單. 如圖所示:
-
日誌門面
門面設計模式是物件導向設計模式中的一種,日誌框架採用的就是這種模式, 類似於JDBC 的設計理念. 它只提供了一套介面規範,自身不負責日誌功能的實現, 目的是讓使用者不需要關注底層具體是哪個日誌庫來負責日誌列印及具體的使用細節等. 目前用得最為廣泛的日誌門面有兩種: slf4j 和 commons-logging -
日誌庫
它具體實現了日誌的相關功能, 主流的日誌庫有三個,分別是log4j, log-jdk, logback.
在JDK1.4版引入了一個日誌庫 java.util.logging.Logger ,簡稱 log-jdk .
logback 是最晚出現的, 它與log4j 出自同一個作者, 是log4j 的升級版且本身就實現了 slf4j的介面 -
日誌介面卡
日誌介面卡分兩種場景:
(1) 日誌門面介面卡, 因為slf4j 規範是後來提出的,在此之前的日誌庫是沒有實現 slf4j 的介面的, 例如 log4j; 所以,在工程裡使用 slf4j + log4j 的模式,就額外需要一個介面卡( slf4j-log4j12) 來解決介面不相容的問題
(2) 日誌庫介面卡, 在一些老的工程裡, 一開始為了開發簡單而直接使用了日誌庫API 來完成日誌列印, 隨著時間的推移想將原來直接呼叫日誌庫的模式改為業界標準的門面模式( 例如 slf4j + logback 組合),就需要一個介面卡來完成從舊日誌庫的API 到slf4j 的路由
如果是新工程推薦使用 slf4j + logback 模式, 因為logback 自身實現了slf4j 的介面, 無需額外引入介面卡,另外 logback 是log4j 的升級版, 具備比 log4j 更多的優點.
可通過如下配置進行整合
<dependency>
<groupid>org.slf4j</groupid>
<artifactid>slf4j-api</artifactid>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupid>ch.qos.logback</groupid>
<artifactid>logback-core</artifactid>
<version>${logback-core.version}</version>
</dependency>
<dependency>
<groupid>ch.qos.logback</groupid>
<artifactid>logback-classic</artifactid>
<version>${logback-classic.version}</version>
</dependency>
完成了日誌框架的整合,再加上一個日誌配置檔案(如 logback.xml , log4j.xml等) , 並在工程啟動時載入,然後就可以進行日誌列印了.示例程式碼如下:
private static final Logger logger = LoggerFactory.getLogger(Abc.class) ;
logger 被定義為static 變數,是因為這個 logger 與當前類繫結, 避免每次都new 一個新物件, 造成資源浪費,甚至引發 OutOfMemoryError 問題.
相關文章
- 工程實踐:如何規範地列印程式日誌?
- 系統崩了,竟然是不規範列印日誌的鍋?
- 【Spring】日誌列印sql,日誌配置列印sqlSpringSQL
- Node.js + ELK 日誌規範Node.js
- 日誌列印
- Log 工具列印日誌
- Unity——日誌列印工具Unity
- 39,日誌列印sql 配置SQL
- feign配置日誌不列印
- MySQL列印死鎖日誌MySql
- 日誌到底該如何列印?
- Linux動態列印kernel日誌Linux
- 設定mybatis 是否列印日誌MyBatis
- java日誌列印使用指南Java
- [Java/日誌] 日誌框架列印應用程式日誌程式碼的執行情況Java框架
- 日誌規約
- Flutter - 列印好用的Debug日誌Flutter
- 【工具】方法日誌列印+任務切片
- java 日誌脫敏框架 sensitive,優雅的列印脫敏日誌Java框架
- python logger 列印日誌錯誤行數Python
- SpringBoot自定義註解、AOP列印日誌Spring Boot
- 日誌列印的碎碎念總結
- Python 日誌列印之自定義logger handlerPython
- 日誌-log4j2基於AsyncLogger的非同步日誌列印非同步
- 日誌-log4j2基於AsyncAppender的非同步日誌列印APP非同步
- 日誌分析常規操作
- Flutter實戰之自定義日誌列印元件Flutter元件
- 關閉Druid中某些錯誤日誌列印UI
- 微服務開發系列:如何列印好日誌微服務
- 五年Java經驗,面試還是說不出日誌該怎麼寫更好?——日誌規範與最佳實踐篇Java面試
- Android進階:一、日誌列印和儲存策略Android
- 列印日誌時為什麼要使用isDebugEnabled 、isInfoEnabled
- Spring Cloud Gateway 之 請求應答日誌列印SpringCloudGateway
- c# Log 日誌 以及不列印重複LogC#
- 工作總結!日誌列印的11條建議
- python怎麼將列印輸出日誌檔案Python
- Flutter | 日誌還能這麼列印,太秀了!Flutter
- Python 日誌列印之logging.getLogger原始碼分析Python原始碼