摘要:是指可能導致程序終止的非常嚴重的時間。具有最高的級別,旨在關閉中的日志功能。因此為每一個消息選擇一個合適的日志級別是非常重要的。日志的個小建議將日志訪日代碼塊它能顯著的減少因為字符串拼接而帶來的性能的影響。
前言
首先,這篇文章沒有進行任何的日志功能的詳細介紹,而是對日志提出了幾種最佳實踐。適合對日志記錄有所了解的同學閱讀。
下面是正文:
JAVA日志管理既是一門科學,又是一門藝術。科學的部分是指了解寫日志的工具以及其API,而選擇日志的格式,消息的格式,日志記錄的內容,哪種消息對應于哪一種日志級別,則完全是基于經驗。從過去的實踐證明,JAVA的日志記錄會嚴重的影響性能。我也曾多次親眼見到在DEBUG模式下運行的在線股票交易程序,比在WARN或是其它更高層次模式下運行時延時要嚴重的多。延時和速度是任何電子交易平臺或是股票交易平臺的一個重大關注點,所以我們必須了解并掌握JAVA日志及其最佳實踐。這不僅僅只是為了用在金融或是投資銀行領域,它適用于所有既追求速度又需要日志功能的應用。
為何需要日志這是一個很基本的爭議,人們會爭辯說,我們可以使用System.out.println()來打印消息,為何還需要日志呢?每個人剛開始接觸JAVA時,都使用System.out.println()在控制臺打印消息。但是它的功能遠遠沒有日志記錄API如log4j或是java.util.logging強大。如果你正在寫一個java服務器應用,那么你只有通過日志文件才能知道你的服務器在做什么。如果你沒有記錄任何日志,那么沒有人知道你的服務器在干啥。而如果你的服務器作為一個中間件連接到應用中時,比如從股票交易系統或是電子交易系統獲得輸入流,將其轉換并標準化后發送到輸出流,這時日志就更為重要。沒有日志你根本不知道究竟哪里出了問題。因此,日志在JAVA中是必不可少的。
JAVA中有哪些不同的日志級別使用過JAVA日志的童鞋一定知道這些基礎的日志級別比如DEBUG, INFO, WARN和ERROR。
DEBUG是最低的限制級別。這個級別只能用于開發和測試環境中,不可以用于生產環境。
INFO略高于DEBUG的限制級別,我們應該用這個級別記錄一些信息型消息比如服務器啟動成功,輸入的數據,輸出的數據等等。
WARN的限制級別高于INFO,它用來記錄警告信息比如客戶端和服務器之間的連接中斷,數據庫連接丟失,Socket達到上限。這些信息是最為重要的,因為你可以在這些信息出現時發出警告,從而讓運維團隊管理應用程序的運行,并及時處理這些報錯。
ERROR比WARN的限制級別還高,用于記錄ERROR和Exception。你可以在該日志級別上設置警報裝置,并且提醒運維團隊對之做出處理。ERROR非常重要,你必須將其記錄下來。
FATAL是指可能導致程序終止的非常嚴重的時間。在這種事件之后你的應用很可能會崩潰。
OFF具有最高的級別,旨在關閉JAVA中的日志功能。
這些日志級別是根據slf4j整理的,和java.util.loggingAPI中定義的級別不太一樣。java.util.logging還提供了其它的基于問題嚴重性進行劃分的日志級別如SEVERE, FINER, FINEST, FATAL 等。
使用log4j還是java.util.logging我會推薦使用log4j,你可能會對此持有異議。我也同意java.util.logging的功能很強大,但是我發現log4j更易于使用。你已經了解了log4j的各個日志級別,這里每個級別都非常恰當的描述了其功能。log4j還提供了額外的靈活性,你無需重新啟動應用來改變日志的級別。當然,你也可以在java.util.logging中通過JMX實現這個功能。
log4j還允許我們在配置文件log4j.xml中設置每個類的日志級別。你既可以使用XML文件也可以使用properties文件進行配置。而且log4j是線程安全的。它被設計用于高并發的系統中。在另一方面,我發現java.util.logging中的Formatter和Appender功能非常棒。
為何在JAVA中使用日志會影響性能通常來說,記錄日志越頻繁,所需的IO操作就越多,從而影響了應用的性能。因此為每一個消息選擇一個合適的日志級別是非常重要的。既然我們不能不使用JAVA日志,那么我們只能控制日志的級別以及在那個級別上記錄的日志內容。所以,一定要在isDebugEnabled()代碼塊中記錄DEBUG消息,如下所示:
if(logger.isDebugEnabled()){ logger.debug("java logging level is DEBUG Enabled") }
在生產環境中一定要使用WARN或是更高級別的日志記錄等級,一定不要使用DEBUG。它很可能成為性能下降的罪魁禍首。
JAVA日志的10個小建議 1.將DEBUG日志訪日isDebugEnabled代碼塊它能顯著的減少因為字符串拼接而帶來的性能的影響。
2.謹慎的消息的等級當你在編寫服務器端應用時,這一點顯得格外的重要,因為它是你觀察服務器運行情況的唯一途徑。如果你記錄了太多的日志,則會影響服務器的性能,但是如果你不記錄重要的信息如輸入數據和輸出數據,那么就很難識別究竟發生了什么問題。
3.使用slf4j或是java.util.loggin我推薦slf4j因為它的靈活性非常高。它允許在不重啟應用的前提下更改日志級別。你可以通過log4j的看門狗來不停的尋找目錄中的log4j.xml配置文件,并且在找到后重置日志配置。
4.log4j可以為不同的類配置不同的日志級別你可以將一些類設置為INFO級別,再將另一些類設置為WARN級別或是ERROR級別。
5.日志的格式化不要忘了記錄線程的名稱和完整的JAVA類名,因為如果有多個線程同時在執行這段代碼,你可能根本找不出事件序列。在我看來,這一條建議最為重要
6.從日志中生成報告在記錄日志時要保證一致性和信息性,從而可以分析日志。
7.使用前綴來說明哪一部分代碼在打印日志前綴是指如客戶端,數據庫或是Session等等。之后你可以使用grep或是find來找到和這些關鍵字相關的日志。我在進行了這種實踐后發現它非常有助于debug或是調查事件,尤其是當日志文件很龐大的時候。你可以將所有數據庫級別的日志加上前綴DB_LOG,再將所有SESSION級別的日志加上前綴SESSION_LOG
8.如果某個日志沒有分配等級,則將其繼承最近級別的等級這也是為什么我們總是將日志等級分配到根日志上log4j.rootLogger=DEBUG.
9.沒有日志和過度日志都是不好的原因前面已經說明
10.自檢日志并調整日志最好用英文記錄日志,而且要有良好的可讀性,從而在查閱時能夠快速理解日志。
11.使用標準化格式而不要自行拼接logger.debug("No of Orders " + noOfOrder + " for client: " + client);//不好 logger.debug("No of Orders {} for client: {}", noOfOrder, client);補充:記錄哪些信息以及各個信息對應什么級別的日志 1.不要記錄敏感信息
不要記錄敏感信息如密碼,身份證號,信用卡號或賬戶號。
2.盡量記錄決策性信息比如,一個JAVA應用需要從偏好文件或是環境中加載配置,如果沒有找到就使用默認的配置。如果你在使用默認配置,那么你應當記錄如下信息:
logger.info("Not able to load personal settings, default Setting selected for user : {}", user);
這個日志丟失了一個關鍵性信息,為什么無法加載到個人配置?因此如果出現異常的話,還應當記錄異常。當然,這條日志也提供了有用的信息,比如究竟是哪個用戶遇到了這個問題。
3.一致性一致性在日志和編碼中都很重要。無論你采用哪種格式,你都應當堅持一致性。你應當花些時間仔細考慮日志的格式,從而用它來捕獲有用的信息。
4.記錄一切出現問題時輔助debug的信息舉個例子,我們經常在應用中將String轉化為Date,如果String的格式不正確的話,我們通常會拋出ParseException。但是我經常看到有的代碼里捕獲了這個異常之后,將Date賦值為null并打印如下日志:
logger.info("failed to convert String to date")
看到這行日志的時候,你根本不知道那個date傳入了不合法的值。它也沒有打印出不合法的String的內容究竟是什么。你需要這些信息來解決這個問題。一個更好的日志信息如下:
logger.info("invalid startDate: {}", startDate);
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注我的微信公眾號!將會不定期的發放福利哦~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68545.html
摘要:無需檢查的異常也是的子類。從低層拋出的需檢查異常強制要求調用方捕獲或是拋出該異常。當前執行的線程將會停止并報告該異常。單元測試允許我在使用中查看異常,并且作為一個可以被執行的文檔來使用。不要捕獲最高層異常繼承的異常同樣是的子類。 前言 異常處理的問題之一是知道何時以及如何去使用它。我會討論一些異常處理的最佳實踐,也會總結最近在異常處理上的一些爭論。 作為程序員,我們想要寫高質量的能夠解...
摘要:讀取出數據時,將此版本號一同讀出,之后更新時,對此版本號加一。此時,將提交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大于數據庫表當前版本號,則予以更新,否則認為是過期數據。 前言 很多人都在討論數據的指數型增長,以及我們將會有比想象的還要大的數據量。但是,很少有人從數據庫的角度談論這個問題。隨著數據量的暴漲,數據庫也需要隨之升級。這也是為什么既要了解如...
摘要:否則它就會用新的值替代當前值。在這種情況下,鎖可能會優于原子變量,但在實際的爭用級別中,原子變量的性能優于鎖。在中引入了另外一個構件。 題目要求 在我們深入了解CAS(Compare And Swap)策略以及它是如何在AtomicInteger這樣的原子構造器中使用的,首先來看一下這段代碼: public class MyApp { private volatile int ...
摘要:因此,誤解幾乎是與之俱來的。這是完全錯誤的。就像所強調的,對于一個被稱作的來說,狀態轉移管理是一個必須要完成的需求。你可以將其稱為或是,但是請不要把它叫做。 2000年的時候,Douglas Crockford聲明JavaScript是最被誤解的編程語言。這種誤解來源于不良的命名規范,錯誤設計,非標準模式等等。因此,誤解幾乎是與之俱來的。 我也在關于Restful架構上發表了一個相似的...
閱讀 2089·2021-11-02 14:48
閱讀 2763·2019-08-30 14:19
閱讀 2934·2019-08-30 13:19
閱讀 1302·2019-08-29 16:17
閱讀 3239·2019-08-26 14:05
閱讀 2994·2019-08-26 13:58
閱讀 3082·2019-08-23 18:10
閱讀 1110·2019-08-23 18:04