Trace 日志文件


日志,又稱為 Log,是我們開發人員的又一利器,其實,不管是在調試還是測試的時候,日志都可以幫助我們解決問題,不過,很多的程序員迷戀於調試器,而忽視了日志。尤其是在測試驅動的開發中,日志更是我們的得力助手。
所謂的日志,其實是一種記錄機制,允許我們在程序代碼中插入一些特殊的輸出代碼,將程序當前的運行狀態隨時輸出,以便於在無人值守的情況下記錄信息,在事后對程序的處理過程進行分析。

最簡單的日志就是直接通過 Console 來輸出,或者使用 alert, 或者 MessageBox 來輸出,沒准你就使用過這些手法。這些方法會給程序帶來副作用,在開發完成之后,往往需要你手工刪除。不刪除的話會造成程序的效率問題。要是又發現有新的問題存在呢?是不是又要再來一遍?這可是開發人員的噩夢呀!

一個完善的日志系統絕不是簡單地在控制台輸出,它至少需要支持下面的幾個特征:

  • 使用一種方式就支持輸出到多個目的地,例如:控制台,文本文件,數據庫,甚至電子郵件等等。
  • 允許控制輸出的級別,過濾輸出的內容,而不需要大幅度修改日志程序
  • 使用簡單,可以使用簡單的語法來記錄日志

目前,存在着多個成熟的日志系統供我們選擇,在 .NET 開發平台上,主要有兩個日志系統:.NET 平台直接支持的日志系統和開源的 Log4Net。

今天,我們先看看 .NET 平台內置的日志系統。

這里我們首先了解三個概念:

  • 日志器:用來發送日志,在開發中,主要是用日志器來輸出日志信息。
  • 監聽器:日志器用來輸出日志信息,日志信息輸出到哪里呢? 監聽器用來完成實際的日志記錄功能,在日志系統中,存在多種監聽器,用來將日志信息記錄到不同的目的地。
  • 日志控制開關:在軟件生命周期的不同階段,我們需要不同的日志信息,在開發階段,可能需要比較詳細的日志來檢查錯誤,在運行階段,大部分的問題已經被處理,我們可能僅僅需要記錄一些關鍵信息,通過控制開關,可以在不需要修改代碼的情況下,調整日志輸出的內容。

在 .NET 中,關於日志處理的相關類型,定義在命名空間 System.Diagnostics 中,有兩個預定義的日志器類型,Debug 和 Trace。
這兩個日志記錄器的工作機制是相同的,區別僅僅在於 Debug 僅僅在編譯器定義了 DEBUG 常量的情況下工作,而 Trace 僅僅在定義了 TRACE 常量的情況下工作,默認情況下,當 我們使用 Debug 模式編譯的時候,默認已經定義了這兩個常量。所以,不管使用 Debug 還是 Trace 都可以輸出日志信息。如果我們將程序編譯為發布模式,那么,將僅僅定義 TRACE 常量,導致忽略 Debug 的存在,只記錄 Trace 的日志信息。

我們先看一看監聽器,以便能夠看到輸出的日志信息。
所有的監聽器都要從 TraceListener  派生,這是定義在命名空間 System.Diagnostics 中的一個抽象基類。通常我們直接使用系統的一些派生類。

?
System.Diagnostics.DefaultTraceListener
System.Diagnostics.Eventing.EventProviderTraceListener
System.Diagnostics.EventLogTraceListener
System.Diagnostics.TextWriterTraceListener
System.Web.WebPageTraceListener

作為文本格式的日志, System.Diagnostics.TextWriterTraceListener 又有幾個常用的派生類

?
System.Diagnostics.ConsoleTraceListener
System.Diagnostics.DelimitedListTraceListener
System.Diagnostics.EventSchemaTraceListener
System.Diagnostics.XmlWriterTraceListener


