DOBON.NET

TraceSourceを使用してトレースする、ログに書き込む

注意:ここで紹介する方法は、.NET Framework 2.0以降で有効です。それ以外では、こちらこちらのように、TraceとDebugを使用するようにします。

ここでは、.NET Framework 2.0から追加されたTraceSourceクラスを使ってトレースする方法を紹介します。.NET Framework 1.1以前は、こちらこちらのように、TraceとDebugを使用してトレースを行いましたが、.NET Framework 2.0ではTraceSourceを使用したトレースが推奨されています。

早速ですが、TraceSourceを使った簡単な例を示します。以下のコードでは、Button1をクリックしたときに、指定したメッセージがVisual Studioの出力ウィンドウに表示されます。

VB.NET
コードを隠すコードを選択
'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
C#
コードを隠すコードを選択
//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列挙体のメンバ名説明
ActivityTracingStop、Start、Suspend、Transfer、および Resume の各イベントを通過させます。
Allすべてのイベントを通過させます。
CriticalCritical イベントのみを通過させます。
ErrorCritical イベントおよび Error イベントを通過させます。
InformationCritical、Error、Warning、および Information の各イベントを通過させます。
Offいずれのイベントも通過させません。
VerboseCritical、Error、Warning、Information、および Verbose の各イベントを通過させます。
WarningCritical、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を追加し、テキストファイルに出力する例を示します。

VB.NET
コードを隠すコードを選択
'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
C#
コードを隠すコードを選択
//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にする例を以下に示します。

VB.NET
コードを隠すコードを選択
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
C#
コードを隠すコードを選択
//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>

<sharedListeners>要素にリスナの設定を記述する

複数の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>

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。
共有する

この記事への評価

この記事へのコメント

この記事に関するコメントを投稿するには、下のボタンをクリックしてください。投稿フォームへ移動します。通常のご質問、ご意見等は掲示板へご投稿ください。