程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> top 10 tipis on Logging in Java- Tutorial (翻譯),tipisjava-

top 10 tipis on Logging in Java- Tutorial (翻譯),tipisjava-

編輯:JAVA綜合教程

top 10 tipis on Logging in Java- Tutorial (翻譯),tipisjava-


開篇廢話,就記得出國之前有一回騰訊面試,面試官說既然你都快要出國了,英語肯定挺不錯的,那為什麼不去翻譯一些國外好的文章呢,我希望找一個能主動學習的人,一直受教。目前在實習,需要做大數據相關方向,都是挺前衛的東西,發現國內的資料有點稀缺,hadoop官網啥的都是英文,硬著頭皮開始啃這些,發現國外的技術想法真的挺不錯的,用英文找資料也得卻方便。我把我做的過程中找到的一些不錯的文章都保存下來,github項目地址,感興趣的可以去fork或者star一個,絕大部分都是英文,如果英語不錯的可以直接看,都是不錯的文章。

______________________________________________________

Java 日志或者說用 JAVA 記錄日志是一門學問也是一門藝術。 知道日志記錄工具和 API 是一門技術,但是選擇日志格式,消息格式,記錄內容,日志級別更像來自經驗的總結。因為 Java日志會非常影響性能,我見證了線上股票交易系統因為 DEBUG 模式比 WARN 或者更高的日志級別帶來的延遲, 在線交易系統中,延遲和響應速度是非常重要的因素,尤其是對於股票交易系統。正因為此,系統的了解 Java 日志是非常有必要的, 不僅僅是對於金融和銀行投資系統,而且對於任何的追求響應速度和完備的日志的 java 服務器或者客戶端應用.

在這一篇 Java 日志總覽中,我會分享我在 Java 日志方面的經驗,我會回答一些基礎的問題“為什麼需要 Java 日志”,“不同的 Java 日志級別以及如何選擇正確的日志級別”,“不正確的 Java 日志如何影響了性能”。 我會討論一些 Java 日志工具和 API, 例如 log4j.jar 和Java.util.logging.

為什麼需要 JAVA 日志

這是一個很基礎的關於 Java 日志的問題,大家都說反正已經有 System.out.println()來打印記錄了,為什麼還需要 logging。我們都是從 System.out.println()打印消息(”Hello World!”)到終端上,開始的 Java 學習之旅。但是這個遠不能和功能強大的 Java 日志 API(比如 log4j 和java.util.logging)相比。 如果你開發一個 Java 服務器端應用,如果你不記錄任何運行信息,你就不可能知道你的服務器正在干什麼。這對於需要很多上傳信息和下載信息(信息交換)的應用來說(例如股票交易和在線交易系統),記錄日志顯得更為重要。如果不記錄日志,你壓根不知道哪裡出了問題。這就是為什麼 Java 日志服務在 Java 服務端應用中很重要,而且是必須的。

Java 日志的不同級別

用過 Java 日志的一定知道 Java 日志級別, 例如 DEBUG, INFO, WARN 和 ERROR. 

DEBUG 是最低限制級的日志級別,並且我們需要記錄所有的日志去調試代碼,這個模式只能在開發和測試環境中使用,不能在生產環境中使用。

INFO 是比 DEGUG 更限制的日志級別, 我們只應該記錄一些重要的信息內容,例如服務器啟動,有請求,輸入輸出數據等等。

WARM 是比 INFO 更限制的日志級別,主要是用來記錄警告信息,包括服務器和客戶端斷開連接,數據庫斷開連接, socket 到達限制。 這些信息是很有用的,你可以在此基礎上監控你的服務器運行狀態並對這些警告信息做出反應。

ERROR 是比 WARN 更限制的日志級別,它是用來記錄錯誤和 Exception 的,你可以 alert(彈出)這些錯誤信息,你必須牢記打印出 ERROR 的錯誤信息。

FATAL 是用來記錄很嚴重的錯誤信息,這些錯誤一般會導致服務器奔潰或者宕機。

OFF 級別代表了要關閉 Java Logging 功能。

這些日志級別是定義在 log4j 包的基礎上,跟 java.util.logging API 區別也不大, java.util.loggingAPI 還額外提供例如 SEVERE,FINER,FINEST,FATAL 等其他級別。上述的那些級別是最常用的。

                                            使用 log4j 或者 java.util.loggin API 來做日志記錄

if(logger.isDebugEnabled()){ logger.debug("java logging level is DEBUG Enabled"); }

在正式環境中使用 WARN ERROR 或者 FINER, FINEST 這樣的日志級別, 絕對不要使用 DEBUG 在正式環境中, 我見過一些應用運行起來非常慢的原因就是因為有 DEBUG 級別的日志在打印。

在 JAVA 日志服務中的 10 個小細節

1) 使用 isDebugEnabled()將來輸出 DEBUG 日志, 它會節省很多的字符串連接操作當你轉換到正式環境中。 {這裡是因為正式環境中, 都不需要執行這段代碼了, 所以不會有日志輸出,當然節省了很多的字符串連接操作}。