Debug 和 Trace 使用相同的監聽器,默認情況下,在它們的監聽器集合屬性 Listeners 中,已經添加了一個 System.Diagnostics.DefaultTraceListener 的實例,以便輸出到 Visual Studio 的 Output 窗口中,所以,在使用了日志之后,我們可以打開 Output 窗口來看看實際的輸出。如果我們希望能夠在控制台窗口中看到輸出,那么只需要增加一個 ConsoleTraceListener 就可以了。

?
// 增加一個可以輸出到控制台的 Listener
System.Diagnostics.Trace.Listeners.Add(
     new System.Diagnostics.ConsoleTraceListener()
     );

當然,在實際的開發中,我們可能需要的是一個文本文件,現在,你還需要提供一個文件名了。

?
System.Diagnostics.Trace.Listeners.Add(
     new System.Diagnostics.TextWriterTraceListener( "log.txt" )
     );

這些監聽器也可以不在程序中固定聲明,而是通過配置文件來更加方便地定義。這樣的話,我們就可以動態地修改監聽器,而不需要修改我們的代碼了。
在程序的配置文件中,配置節 system.diagnostics 用來定義日志的配置參數,其子元素 trace 定義日志的參數,trace 的子元素 listeners 定義日志的監聽器。我們可以通過下面的配置參數來增加一個文件的監聽器。其中的 initializeData 用來配置文件名。

?
< add name = "fileListener"
         type = "System.Diagnostics.TextWriterTraceListener"
         initializeData = "log.txt" />

當監聽器配置好之后,就可以使用日志器輸出日志了。不管是 Debug 還是 Trace 都提供了多個方法來輸出日志。
最簡單的方式就是使用 WriteLine 來輸出日志,就跟使用 Console 一樣。
不過,對於日志來說,存在的一個問題就是,我們並不總想輸出所有的日志,比如程序已經經過測試,我們可能並不需要大量的日志信息來干擾我們,怎么減少實際輸出的日志呢?修改程序當然不是一個好主意,我們可以通過條件輸出來限制輸出的日志內容,僅僅在某種條件下,才輸出日志,通過 WriteLineIf ,我們可以指定一個條件,僅僅當條件滿足的時候,才會輸出日志。

條件僅僅是一個條件,什么樣的條件都可以,只要你需要。

為了方便使用,在 .NET 中又提供了一個日志的開關,來方便我們指定條件,所謂日志的開關其實就是一個從 0 到 4 的整數,通過一個枚舉 TraceLevel 來方便使用這個整數

  • 0. 關閉,不希望輸出日志
  • 1. 錯誤級別的日志
  • 2. 建議輸出錯誤和警告級別的日志
  • 3. 一般信息的日志也輸出
  • 4. 詳細日志

不過,實際上輸出什么日志還是看你的日志輸出語句,你在日志輸出語句中可以通過這個開關來判斷該不該輸出。

那么,這個開關從哪里取得呢?還是配置文件。在配置文件的 system.diagnostics 中,子元素 switches 用來配置一個日志級別,你需要為你的級別起一個名字,以便在程序中

取得這個設置。

?
< add name = "traceSwitch" value = "0" />

在程序中,你可以這樣取得配置文件中日志的開關

?
System.Diagnostics.TraceSwitch myTraceSwitch =
     new System.Diagnostics.TraceSwitch("traceSwitch", string.Empty);

在程序中,你可以通過這個開關的設置來決定輸出什么,配合開關的級別,在 Trace 中又提供了幾個匹配的方法

?
System.Diagnostics.Trace.TraceError("Error!!!");
System.Diagnostics.Trace.TraceWarning("Warning!!!");

當然,它們僅僅用來輸出分類的日志,注意,判斷是否輸出是你的事情,所以,程序的代碼往往如下:

?
if( myTraceSwitch.TraceError)
     System.Diagnostics.Trace.TraceError("Error!!!");
  
if( myTraceSwitch.TraceWarning)
     System.Diagnostics.Trace.TraceWarning("Warning!!!");


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM