ここでは、.NET Framework 2.0から追加されたTraceSourceクラスを使ってトレースする方法を紹介します。.NET Framework 1.1以前は、こちらやこちらのように、TraceとDebugを使用してトレースを行いましたが、.NET Framework 2.0ではTraceSourceを使用したトレースが推奨されています。
早速ですが、TraceSourceを使った簡単な例を示します。以下のコードでは、Button1をクリックしたときに、指定したメッセージがVisual Studioの出力ウィンドウに表示されます。
'TraceSourceの作成 Private Shared appTrace As New System.Diagnostics.TraceSource("MainTraceSource") '次のようにソースレベルを指定して作成することもできる '指定しないと、Offになる 'Private Shared appTrace As New System.Diagnostics.TraceSource( _ ' "MainTraceSource", System.Diagnostics.SourceLevels.Error) 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click 'ソースレベルを変更する 'Error以上のイベントが通過されるようにする appTrace.Switch.Level = System.Diagnostics.SourceLevels.Error 'Warningイベントを書き込む 'ソースレベルがErrorなので、出力されない appTrace.TraceEvent(System.Diagnostics.TraceEventType.Warning, 0, "警告") 'Criticalイベントを書き込む 'ソースレベルがErrorなので、出力される appTrace.TraceEvent(System.Diagnostics.TraceEventType.Critical, 1, "重大") 'フラッシュする appTrace.Flush() End Sub
//TraceSourceの作成 private static System.Diagnostics.TraceSource appTrace = new System.Diagnostics.TraceSource("MainTraceSource"); //次のようにソースレベルを指定して作成することもできる //指定しないと、Offになる //private static System.Diagnostics.TraceSource appTrace = // new System.Diagnostics.TraceSource("TraceSource1", // System.Diagnostics.SourceLevels.Error); //Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { //ソースレベルを変更する //Error以上のイベントが通過されるようにする appTrace.Switch.Level = System.Diagnostics.SourceLevels.Error; //Warningイベントを書き込む //ソースレベルがErrorなので、出力されない appTrace.TraceEvent(System.Diagnostics.TraceEventType.Warning, 0, "警告"); //Criticalイベントを書き込む //ソースレベルがErrorなので、出力される appTrace.TraceEvent(System.Diagnostics.TraceEventType.Critical, 1, "重大"); //フラッシュする appTrace.Flush(); }
上記のコードを実行すると、Visual Studioの出力ウィンドウに次のように出力されます。
MainTraceSource Critical: 1 : 重大
上記のコードでは、TraceSourceのスイッチレベルをErrorにしています。これにより、CriticalかErrorのイベントしか出力されなくなります。つまり上記のように、Warningでは表示されず、Criticalでは表示されます。
TraceSourceのスイッチレベルに指定できるSourceLevels列挙体のメンバの意味は、次のようなものです(ヘルプの「SourceLevels 列挙体」より抜粋)。
SourceLevels列挙体のメンバ名 | 説明 |
---|---|
ActivityTracing | Stop、Start、Suspend、Transfer、および Resume の各イベントを通過させます。 |
All | すべてのイベントを通過させます。 |
Critical | Critical イベントのみを通過させます。 |
Error | Critical イベントおよび Error イベントを通過させます。 |
Information | Critical、Error、Warning、および Information の各イベントを通過させます。 |
Off | いずれのイベントも通過させません。 |
Verbose | Critical、Error、Warning、Information、および Verbose の各イベントを通過させます。 |
Warning | Critical、Error、および Warning の各イベントを通過させます。 |
TraceEventメソッドの第1引数に指定できるTraceEventType構造体のメンバの意味は、次のようなのもです(ヘルプの「TraceEventType 列挙体」からの抜粋)。
TraceEventType列挙体のメンバ | 説明 |
---|---|
Critical | 致命的なエラーまたはアプリケーションのクラッシュ。 |
Error | 回復可能なエラー。 |
Information | 情報メッセージ。 |
Resume | 論理演算の再開。 |
Start | 論理演算の開始。 |
Stop | 論理演算の停止。 |
Suspend | 論理演算の中断。 |
Transfer | 相関 ID の変更。 |
Verbose | トレースのデバッグ。 |
Warning | 重大でない問題。 |
補足:TraceEventメソッドの第2引数に指定する数字は、イベントのIDです。ここで指定できる数字の最大値は65,535です。それ以上を指定すると、65,535になります。
補足:イベントの種類を"Information"、IDを"0"としてメッセージを書き込むには、TraceEventメソッドの代わりにTraceInformationを使うと便利です。
また、イベントの種類を"Transfer"としてTraceEventメソッドを呼び出す代わりに、TraceTransferメソッドを使うこともできます。
トレースソースで使用されるリスナは、デフォルトでDefaultTraceListenerです。トレースソースにリスナを追加する方法は、「TraceやDebugのWriteメソッドでファイルに出力する」で紹介している方法とほぼ同じです。リスナに関する簡単な説明や、使用できるリスナの種類等もそちらで説明いています。
以下にTextWriterTraceListenerを追加し、テキストファイルに出力する例を示します。
'TraceSourceの作成 Private Shared appTrace As New System.Diagnostics.TraceSource("MainTraceSource") 'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles MyBase.Load 'DefaultTraceListenerが必要なければ削除する appTrace.Listeners.Remove("Default") '出力先ファイルを C:\test.txt、名前を LogFile として 'TextWriterTraceListenerオブジェクトを作成 Dim twtl As New System.Diagnostics.TextWriterTraceListener( _ "C:\test.txt", "LogFile") 'リスナコレクションに追加する appTrace.Listeners.Add(twtl) End Sub
//TraceSourceの作成 private static System.Diagnostics.TraceSource appTrace = new System.Diagnostics.TraceSource("MainTraceSource"); //フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { //DefaultTraceListenerが必要なければ削除する appTrace.Listeners.Remove("Default"); //出力先ファイルを C:\test.txt、名前を LogFile として //TextWriterTraceListenerオブジェクトを作成 System.Diagnostics.TextWriterTraceListener twtl = new System.Diagnostics.TextWriterTraceListener( "C:\\test.txt", "LogFile"); //リスナコレクションに追加する appTrace.Listeners.Add(twtl); }
通常は、TraceSource.Switch.Levelで指定されたレベルに応じて、TraceSourceに追加されているリスナがメッセージを出力するかしないか制御されます。しかし、リスナ毎に別のレベルを設定したい場合もあるでしょう。そのような時は、リスナのFilterプロパティにEventTypeFilterオブジェクトを設定します。
ただし、はじめにTraceSource.Switch.Levelで指定されたレベルを通過したイベントが、リスナのFilterでさらに審査されるという方式ですので、リスナのFilterがTraceSource.Switch.Levelよりも低いレベルでは意味がありません。完全にそれぞれのリスナのFilterによって判断されるようにするには、TraceSource.Switch.LevelにAllを指定すればよいでしょう。
"Default"リスナのレベルをErrorにする例を以下に示します。
Private Shared appTrace As New System.Diagnostics.TraceSource("MainTraceSource") 'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles MyBase.Load 'ソースレベルを変更する 'すべてのイベントが通過されるようにする appTrace.Switch.Level = System.Diagnostics.SourceLevels.All 'DefaultリスナのレベルをErrorにする appTrace.Listeners("Default").Filter = _ New System.Diagnostics.EventTypeFilter( _ System.Diagnostics.SourceLevels.Error) End Sub
//TraceSourceの作成 private static System.Diagnostics.TraceSource appTrace = new System.Diagnostics.TraceSource("MainTraceSource"); //フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { //ソースレベルを変更する //すべてのイベントが通過されるようにする appTrace.Switch.Level = System.Diagnostics.SourceLevels.All; //DefaultリスナのレベルをErrorにする appTrace.Listeners["Default"].Filter = new System.Diagnostics.EventTypeFilter( System.Diagnostics.SourceLevels.Error); }
これまではTraceSourceの作成、設定の変更、リスナの追加などすべてコードで行いましたが、アプリケーション構成ファイルに記述することによっても可能です。むしろ、こちらの方法が推奨されています。なお、アプリケーション構成ファイルについては、こちらをご覧ください。
まずは簡単な例です。"MainTraceSource"という名前のトレースソースのスイッチのレベルをWarningにしています。このようにすると、一番はじめに紹介したコードのように、TraceSource.Switch.Levelを指定する必要がなくなります。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <sources> <source name="MainTraceSource" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch"/> </sources> <switches> <add name="sourceSwitch" value="Warning"/> </switches> </system.diagnostics> </configuration>
リスナを追加する方法は、こちらで紹介している方法とほぼ同じです。ここではこれに加えて、リスナのFilterも指定します。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <sources> <source name="MainTraceSource" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="LogFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\test.txt"> <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"/> </add> <remove name="Default"/> </listeners> </source> </sources> <switches> <add name="sourceSwitch" value="Warning"/> </switches> </system.diagnostics> </configuration>
複数のTraceやTraceSourceで同じリスナを使う場合は、<sharedListeners>要素を使うと便利です。ここに共有するリスナを記述しておき、source要素でその名前だけを指定してリスナを追加できます。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <sources> <source name="MainTraceSource" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="LogFile"/> <remove name="Default"/> </listeners> </source> </sources> <switches> <add name="sourceSwitch" value="Warning"/> </switches> <sharedListeners> <add name="LogFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\test.txt"> <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"/> </add> </sharedListeners> </system.diagnostics> </configuration>
.NET Framework 2.0で使用できるリスナをアプリケーション構成ファイルによりTraceSourceに追加する例を示します。アプリケーション構成ファイルを以下のようにして、listeners要素内の使用したいリスナのコメントアウトを元に戻すだけです。ログを書き込む位置などは適当に書き換えてください。(こちらを参考にして作成しました。)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <sources> <source name="MainTraceSource" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch"> <listeners> <!-- <add name="EventLog" /> --> <!-- <add name="TextLog" /> --> <!-- <add name="Delimited" /> --> <!-- <add name="XmlWriter" /> --> <!-- <add name="Console" /> --> <!-- <add name="FileLog" /> --> </listeners> </source> </sources> <switches> <add name="sourceSwitch" value="Warning"/> </switches> <sharedListeners> <add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="sample application" /> <add name="TextLog" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\TextLog.txt" /> <add name="Delimited" type="System.Diagnostics.DelimitedListTraceListener" initializeData="C:\DelimitedLog.txt" delimiter="," traceOutputOptions="DateTime" /> <add name="XmlWriter" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Log.xml" /> <add name="Console" type="System.Diagnostics.ConsoleTraceListener" initializeData="true" /> <add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener" initializeData="FileLogWriter" /> </sharedListeners> </system.diagnostics> </configuration>