2) 仔細的選擇你的日志級別和打印日志的位置, 日志不宜過多, 因為會影響性能, 也不宜過少, 因為過少的日志信息很難讓你定位到錯誤位置和你需要的關鍵信息。

3) 建議使用 log4j.xml, 因為我用過它很多次, 我發現它很靈活, 它能讓你改變日志級別而不需要重啟服務, 這在環境轉換中是非常有用的(從調試環境到正式環境), 它是通過 log4jwatchdog( 看門狗) 程序一直在監視 log4j.xml,如果找到它就加載然後重新設置日志級別。

4) 通過使用 log4j.xml,你可以對不同的 java 類設置不同的日志級別, 這是非常靈活的。

5) 另一個重要的點是, 記住日志格式, 在日志中最好包括進程名字和類名, 方法名, 這會幫你很方便的定位。

6) 仔細選擇日志格式, 你可以通過它生成報表。 Balabala 一堆。

7) 在你生成日志的時候, 可以在日志的開頭使用一些特殊的標記, 例如方便定位到 client side,database side, session side 等, 因為接下來你可以在 linux 環境下使用 grep 或者 find 命令很方便的找到相關的信息。 例如你可以加一個標記“ DB_LOG” 針對於有關數據庫的日志,“ SESSION_LOG” 針對有關於緩存的信息。

8) 假如你沒用定義一個日志級別, 那麼它會自動的是使用離他最近的一個錨, 這就是為什麼我們經常定義 root 日志級別為 log4j.rootLogger = DEBUG.

9) 沒有日志和過多的日志都是壞主意, 所以仔細選擇你想要打印的內容並選好日志級別, 這樣能讓你在正式環境中快速的運行應用, 同時讓你在開發環境中很快的找到問題。

10) 優化你的日志是很重要的, 日志要保持簡單和明了, 不單單是為了自己, 也為了方便別人查看和更改。

11) 如果你是使用 SJFS 來記錄 java 日志的, 那麼使用參數模式可以讓你性能變得更快,

logger.debug("No of Orders " + noOfOrder + " for client : " + client); // slower
logger.debug("No of Executions {} for clients:{}", noOfOrder , client); // faster

 

這裡作者也不知道為什麼, 其實是因為第二種模式少了字符串拼接過程, 所以變的更快了。 後面的鏈接中有給出, 大家可以看看。

更新:

記錄日志的好壞可以用來區分好的程序員和偉大的程序員。 不僅僅是對於 JAVA,對於其他編程語言也是一樣的。 你需要關注的是:

1) 你需要打印什麼樣的信息?

2) 這個信息是屬於哪個日志級別的?

這是兩個最重要的問題, 下面是我編程的一些寶貴經驗:

1) 不要打印敏感信息, 包括密碼, 社會人口號, 信用卡賬號等等, 在你完成這部分開發的時候就應該把這些可能打印出來的關鍵信息刪除了。

2) 打印一些決策性的信息, 比如你在 java 中加載一些配置信息, 如果沒找到就加載默認選項,那你可以打印以下內容:

logger.info("Not able to load personal settings, default Setting selected for user : {user});

這裡就包括決策性信息, 而且也包括了哪個用戶信息你沒法打印, 因為你可能擁有很多個用戶。

3) 保持一致性, 日志格式需要保持一致。

4) 打印關鍵信息, 尤其是你在調試的時候。

我們經常用到日期轉換成字符串的操作, 這個方法經常會拋出一些異常, 以下就是一個日志,這個打印信息包含的內容不全, 它沒有告訴我們到底是什麼問題, 是輸入的日期格式不對, 日期空白, 還是什麼。

logger.info("failed to convert String to date");

這個打印日志語句就好了很多, 它告訴了我們輸入的到底是什麼東西, 我們可以很容易的定位出問題位置和問題原因。 logger.info("invalid startDate : {startDate});

感謝你閱讀本篇文章, 如果你覺得不錯, 歡迎分享給你的朋友。

_________________________________________________________

第一次翻譯文章,有些地方都只是意會,沒有翻譯原文的意思。github上有英文原版,可以直接去閱讀,附錄裡面的幾篇文章都挺不錯的,看完基本就弄明白,透徹了。

——————————————————————————————————
最後面是我找到的幾篇 JAVA 日志級別的文章
http://developer.51cto.com/art/201507/484646.htm Java 日志終極指南
http://www.ibm.com/developerworks/cn/java/j-lo-practicelog/index.html#ibm-pcon Java 日志管理
最佳實踐
http://www.oschina.net/translate/why-use-sl4j-over-log4j-for-logging?cmp 為什麼使用 SLF4J 而不
是 Log4J 來做 Java 日志( 這是原作者寫的關於 java 日志的另一篇文章)

______________________________________________________

請尊重勞動成果,轉帖請附上 博客園 tony_lp 首發

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved