国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

有效地記錄日志簡化企業的開發過程

2019-11-18 12:27:08
字體:
來源:轉載
供稿:網友

  在企業級的開發過程中,我們不可避免地會碰到很多問題;假如您希望在開發過程的后期能夠有效地捕捉 bug,那就需要一種有效的日志策略。但是在一個企業的應用程序中要想實現有效地記錄日志,需要進行一番規劃,并設計一些準則。在本文中,顧問 Charles Chan 將向您介紹一些最好的實踐,從而幫助您從項目一開始就編寫有用的日志代碼。
  
  假如您是一名開發人員,那您很可能就已經具有這種經驗:您已經開發了一些代碼以及一些測試用例。應用程序經過了嚴格的 QA 測試,您確信代碼可以完全適合業務的需求。然而,在將應用程序最終交付終端用戶的手里時,卻會出現一些預想不到的問題。假如沒有適當的日志消息,可能需要花費幾天的時間來診斷這些問題。不幸的是,大部分項目對于日志都沒有一個清楚的策略。假如沒有這種策略,系統產生的日志消息就有可能無益于問題的分析和解決。在本文中,我們將討論企業應用程序日志的各個方面的問題。您將看到一個 java™ 平臺上日志 API 的概述,學習一些最好的編寫日志代碼的實踐,并了解假如需要在產品環境中對具體日志重新進行排序,應該如何處理。
  
  選擇日志 API
  
  在使用 Java 平臺進行開發時,可以使用兩個主要的日志 API:Apache Log4J 和 Java Logging API,在 1.4 及更高版本的 Java 平臺中都提供了這兩個 API。與 Java Logging API 相比,Log4J 更加成熟,特性也更加豐富。這兩個日志的實現都采用了一個類似的設計模式(如圖 1 所示)。除非您的公司限制要使用第三方的庫,否則我強烈建議使用 Log4J。假如您不能決定使用哪個 API,就可以使用 Apache Commons Logging API,它對底層的日志實現進行了封裝。從理論上來說,這樣不用修改代碼就可以進行日志實現的切換。然而,實際上您很少會切換日志的實現;因此,我不建議使用 Apache Commons Logging API,因為它的復雜性并不沒有給您帶來其他特性。
  
  日志概述
  
  Log4J 和 Java Logging API 都采用了類似的設計和使用模式(如圖 1 和清單 1 所示)。消息首先被創建,然后傳遞給一個具有特定優先權的日志對象。這些消息的目的和格式是由輸出處理程序及其布局所決定。
  
  清單 1. 日志對象的實例化和使用
  
  import org.apache.log4j.Logger;public class MyClass { /*  * OBTain a logger for a message category. In this case, the message category is  * the fully qualified class name of MyClass.  */ PRivate static final Logger logger = Logger.getLogger(MyClass.class.getName()); ... public void myMethod() {  ...  if (logger.isDebugEnabled()) {   logger.debug("Executing with parameters: " + param1 + ":" + param2);  } }}
  
  一個好的日志實現中提供了很多不同的輸出處理程序,最常見的文件輸出處理程序和終端輸出處理程序。Log4J 還提供了一些處理程序將消息發布到一個 JMS 主題中,或者將消息插入一個數據庫表中。盡管這編寫一個定制的附加器并不困難,但是編寫和維護這種代碼的總體成本不應低估。消息的格式可以通過 Layout 對象進行配置。最常見的 layout 對象是 PatternLayout,它根據所提供的模式對消息進行格式化。
  
  清單 2 給出了一個 Log4J 的樣例配置文件,它負責配置 FileAppender。在這種配置中,com.ambrosesoft.log.MyClass 類中的錯誤消息被發送給 FileAppender,后者將其寫入一個名為 log.txt 的文件中。這些消息是根據與這個添加器相關的 layout(在這種情況中是 PatternLayout)進行格式化的。
  
  清單 2. Log4J xml 配置樣例文件
  
  <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">     <appender name="fileAppender" class="org.apache.log4j.FileAppender">  <param name="File" value="log.txt"/>  <param name="Append" value="true"/>  <layout class="org.apache.log4j.PatternLayout">   <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>  </layout> </appender> <category name="com.ambrosesoft.log.MyClass">  <priority value="error"/>  <appender-ref ref="fileAppender"/> </category> <root>  <priority value="debug"/>  <appender-ref ref="fileAppender"/> </root></log4j:configuration>
  
  日志最佳實踐
  
  關于日志,您要做的一個最重要的選擇可能是確定一種模式,將每個日志消息分配給一個特定的 類別。常見的一種實踐是使用每個類的全名,這些類的操作會被作為一個消息類別在日志中記錄(正如我們在清單 1 中看到的一樣),這是因為這可以讓開發人員更細粒度地記錄每個類的設置。然而,這只有在使用日志消息來跟蹤執行過程時才能良好地工作。在企業級的應用程序中,有很多其他類型的日志消息。舉例來說,一條日志消息可能是為安全顧問產生的,而另外一條日志消息則可能是會為了幫助進行性能調優而產生的。假如這兩條消息所關注的是同一個類,這樣就會被分配給相同的類別,這將很難在日志輸出結果中對其進行區分。
  
  為了避免這個問題,應用程序應該具有一組專用的日志記錄程序,它們都進行了獨特的分類,如清單 3 所示。每個日志記錄程序都可以配置自己的優先級和輸出處理程序。例如,安全性日志記錄程序可以在將日志寫入目的地之前對消息進行加密。有時應用程序的設計者應該與使用日志的用戶(例如安全顧問)一起來商討日志的輸出格式,從而對這些消息進行更好的控制。
  
  清單 3. 專用的日志記錄程序
  
  import org.apache.log4j.Logger;public interface Loggers { Logger performance = Logger.getLogger("performance"); Logger security = Logger.getLogger("security"); Logger business = Logger.getLogger("business");}...public class MyClass { .... if (Loggers.security.isWarnEnabled()) {  Loggers.security.warn("access denied: Username [" + userName + "] ..."); } ...}
  
  選擇日志的級別
  
  一個 類別 (例如 security)中的消息可以具有不同的 優先級。有些消息是為了調試而產生的,有些是為了警告而產生的,有些則是出現錯誤而產生的。消息的不同優先級可以通過記錄 級別 來產生。最常用的日志級別有:
  
  Debug: 這個級別的消息中包含了非常廣泛的上下文信息。通常用于問題診斷。
  
  Info: 這些消息包含了一些有助于在產品環境中(粒度較粗)幫助跟蹤執行過程的上下文消息。
  
  Warning: 警告消息,說明系統中可能存在問題。例如,假如這個消息類別是有關安全性方面的,那么假如檢測到字典攻擊,就應該產生一條警告消息。
  
  Error: 錯誤消息說明系統中出現了嚴重的問題。這種問題通常都是不可恢復的,需要人工進行干預。
  
  標準的 Java Logging API 和 Apache Log4J 在此之外又提供了一些日志級別。日志級別的主要目標是幫助您過濾有用信息中的噪聲。為了防止出現使用錯誤的級別以及降低日志消息的效用的情況,在開始編碼之前,必須為開發人員提供一個清楚的指導方針。
  
  日志消息的格式
  
  一旦選定日志記錄程序并建立起日志級別之后,就可以開始構建日志消息了。在這樣做時,重要的是要包含盡可能多的上下文信息,例如用戶提供的參數,其他應用程序的狀態信息。記錄日志對象的一種方法是將它們轉換成 XML。第三方庫,例如 XStream(請參閱 參考資料)可以自動將 Java 對象轉換成 XML 。盡管這是一種非常強大的機制,但是我們必須要考慮在速度與具體程度之間達到一種平衡。除了典型的應用程序狀態信息之外,還應該記錄以下信息:
  
  線程 ID: 企業級的應用程序通常都是在多線程的環境中運行的。使用線程 ID 信息,您就可以將多個請求區分開來。
  
  調用程序的標識: 調用程序的標識也是非常重要的信息。由于不同的用戶具有不同的特權,它們的執行路徑也可能會有很大的不同。將用戶的標識放到日志消息中,這對于對安全性敏感的應用程序是非常大的一個幫助。
  
  時間戳: 通常來說,用戶只能近似地知道問題發生的時間。假如沒有時間戳,就很難讓別人來判定問題的原因所在。
  
  源代碼信息: 這包括類名、方法名和行號。除非您非常關注安全性,否則我建議您保留調試標記(-g),即使在編譯產品時也是如此。假如沒有調試標記,Java 編譯器就會刪除所有的行號信息,從而極大地減少日志消息的可用性。
  
  上面這些信息(除了調用程序標識)都是由日志實現自動獲取的。為了將這些信息包含到消息中,您只需要為輸出處理程序配置一個適當的 layout 模式即可。要捕捉調用者的標識,您可以利用 Log4J 中的診斷上下文特性(更多信息請參閱 參考資料)。診斷上下文讓您可以將上下文信息與當前正在運行的線程關聯在一起。這些信息可以在為輸出進行格式化的同時而包含到每條消息中。
  
  在 J2EE Web 應用程序中,應用邏輯將用戶標識保存到診斷上下文中最好的地方是在一個 servlet 過濾器中。清單 4 中顯示了要實現這種功能的必要代碼。它使用了 Log4J 1.3 alpha 中提供的映射診斷上下文類(MDC)。您可以使用 Log4J 1.2 中提供的嵌套診斷上下文(NDC)實現相同的功能。有關 servlet 過濾器的更多通用信息,請參閱 參考資料 中的信息。
  
  清單 4. 在 servlet 過濾器中使用診斷上下文

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洛扎县| 宝兴县| 金塔县| 射阳县| 神农架林区| 北宁市| 克山县| 三门峡市| 崇仁县| 特克斯县| 盘山县| 抚州市| 织金县| 平顶山市| 麻江县| 滕州市| 宁河县| 新竹县| 甘孜县| 河池市| 宁强县| 龙门县| 信阳市| 延边| 扶沟县| 吉首市| 阳春市| 富源县| 康乐县| 万全县| 台州市| 公安县| 卓资县| 宜丰县| 福州市| 天气| 宁津县| 星子县| 新绛县| 枣庄市| 崇明县|