Trace、Debug和TraceSource的使用以及日誌設計編程
.NET Framework 命名空間 System.Diagnostics 包含用於跟蹤執行流程的 Trace、Debug 和 TraceSource 類,以及用於分析代碼的 Process、EventLog 和 PerformanceCounter 類。windows
跟蹤是一種在應用程序運行時監視其執行狀況的方式。當開發 .NET Framework 應用程序時,能夠在其中添加跟蹤和調試檢測功能,而且在開發應用程序時和部署應用程序後,均可以使用該檢測功能。利用 Trace 和 Debug 類,能夠將有關錯誤和應用程序執行的信息記錄到日誌、文本文件或其餘設備中,以便在隨後進行分析。app
下面列出了六個寫入跟蹤信息的 Debug Members 和 Trace 方法。less
Assert:指定的文本;若是未指定任何文本,則爲「調用堆棧」。只有當 Assert 語句中以參數形式指定的條件爲 false 時,纔會寫入輸出。ide
Fail:指定的文本;若是未指定任何文本,則爲「調用堆棧」。函數
Write:指定的文本。post
WriteIf:若是知足 WriteIf 語句中以參數形式指定的條件,則爲指定的文本。spa
WriteLine:指定的文本和一個回車。設計
WriteLineIf:若是知足 WriteLineIf 語句中以參數形式指定的條件,則爲指定的文本和一個回車。調試
1:Trace 和 Debug區別
Trace 和 Debug 類基本相同,不一樣的只是 Trace 類的過程和函數默認爲編譯成發佈版本。
2:什麼是Listeners
Listenters屬性,它是TraceListenerCollection類型(TraceSource類和TraceListener類),給類屬性控制跟蹤信息輸出的方向,能夠是控制檯(add(TextWriterTraceListener(newConsole.Out))),文件(add(TextWriterTraceListener(newIO.File.CreateText(「output.txt」))等。Listenters集合中的成員包括TextWriterTraceListener,DefaultTraceListener,EventLogTraceListener,WebPageTraceListener等。而TextWriterTraceListener的子類又有ConsoleTraceListener, DelimitedListTraceListener,XmlWriterTraceListener,EventSchemaTraceListener。
您能夠經過實現您本身的偵聽器來生成自定義的結果。 全部自定義偵聽器都應支持文章開頭表中的六個方法。
如下的例子說明輸出的消息將會在控制檯、TXT文件以及系統日誌中均被記錄。
TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(tr1);
TextWriterTraceListener tr2 = newTextWriterTraceListener(System.IO.File.CreateText("output.txt"));
Debug.Listeners.Add(tr2);
EventLogTraceListener tr3 = newEventLogTraceListener();
Debug.Listeners.Add(tr3);
3:跟蹤開關
除了指定Listener外,要控制消息是否被輸出,還須要指定跟蹤開關。跟蹤開關用於啓用、禁用和篩選跟蹤輸出。
Framework 中提供了三種類型的跟蹤開關:BooleanSwitch 類、TraceSwitch 類和 SourceSwitch 類。BooleanSwitch是最簡單的跟蹤開關,能夠指定是否輸出消息。TraceSwitch 和 SourceSwitch 類用於爲特定的跟蹤級別啓用跟蹤開關,以便顯示爲該級別及其下的全部級別指定的 Trace 或 TraceSource 消息。
3.1:使用BooleanSwitch開關
如下是使用BooleanSwitch的例子:
TextWriterTraceListenertr1 = newTextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(tr1);
TextWriterTraceListenertr2 = new TextWriterTraceListener(System.IO.File.CreateText("output.txt"));
Debug.Listeners.Add(tr2);
EventLogTraceListenertr3 = new EventLogTraceListener();
Debug.Listeners.Add(tr3);
bool someBizCondition = true;
BooleanSwitch bs = new BooleanSwitch("DataMessageSwitch", "DataMessageSwitch des");
bs.Enabled = true;
Debug.WriteLineIf(someBizCondition, "log....");
Debug.Flush();
bs.Enabled設置爲true或者false,並不會使程序自動決定是否輸出信息。
若是不使用代碼方式,而是使用配置文件的方式,是在<configuration> 標記以後,但在</configuration> 標記以前添加相應的 XML 來配置您的開關。以下:
<system.diagnostics>
<switches>
<add name="DataMessagesSwitch" value="1" />
</switches>
</system.diagnostics>
3.2:使用TraceSwitch開關
TraceSwitch類能夠經過使用跟蹤開關來篩選消息,經過Level屬性來獲取或設置開關級別。0、一、二、3 和 4 分別對應於 Off、Error、Warning、Info 和 Verbose。任何大於 4 的數字都會被看成 Verbose,任何小於零的數字都會被看成 Off。
如下的例子,用代碼的方式來演示使用TraceSwitch來設置跟蹤開關:
TextWriterTraceListenertr1 = new TextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(tr1);
TextWriterTraceListenertr2 = newTextWriterTraceListener(System.IO.File.CreateText("output.txt"));
Debug.Listeners.Add(tr2);
EventLogTraceListenertr3 = new EventLogTraceListener();
Debug.Listeners.Add(tr3);
bool someBizCondition = true;
TraceSwitch ts = new TraceSwitch("mySwitch", "in the Config file");
ts.Level =TraceLevel.Verbose;
Debug.WriteLineIf(ts.TraceError&& someBizCondition, "Error!!!");
Debug.WriteLineIf(ts.TraceWarning && someBizCondition, "Warning!!!");
Debug.WriteLineIf(ts.TraceInfo && someBizCondition, "Info!!!");
Debug.WriteLineIf(ts.TraceVerbose&& someBizCondition, "Verbose!!!");
Debug.Flush();
使用XML來配置,以下:
<system.diagnostics>
<switches>
<add name="mySwitch" value="1" />
</switches>
</system.diagnostics>
4:使用TraceSource代替Trace和Debug
從FRAMEWORK2.0開始,就不建議使用Trace和Debug了,而改而用TraceSouce。TraceSource 旨在用做加強的跟蹤系統,而且可代替較舊的 Trace 和 Debug 跟蹤類的靜態方法使用。熟悉的 Trace 和 Debug 類仍然存在,不過建議的作法是使用 TraceSource 類進行跟蹤。
下面的例子演示使用代碼來實現消息的輸出:
private static TraceSource mySource = new TraceSource("TraceSourceApp");
static void Main(string[] args)
{
mySource.Switch = new SourceSwitch("sourceSwitch", "Error");
mySource.Listeners.Remove("Default");
TextWriterTraceListenertextListener = new TextWriterTraceListener("myListener.log");
textListener.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Callstack;
textListener.Filter = new EventTypeFilter(SourceLevels.Error);
mySource.Listeners.Add(textListener);
ConsoleTraceListenerconsole = new ConsoleTraceListener(false);
console.Filter = newEventTypeFilter(SourceLevels.Information);
console.Name = "console";
mySource.Listeners.Add(console);
Activity1();
// Set the filter settings for the
// console trace listener.
mySource.Listeners["console"].Filter = new EventTypeFilter(SourceLevels.Critical);
Activity2();
// Allow the trace source to send messagesto
// listeners for all event types.
mySource.Switch.Level = SourceLevels.All;
// Change the filter settings for theconsole trace listener.
mySource.Listeners["console"].Filter = newEventTypeFilter(SourceLevels.Information);
Activity3();
mySource.Close();
return;
}
static void Activity1()
{
mySource.TraceEvent(TraceEventType.Error, 1, "Error message.");
mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message.");
}
static void Activity2()
{
mySource.TraceEvent(TraceEventType.Critical, 3, "Critical message.");
mySource.TraceInformation("Informational message.");
}
static void Activity3()
{
mySource.TraceEvent(TraceEventType.Error, 4, "Error message.");
mySource.TraceInformation("Informational message.");
}
以上代碼,若是使用配置文件的方式實現,以下:
<system.diagnostics>
<sources>
<source name="TraceSourceApp" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="console" type="System.Diagnostics.ConsoleTraceListener">
<filter type="System.Diagnostics.EventTypeFilter" initializeData="Warning"/>
</add>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="myListener.log"
traceOutputOptions="Callstack">
<filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"></filter>
</add>
<remove name="Default"/>
</listeners>
</source>
</sources>
<switches>
<add name="sourceSwitch" value="Warning"/>
</switches>
</system.diagnostics>
配置文件實現的對應代碼部分爲:
private static TraceSource mySource = new TraceSource("TraceSourceApp");
static void Main(string[] args)
{
Activity1();
Activity2();
Activity3();
mySource.Close();
return;
}
static void Activity1()
{
mySource.TraceEvent(TraceEventType.Error, 1, "Error message.");
mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message.");
}
static void Activity2()
{
mySource.TraceEvent(TraceEventType.Critical, 3, "Critical message.");
mySource.TraceInformation("Informational message.");
}
static void Activity3()
{
mySource.TraceEvent(TraceEventType.Error, 4, "Error message.");
mySource.TraceInformation("Informational message.");
}
5:設計一個日誌系統
有了以上的知識以後,咱們就能夠來設計一個應用程序的日誌系統(是的,咱們不在須要LOG4NET)。咱們來假設這個日誌系統最基礎的功能:
一、以日期來建立日誌名,以避免歷史日誌所有寫入一個文件中去;
二、能夠配置想要輸出的日誌類別,如Warning或者Error等;
三、能夠配置想要的日誌內容:如StackTrace或者錯誤信息等;
思路:
一、在應用程序啓動代碼中,設置文件名。由於文件名要根據日期動態生成,因此不能使用配置文件;
二、其它配置能夠配置文件實現;
三、DO IT;
6:關於EventLog
EventLog 類提供了C#與Windows事件日誌交互的功能。 不少時候咱們能夠把日誌寫到windows事件日誌中.
說明:EventLog 使您能夠訪問或自定義Windows 事件日誌。經過C#提供的EventLog類,能夠讀取現有日誌,向日志中寫入項,建立或刪除事件源,刪除日誌,以及響應日誌項。也可在建立事件源時建立新日誌。
打開Windows事件日誌的方法
右擊個人電腦->管理->事件日誌就能夠了.
CreateEventSource
已重載。 創建一個可以將事件信息寫入到系統的特定日誌中的應用程序。
Delete
已重載。 移除日誌資源。
DeleteEventSource
已重載。 從事件日誌中移除應用程序的事件源註冊。
SourceExist
已重載。 在計算機的註冊表中搜索給定的事件源。
WriteEntry
已重載。 將項寫入事件日誌。
WriteEvent
已重載。 向事件日誌寫入本地化事件項。
爲了可以使用EventLog,咱們須要引入usingSystem.Diagnostics命令空間.下面兩個方法在你捕獲到異常或其餘時能夠調用.
privatevoid WriteError(string sText)
{
if (!EventLog.SourceExists(sEventSource))
EventLog.CreateEventSource(sEventSource, sEventLog);
EventLog.WriteEntry(sEventSource,sText, EventLogEntryType.Error);
}
privatevoid WriteInfo(string sText)
{
if (!EventLog.SourceExists(sEventSource))
EventLog.CreateEventSource(sEventSource, sEventLog);
EventLog.WriteEntry(sEventSource,sText, EventLogEntryType.Information);
}
下面是一個簡單使用的例子.
try
{
//操做
}
catch(Excepetionex)
{
WriteError(ex.message);
}
這樣咱們就能夠成功的寫入到Windows事件中..:)
EventLog(事件日誌)的讀寫方法
在C#中讀寫EventLog(事件日誌)挺簡單的,代碼量也比較小。
1.加入System.DiagnosticsName Space;
usingSystem.Diagnostics;
2.聲明一個EventLog類的實例。
EventLogeventLog;
eventLog=newEventLog("TestEvent",".","mySource");
"TestEvent"是創建一個新的EventLog名,
".": 表示本機
"mySource": 源名
若是以上不設參數,就默認爲"Application"
設好之後,就能夠讀寫了。
寫:
eventLog.Source="mySource";
eventLog.WriteEntry("Log text");
MessageBox.Show("Write Complete!")
讀:
lstEvent.Items.Clear();
eventLog.Log="TestEvent";
foreach(EventLogEntry eventlogEntry in eventLog.Entries)
{
lstEvent.Items.Add(eventlogEntry.Message);
}
關於EventLog更多內容,可參考:http://msdn.microsoft.com/zh-cn/library/aaaxk5bx(VS.80).aspx
7: 如何建立和初始化跟蹤源
使用配置文件建立和初始化跟蹤源
1. Create a VisualStudio console application project and replace the supplied code with thefollowing code.
using System;
using System.Diagnostics;
class TraceTest
{
private static TraceSource mySource =
new TraceSource("TraceSourceApp");
static void Main(string[] args)
{
// Issue an error and a warningmessage. Only the error message
// should be logged.
Activity1();
// Save the original settings from theconfiguration file.
EventTypeFilter configFilter =
(EventTypeFilter)mySource.Listeners["console"].Filter;
// Create a new event type filter thatensures
// warning messages will be written.
mySource.Listeners["console"].Filter =
newEventTypeFilter(SourceLevels.Warning);
// Allow the trace source to sendmessages to listeners
// for all event types. This statementwill override
// any settings in the configurationfile.
// If you do not change the switchlevel, the event filter
// changes have no effect.
mySource.Switch.Level = SourceLevels.All;
// Issue a warning and a criticalmessage. Both should be logged.
Activity2();
// Restore the original filtersettings.
mySource.Listeners["console"].Filter = configFilter;
Activity3();
mySource.Close();
return;
}
static void Activity1()
{
mySource.TraceEvent(TraceEventType.Error, 1,
"Error message.");
mySource.TraceEvent(TraceEventType.Warning, 2,
"Warning message.");
}
static void Activity2()
{
mySource.TraceEvent(TraceEventType.Critical, 3,
"Critical message.");
mySource.TraceEvent(TraceEventType.Warning, 2,
"Warning message.");
}
static void Activity3()
{
mySource.TraceEvent(TraceEventType.Error, 4,
"Error message.");
mySource.TraceInformation("Informationalmessage.");
}
}
2. Add an applicationconfiguration file to the project to initialize the trace source named TraceSourceApp in the code examplein step 1.
3. 初始化控制檯跟蹤偵聽器和文本編寫器跟蹤偵聽器的跟蹤源的步驟 1 中建立如下設置替換默認的配置文件設置。
<configuration>
<system.diagnostics>
<sources>
<sourcename="TraceSourceApp"
switchName="sourceSwitch"
switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="console"
type="System.Diagnostics.ConsoleTraceListener">
<filtertype="System.Diagnostics.EventTypeFilter"
initializeData="Error"/>
</add>
<addname="myListener"/>
<removename="Default"/>
</listeners>
</source>
</sources>
<switches>
<add name="sourceSwitch"value="Error"/>
</switches>
<sharedListeners>
<add name="myListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="myListener.log">
<filter type="System.Diagnostics.EventTypeFilter"
initializeData="Error"/>
</add>
</sharedListeners>
</system.diagnostics>
</configuration>
除了配置跟蹤偵聽器,配置文件的兩個偵聽器建立篩選器,並建立一個源開關的跟蹤源。其中演示了兩種添加跟蹤偵聽器的技術:將偵聽器直接添加到跟蹤源,以及將偵聽器添加到共享的偵聽器集合,而後按名稱將它添加到跟蹤源。爲這兩個偵聽器標識的篩選器用不一樣的源級別進行初始化。這樣致使某些消息僅由其中一個偵聽器編寫。
配置文件在初始化應用程序時初始化跟蹤源的設置。應用程序能夠動態更改配置文件設置的屬性,以重寫用戶指定的任何設置。例如對於您可能但願確保重要的郵件始終發送到一個文本文件而不考慮當前的配置設置。該代碼示例演示如何重寫配置文件設置,以確保重要郵件的跟蹤偵聽器的輸出。
在應用程序執行時更改配置文件設置不會更改初始設置。若要將該設置必須從新啓動該應用程序或以編程方式刷新應用程序,經過使用Trace.Refresh方法。
不使用配置文件初始化跟蹤源、偵聽器和篩選器
· 使用下面的代碼示例不使用配置文件啓用跟蹤源跟蹤。這不是建議的作法,但可能在其中您不想依賴於配置文件,以確保跟蹤的狀況。
using System;
using System.Diagnostics;
using System.Threading;
namespace TraceSourceApp
{
class Program
{
private static TraceSource mySource =
new TraceSource("TraceSourceApp");
static void Main(string[] args)
{
mySource.Switch = new SourceSwitch("sourceSwitch", "Error");
mySource.Listeners.Remove("Default");
TextWriterTraceListenertextListener =
new TextWriterTraceListener("myListener.log");
ConsoleTraceListener console =
new ConsoleTraceListener(false);
console.Filter =
newEventTypeFilter(SourceLevels.Information);
console.Name = "console";
textListener.Filter =
new EventTypeFilter(SourceLevels.Error);
mySource.Listeners.Add(console);
mySource.Listeners.Add(textListener);
Activity1();
// Allow the trace source to sendmessages to
// listeners for all event types.Currently only
// error messages or higher go to thelisteners.
// Messages must get past the sourceswitch to
// get to the listeners, regardless ofthe settings
// for the listeners.
mySource.Switch.Level =SourceLevels.All;
// Set the filter settings for the
// console trace listener.
mySource.Listeners["console"].Filter =
newEventTypeFilter(SourceLevels.Critical);
Activity2();
// Change the filter settings for theconsole trace listener.
mySource.Listeners["console"].Filter =
new EventTypeFilter(SourceLevels.Information);
Activity3();
mySource.Close();
return;
}
static void Activity1()
{
mySource.TraceEvent(TraceEventType.Error, 1,
"Error message.");
mySource.TraceEvent(TraceEventType.Warning,2,
"Warning message.");
}
static void Activity2()
{
mySource.TraceEvent(TraceEventType.Critical, 3,
"Critical message.");
mySource.TraceInformation("Informationalmessage.");
}
static void Activity3()
{
mySource.TraceEvent(TraceEventType.Error, 4,
"Error message.");
mySource.TraceInformation("Informationalmessage.");
}
}
}