japan.internet.comThe Internet & IT Network
Twitter
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2009年11月24日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
事業仕分けによる次世代スーパーコンピューターの開発予算削減について、どうお考えですか?
賛成
反対
どちらとも言えない
投票締切 11/30 12:00
デベロッパー コラム2005年10月18日 17:10
15 seconds
15 seconds japan.internet.com 編集部(japan.internet.com)メールホームrss
米国 WebMediaBrands が運営する、
Microsoft のインターネットソリューションで作業する開発者向けの、フリーのリソースを提供するサイト。

.NETでのトレースの方法と独自のトレースリスナの実装

海外海外internet.com発の記事

はじめに

 「デバッグ」と「トレース」は、アプリケーションの作成と保守に役立つ重要なプログラミング操作/プロセスです。デバッグとは、プログラミングエラーを観察して訂正することです。トレースはデバッグの一種であり、アプリケーションの「健康状態」を追跡することです(これは硬直的な定義であり、実際にはもっと広い意味も含まれます)。

 アプリケーションの動作を動的に制御し、アプリケーションがどのように実行されているか、実行時にどんなエラーが発生するか、ピーク時にどんな動作をするか、アプリケーションの動作がどのような仕組みで動的に変化しているか、といった側面を追跡できるようにすることは非常に重要です。

 この記事では、.NETでデバッグとトレースがどのように実装されているかと、これらの機能をニーズに合わせてカスタマイズする方法について説明します。

.NETでのトレース

 まずは、.NETでトレースがどのように実装されているかを見てみましょう。.NETにはトレースリスナというオブジェクトが用意されています。トレースリスナとは、トレース出力を受け取って、それを他の場所に出力するオブジェクトです。開発環境内のウィンドウや、ハードディスク上のファイル、Windowsのイベントログ、SQL Serverデータベース、Oracleデータベースなど、さまざまなデータストアにトレース情報を出力することができます。

 トレースリスナは、アプリケーションからのトレース情報を出力ストアに送り出すためのパイプのようなものです。トレース情報をトレースリスナに書き込むと、そのトレースリスナがトレース情報をターゲットメディアに出力してくれます。

 トレース情報を何らかのデータストアに格納すると、後でそのデータを柔軟な方法で分析することができ、アプリケーション内の動作パターンとエラーやパフォーマンスとの関係を探るのに役立ちます。

 System.Diagnostics名前空間は、トレースやデバッグをはじめとする各種のアプリケーション診断サービスやシステム診断サービスで使用されるインターフェイス、クラス、列挙体、構造体を提供します。この記事では、トレースにのみ焦点を当てることにします。

 System.Diagnostics名前空間には、エラー情報とアプリケーション実行情報をログに書き込むために使用するTraceDebugというクラスが用意されています。これらのクラスは、開発中にデバッグメッセージなどを出力するときや、開発後にパフォーマンス関連のパターンなどを出力するときに役立ちます。この2つのクラスは基本的には同じものですが、Traceクラスのメソッドはリリースビルドコードの一部になるのに対して、Debugクラスのメソッドはリリースビルド実行可能ファイルの一部にはなりません。

 新しいプロジェクトを作成したときに、Debugクラスによる出力を有効にするにはDEBUGシンボルを定義し、Traceクラスによる出力を有効にするにはTRACEシンボルを定義します。Visual Studio .NETでプロジェクトを作成した場合は、そのプロジェクトのデバッグバージョンにはこれらのシンボルがあからじめ定義されています。

図1
図1

 System.Diagnostics名前空間には、いくつかの種類のトレースリスナが用意されています。既定のトレースリスナはSystem.Diagnostics.DefaultTraceListenerです。このクラスのWriteメソッドとWriteLineメソッドは、トレース情報をOutputDebugStringと関連デバッガのLogメソッドに書き出します。

 .NETフレームワークには、トレーススイッチという概念も導入されています。名前からわかるとおり、これはアプリケーションの外部から値を制御できるスイッチです。アプリケーションの外部から値を制御できるということは、アプリケーションをコンパイルして.exeファイルまたは.DLLファイルを生成した後に、コードを書き換えなくてもこれらのスイッチの値を変更できるということです。.configファイル内の対応するエントリを更新するだけで、アプリケーション内のスイッチに新しい値を割り当てることができます。より厳密に言えば、トレーススイッチとは、.configファイルを通じて外部から制御できる単純なオブジェクトということになります。

 以降では、トレースリスナとトレーススイッチについて詳しく見ていきます。次に示すのは、TraceクラスとDebugクラスのWriteLineメソッドの単純な使用例です。

Trace.WriteLine ("Hello 15Seconds Reader - Trace!") ;
Debug.WriteLine ("Hello 15Seconds Reader - Debug!") ;

 これらのメソッドをデバッグモードで使用すると、トレース出力とデバッグ出力がデバッガの出力ウィンドウに書き出されます(図2を参照)。

図2
図2

トレースリスナ

 前述したとおり、トレースリスナはトレース情報を受け取り、格納し、最終的な宛先に送り出すためのオブジェクトです。トレース情報の最終的な宛先は、トレースリスナによって決定されます。.NETには次のようなトレースリスナが用意されています。

  • DefaultTraceListener
  • TextWriterTraceListener
  • EventLogTraceListener

 すべてのトレースリスナはTraceListener抽象クラスから派生しています。このクラスは、個々のトレースリスナが実装すべきメソッドを宣言しています。このクラスを継承する場合は、少なくともWriteメソッドとWriteLineメソッドを実装する必要があります。TraceクラスとDebugクラスには、リスナのコレクションへの参照を格納するListenersというプロパティがあります。リスナのコレクションオブジェクトは、TraceListener型のコレクションを表すTraceListenerCollection型として扱われます。これはつまり、複数のリスナがトレース情報を使用できるということであり、これらのリスナはトレース情報の宛先について完全な制御権を持ちます。

 TraceクラスとDebugクラスは同じTraceListenerCollectionオブジェクトを共有しています。したがって、Traceオブジェクトにリスナを追加すると、そのリスナはDebugでも使用可能になります(逆も同様です)。

 すべてのトレースリスナは次のメソッドを備えています。これらのメソッドの機能は、トレース出力のターゲットメディアがトレースリスナによって決定されるという点を除いては、どのトレースリスナでも同じです。

メソッド名結果
Fail指定されたテキストを呼び出し履歴とともに出力します。
Write指定されたテキストを出力します。
WriteLine指定されたテキストとキャリッジリターンを出力します。
Flushターゲットメディアへの出力バッファをフラッシュします。
Close出力ストリームを閉じて、トレース/デバッグ出力を受け取らないようにします。

DefaultTraceListener

 このクラスは、TraceクラスまたはDebugクラスのTraceListenerCollectionオブジェクトに追加されている既定のトレースリスナです。このトレースリスナのFailメソッドは、アプリケーションがユーザーインターフェイスモードで実行中であるときにはメッセージボックスを表示します。

 このクラスは、Visual Studio環境内でトレース出力を確認したいときに使用します。Visual Studio .NETの外部でトレースメッセージを取得したい場合は、他のトレースリスナを使用する必要があります。

TextWriterTraceListener

 TextWriterTraceListenerは、TextWriterクラスのインスタンスまたはStreamクラスの任意のオブジェクト(ログファイル、ネットワークストリーム、コンソールなど)にトレース出力を書き出します。

 次のコード例を見てください。

1. FileStream objStream = new FileStream("C:AppLog.txt", FileMode.OpenOrCreate) ;
2. TextWriterTraceListener objTraceListener = new TextWriterTraceListener(objStream) ;
3. Trace.Listeners.Add(objTraceListener) ;
4. Trace.WriteLine("Hello 15Seconds Reader -- This is first trace message") ;
5. Trace.WriteLine("Hello again -- This is second trace message") ;
6. Debug.WriteLine("Hello again -- This is first debug message") ;
7. Trace.Flush() ;
8. objStream.Close() ;

 このコードは、TextWriterTraceListenerをログファイルに関連付ける方法、リスナのコレクションにリスナを追加する方法、トレース情報を書き出す方法を示しています。

 1行目では、FileStream型のオブジェクトを作成しています。このオブジェクトは、「C:AppLog.txt」というアプリケーションのログファイルを指しています。

 2行目では、TextWriterTraceListenerオブジェクトを作成し、先ほど作成したFileStreamオブジェクトをパラメータとして渡しています。このステートメントにより、「AppLog.txt」ファイルがトレース情報およびデバッグ情報の最終的な宛先として設定されます。

 3行目では、トレースリスナをリスナのコレクションに追加しています。

 4行目から6行目では、さまざまなトレースメッセージとデバッグメッセージを書き出しています。

 7行目では、TraceオブジェクトのFlushメソッドを呼び出して、ターゲットメディアへの出力バッファをフラッシュしています。

 8行目では、ログファイルを閉じています。

 このコードを実行すると、ハードディスク上に「Applog.txt」ファイルが作成されます。「Applog.txt」ファイルの内容は図3のようになります。

図3
図3

 このように、ログ情報をファイルに保存するのは非常に簡単です。

EventLogTraceListener

 EventLogTraceListenerは、トレースメッセージとデバッグメッセージをWindowsのイベントログに書き出すときに使用します。このクラスの利点は、トレース情報とデバッグ情報をリモートコンピュータのイベントログにも書き出せることです。そのため、このクラスはイベントログをサポートしていないマシン(Microsoft Windows Meなど)でも役立ちます。

 このクラスを使用してトレース情報とデバッグ情報をイベントログに書き出すには、まずこのクラスをイベントログに関連付ける必要があります。そのための手段として、EventLogというプロパティが用意されています。このプロパティを使用すると、出力を受け取るイベントログを取得または設定できます。その他に、このクラスの3つ目のコンストラクタを使用するという方法もあります。このコンストラクタはイベントソースの名前を受け取り、クラスをイベントソースに自動的に関連付けます。

 両方の方法を使用したコード例を次に示します。

例1:EventLogオブジェクトを使用してEventLogTraceListenerを初期化する

EventLogTraceListener objListener = new
EventLogTraceListener() ;
EventLog objLog = new EventLog("EventLogName") ;
objListener.EventLog = objLog ;

例2:コンストラクタを使用してEventLogTraceListenerを初期化する

EventLogTraceListener objListener = new
EventLogTraceListener("EventLogName") ;

外部コードからトレースリスナを操作する

 詳細なトレース情報を組み込んだアプリケーションをビルドし、実際の使用環境に配置したとします。このアプリケーションは順調に動作し、ハードディスク上にトレースログファイルを生成していました。そのうちに、アプリケーションの開発者の1人がトレース情報をデータベースに書き出すトレースリスナを新しく作成したので、それを使用したいと思います。さてどうすればいいでしょうか? コードを書き換えるという方法もありますが、あまりお勧めできません。コードを書き換えるのはトレースリスナを操作する1つの方法ではありますが、.NETには、これを実現する別の方法が用意されています。トレースリスナをコード内にハードコーディングする代わりに、アプリケーションの.configファイルを通じてトレースリスナを追加または削除できるのです。Windowsフォームアプリケーションの場合は、この設定ファイルの名前は「<アプリケーション名>.exe.config」となります。ASP.NETの場合は、「web.config」(マシンレベルの設定の場合は「machine.config」)となります。この設定ファイル内の<listeners>要素で、一部または全部のリスナを追加したり削除したりできます。次の例を見てください。この例では、既定のトレースリスナ(DefaultTraceListener)を削除して、「MyEventLog」というイベントログにトレースメッセージを書き出すEventLogTraceListenerを追加しています。

<configuration>
 <system.diagnostics>
  <trace autoflush="true" indentsize="2">
   <listeners>
    <remove name="Default"/>
    <add name="EventLogListener"
     type="System.Diagnostics.EventLogTraceListener,System"
     initializeData="MyEventLog"/>
   </listeners>
  </trace>
 </system.diagnostics>
</configuration>

トレーススイッチ

 ここまではアプリケーションにトレースコードやデバッグコードを組み込む方法を見てきましたが、トレース出力やデバッグ出力を制御する方法や、配置後にアプリケーションのトレース動作を変更する方法についてはまだ説明していません。

 この種の制御を実現するには、トレーススイッチを使用します。トレーススイッチとは、Switchクラスから派生したオブジェクトです。このオブジェクトはアプリケーションの設定ファイルを通じて制御できるので、トレース動作を変更しようとするたびに、コードを修正してコンパイルと配布をやり直す必要はなくなります。

 スイッチオブジェクトには必ず名前と説明を割り当てます。スイッチオブジェクトの名前は、.configファイル内の対応するエントリを探す際に使用されるので重要な意味を持ちます。

 トレーススイッチには、BooleanSwitchTraceSwitchの2種類があります。以降では、この2種類のスイッチについて詳しく説明します。最初に注意しておきますが、トレーススイッチを使用するにはトレースとデバッグを有効にする必要があります。

BooleanSwitch

 BooleanSwitchは、その名前のとおり、有効(true)または無効(false)に設定できる二極スイッチです。

 コード内でBooleanSwitchを使用するには、BooleanSwitchのインスタンスを作成する必要があります。このインスタンスには、.configファイル内で定義したスイッチと同じ名前を付けなければなりません。コード内のスイッチ名が.configファイル内のどのスイッチにも一致しない場合、そのスイッチは既定で無効になります。

 次の.configファイルは、ShowErrorsというスイッチの例を示しています。これはエラー情報を出力するかどうかを表すためにコード内で使用されるスイッチであり、ここでは有効(value = "1")に設定されています。

<configuration>
 <system.diagnostics>
  <switches>
   <add name="ShowErrors" value="1" />
  </switches>
 </system.diagnostics>
</configuration>

 次のコード例では、このスイッチの値に基づいて、エラー情報をコンソールに出力するかどうかを判断しています。

// Static class level declaration of BooleanSwitch object.
static BooleanSwitch blnSwitch =
new BooleanSwitch("ShowErrors", "Show errors to me") ;

// If BooleanSwitch is enable, then report error/tracing info/etc.
if (blnSwitch.Enabled == true)
        Console.WriteLine("Could not open connection to database") ;

 <add>タグのvalue属性の値は、BoolenSwitchの値を表します。したがって、次のようになります。

  • value属性の値が0の場合は、Enabledfalse
  • value属性の値が1の場合は、Enabledtrue

TraceSwitch

 TraceSwitchクラスでは、単純なBooleanSwitchクラスよりも細かい制御ができます。このクラスでは、BooleanSwitchクラスのような単純な有効/無効の制御ではなく、いくつかのレベルに分けた制御を行うことができます。TraceSwitchには次のようなトレースレベルがあります。

トレースレベル設定値説明
Off0トレースリスナにメッセージを出力しません。
Error1エラーメッセージだけをトレースリスナに出力します。
Warning2エラーメッセージと警告メッセージをトレースリスナに出力します。
Info3情報メッセージ、警告メッセージ、エラーメッセージをトレースリスナに出力します。
Verbose4すべてのメッセージをトレースリスナに出力します。

 TraceSwitchクラスのインスタンスは、BooleanSwitchオブジェクトと同様の方法で作成します。トレースを有効にするには、TraceSwitchオブジェクトのLevelプロパティを使用します。スイッチのLevelプロパティを特定のレベル(上記の表のいずれかの値)に設定すると、指定のレベルよりも低いレベルをすべて含むことになります。たとえば、TraceSwitchLevelプロパティをTraceLevel.Infoに設定した場合は、それよりも低いレベル、つまりTraceLevel.ErrorからTraceLevel.Warningまでを含むことになります。

 次のコードは、エラーメッセージと警告メッセージのみのトレースを有効にする方法を示しています。

TraceSwitch objSwitch = new TraceSwitch("ErrorAndWarningTrace",
"This is the trace for Error and Warning messages") ;
objSwitch.Level = TraceLevel.Warning ;

 TraceSwitchクラスには、その他に次のプロパティがあります。

  • TraceError
  • TraceWarning
  • TraceInfo
  • TraceVerbose

 これらのプロパティはLevelプロパティの値に連動しており、TraceSwitchオブジェクトのLevelプロパティを特定のレベル、たとえばTraceLevel.Warningに設定した場合は、TraceErrorプロパティとTraceWarningプロパティはtrueを返し、TraceInfoプロパティとTraceVerboseプロパティはfalseを返します。これらのプロパティを使用すると、どの種類のメッセージがリスナに送信されるかをコード内で確認できます。これらのプロパティはTraceクラスおよびDebugクラスのWriteIfメソッドとWriteLineIfメソッドで使用されます。

 次のコード例は、上記のトレースレベルプロパティを利用してトレース出力を制御する方法を示しています。

Trace.WriteLineIf(objSwitch.TraceWarning, "This is a warning message") ;

 このステートメントでは、TraceSwitchのトレースレベルが少なくともTraceLevel.Warningに設定されているか、それより高い場合にのみ、警告メッセージを出力します。トレースレベルがTraceLevel.Errorの場合には、このステートメントは何も出力しません。

独自のトレースリスナの実装

 ほとんどのアプリケーションでは、.NETに用意されているトレースリスナを使用すれば用が足ります。しかし、独自のトレースリスナを作成したい場合はどうすればいいでしょうか?

 .NETでは、TraceListenerクラスを利用して独自のトレースリスナを記述することができます。すべてのトレースリスナはこのクラスを継承しているので、独自のトレースリスナを実装するためには、このクラスを継承してトレースリスナクラスを作成する必要があります。

 TraceListenerクラスには、数多くの仮想メソッドと抽象メソッドが用意されています。このクラスを継承するクラスは、少なくともWriteメソッドとWriteLineメソッドを実装する必要があります。この他に重要なメソッドとして、FailCloseFlushがあります。これらのメソッドを継承クラスで実装することは必須ではありませんが、実装しておくと便利です。これらのメソッドの機能については、前出の表を参照してください。

 WriteメソッドとWriteLineメソッドはオーバーロードされています。Writeメソッドのすべてのオーバーロードを次に示します。

  • public override void Write(string message)
  • public override void Write(object o)
  • public override void Write(string message, string category)
  • public override void Write(object o, string category)

 WriteメソッドとWriteLineメソッドのオーバーロードは1対1の対応になっています。TraceListenerクラスのWriteメソッドとWriteLineメソッドのそれぞれに4種類のオーバーロードがあるのはなぜでしょうか? その答えは次のとおりです。

理由
 TraceクラスとDebugクラスのWriteWriteIfWriteLineWriteLineIfメソッドも同様にオーバーロードされており、それぞれのメソッドに4種類のオーバーロードがあります。TraceクラスとDebugクラスのメソッドはトレースリスナのWriteメソッドとWriteLineメソッドを呼び出すので、TraceListener側のこれらのメソッドにもオーバーロードが必要になります。

 独自のトレースリスナを実装する場合は、TraceListenerクラスからリスナクラスを派生させ、少なくともWriteメソッドとWriteLineメソッドを実装します。必要な作業はこれだけです。

 この記事のために、DatabaseTraceListenerというトレースリスナを作成してみました。このリスナはトレースメッセージとデバッグメッセージをデータベースに書き出します。

 書き出し先のデータベースは「TraceStore」という名前で、「Traces」というテーブルを含んでいます。このデータベーステーブルの構造は次のとおりです。

図4
図4
  • TraceDateTime列:トレースメッセージの日付と時刻を格納します。
  • TraceCategory列:トレースメッセージの実際のカテゴリを格納します。
  • TraceDescription列:トレースメッセージを格納します。
  • StackTrace列:スタックトレースを格納します。
  • DetailedErrorDescription列:Failメソッドの2つ目のパラメータに渡される詳細なエラーメッセージを格納します。

 今回のカスタムトレースリスナは次のメソッドを実装しています。

  • Writeとそのすべてのオーバーロード
  • WriteLineとそのすべてのオーバーロード
  • Fail
  • Flush
  • Close

アプリケーション内でDatabaseTraceListenerを使用する

 独自に作成したトレースリスナを使用するのに必要な作業は、.configファイルの一部を書き換えることだけです。この書き換えをした後は、TraceクラスとDebugクラスを使用してトレースメッセージとデバッグメッセージを書き出すことができます。

.configファイル内で必要な設定

 今回作成したDatabaseTraceListenerは、アプリケーションの.configファイル内に2つのカスタムアプリケーション設定が記述されていることを前提にしています。アプリケーションの.configファイルに次の<appSettings>ノードを追加する必要があります。

<appSettings>
 <add key="ConnectionString" value="Data
            Source=localhost;uid=sa;pwd=;Initial Catalog=TraceStore" />
 <add key="MaximumRequests" value="2" />
</appSettings>

 ConnectionString設定には、データベースへの接続文字列を指定します。MaximumRequests設定には、ローカルキャッシュに格納できるトレースメッセージの最大数を表す整数値を指定します(この最大数を超えるとトレースメッセージがデータベースに保存されます)。MaximumRequests設定を用意したのは効率を良くするためです。トレースメソッドからトレースメッセージを受け取るたびにデータベースに接続してトレースメッセージを保存していたのでは、効率が悪くて仕方ありません。これを避けるために、トレースメッセージをローカルキャッシュに一時的に格納し、最大数に達したらデータベースに保存するようにしています。その後、トレースメッセージのキャッシュを再開し、これを繰り返します。

 FlushメソッドとCloseメソッドは、キャッシュしたすべてのメッセージをデータベースに保存するだけです。

 MaximumRequests設定の値は、トレースメッセージの頻度に応じて調節できます。大量のトレースメッセージを書き出すアプリケーションの場合は、これを大きな数値に設定します。そうでない場合は、小さな数値に設定します。

 同様に、アプリケーションの.configファイルに次の<system.diagnostics>ノードを追加する必要があります。

<system.diagnostics>
  <trace autoflush="true" indentsize="2">
   <listeners>
    <add name="DBTL", type="CustomTraceListeners.DatabaseTraceListener,
                                                CustomTraceListeners"/>
   </listeners>
  </trace>
 </system.diagnostics>

サンプルコード

 .configファイルに上記の変更を加えれば、このトレースリスナをテストすることができます。次のコードをアプリケーションのどこかに記述して、試してみましょう。

object obj1 = "Message from Trace.Write(object)" ;
object obj2 = "Message from Trace.Write(object, category)" ;

Trace.Write("Message from Trace.Write(message)") ;
Trace.Write(obj1) ;
Trace.Write("Message from Trace.Write(message, category)","category1") ;
Trace.Write(obj2, "category2") ;

Trace.WriteLine("Message from Trace.WriteLine") ;
Trace.Fail("Message from Trace.Fail") ;
Trace.Fail("Message from Trace.Fail", "Detailed error message") ;

Trace.Flush() ;

 このコードでは、いくつかのトレースメッセージを単純に書き出しています。Failメソッドの呼び出しは、図5のようなアサーションダイアログボックスを表示します。

図5
図5

 これはFailメソッドの既定の動作です。処理を続けるには、[Ignore]ボタンをクリックします。このコードが完全に実行されると、データベース内の「Traces」テーブルに次の行が書き込まれます。

図6
図6

ASP.NETでのトレース

 ASP開発者がASPで何かをデバッグ/トレースするときにはどんな方法を使っているでしょうか。クラシックASPの開発者が特定の値を確認したり実際にコードのロジックをチェックしたりするときには、コードのあちこちにResponse.Writeステートメントを記述する必要があります。誰に聞いても同意してもらえると思いますが、ASP内で何かをデバッグ/トレースするのは非常に手間のかかる作業です。コード内にResponse.Writeステートメントを記述するという古典的な手法でトレースを行うときの問題の1つは、アプリケーションが出荷できる段階になったときに、すべてのトレースステートメントをコードから手動で削除しなければならないことです。これは非常に面倒な作業であり、洗練された手法とは言えません。

 ASP.NETには、ASP.NETファイル(.aspx、.asmxなど)をデバッグするための新しいデバッガと、トレースを行う非常に柔軟な方法が組み込まれています。ASP.NETのトレースは、従来のものとはまったく異なります。ASP.NETでは非常に洗練された形のトレースを行うことができ、トレースステートメントをコード内に記述したままの状態で、アプリケーションを実働環境に配備することができます。

 System.Web.UI.PageクラスのTraceプロパティはSytem.Web.TraceContextオブジェクトを提供します。実際のところ、Traceオブジェクトは、RequestResponseServerなどと同様の組み込みページオブジェクトと考えられます。このオブジェクトはページコード内から直接アクセスできます。このオブジェクトを使用すると、ページまたはアプリケーション全体のトレースを有効にしたときにのみ動作するデバッグ/トレースステートメントを記述できます。

 TraceContextクラスはControl.Context.Traceプロパティを通じてもアクセスできます。これは、カスタムサーバーコントロール内にトレースステートメントを含めたり、必要に応じてASP.NETページの外部(たとえば「global.asax」ファイル)からトレースステートメントを含めたりすることがあるからです。

 ASP.NETのTraceオブジェクトとSystem.Diagnostics.Traceクラスを混同しないでください。2つはまったく異なるオブジェクトです。前者はASP.NET内でのみ使用できますが、後者はASP.NETアプリケーションでもWindowsアプリケーションでも使用できます。ASP.NETアプリケーション内でも、System.Diagnostics名前空間から提供される機能を完全に使用できます。

 ASP.NETには、ページレベルのトレースとアプリケーションレベルのトレースという2種類のトレースが用意されています。以降では、この2種類のトレースを実装する方法を詳しく見ていきます。

ASP.NETでのSystem.Web.TraceContextクラス(またはTraceオブジェクト)

 System.Web.TraceContextクラスはASP.NETページのトレース出力を管理します。このクラスの次に示すメソッドはトレースに関係しています。

メソッド説明
IsEnabledこのプロパティは、トレースが有効な場合はtrue、それ以外の場合はfalseを返します。
TraceModeこのプロパティは、トレースメッセージをHTMLに書き出す順序を設定するために使用します。
Writeこのメソッドは、カスタムトレースメッセージをトレース出力に書き出します。
WarnこのメソッドはWriteメソッドと同じですが、すべてのトレースメッセージを赤字のテキストとして表示します。

 次のコードは、ASP.NETアプリケーション内にトレースステートメントを記述する方法を示しています。

// Simple trace statement
Page.Trace.Write("This is trace statement") ;

// Trace statement in red color.
Page.Trace.Warn("This is the last warning for you") ;

ページレベルのトレース

 ASP.NETではWebページごとにトレースを有効にできます。そのためには、@PageディレクティブのTrace属性を使用します。次のステートメントでは、ページのトレースを有効にしています。

<%@ Page Trace="true" %>

 また、@PageディレクティブのTraceMode属性には次のいずれかの値を指定できます。

  • SortByTime
  • トレースメッセージをサーバー上で処理された順序に並べ替えます。
  • SortByCategory
  • トレースメッセージをTrace.WriteメソッドおよびTrace.Warnメソッドで指定したカテゴリごとに並べ替えます。

 トレースを有効にすると、どのような情報が得られるのでしょうか? 図7を見てください。図7は、次のコードを実行した単純なASP.NETページを示しています。

Response.Write("Hello 15Seconds Reader") ;
Trace.Write("Test Category 1","This is tracing message from ASP.NET") ;
Trace.Warn("Test Category 2", "This is warning message from ASP.NET") ;

 このことからわかるように、ASP.NETのトレースでは次の情報が得られます。

  • Request Details(要求の詳細)
  • セッションID、要求時刻、要求のエンコード、要求の種類、要求の状態、応答のエンコードといった基本情報が含まれます。
  • Trace Information(トレース情報)
  • Trace.WriteおよびTrace.Warnメソッドを使用したときにトレース出力に書き出されるページレベルのトレースメッセージが含まれます。
  • Control Tree(コントロールのツリー)
  • ASP.NETページ上にあるコントロールの一覧とその階層が含まれます。各コントロールのID、種類、描画サイズ、ビューステートのサイズが示されます。
  • Cookies Collection(クッキーコレクション)
  • クッキーの一覧です。クライアントがサーバーに送信するすべてのクッキーの値とサイズが示されます。
  • Headers Collection(ヘッダーコレクション)
  • すべてのHTTPヘッダーの一覧です。
  • Server Variables(サーバー変数)
  • すべてのサーバー変数とその値の一覧です。

 前述のコードで定義したトレースメッセージは、図7のトレース出力の「Trace Information(トレース情報)」セクションに示されています。

図7
図7

 この機能のメリットは、ページ内にトレースステートメントを好きなだけ記述しておき、トレースをこれ以上行う必要がなくなったら、@PageディレクティブのTrace属性をfalseに設定するだけで、トレース出力が生成されないようにすることができるという点です。トレースステートメントをコードから手動で削除する必要はありません。

アプリケーションレベルのトレース

 ページレベルのトレースは、1つか2つのページのトレースを有効にする場合には便利ですが、アプリケーションを構成するすべてのページで1つ1つ@Pageディレクティブを使用してトレースを有効にするのはスマートではありませんし、時間がかかりすぎます。トレースを無効にするときにも、同様に、1つ1つのページをエディタで開いてTrace属性をfalseに設定しなければなりません。

 ASP.NETでは、この問題の解決策としてアプリケーションレベルのトレースが用意されています。アプリケーションレベルのトレースを有効にするには、Webアプリケーションの「web.config」ファイルの<trace>ノードを使用します。

 次の<trace>ノード設定では、Webアプリケーションのアプリケーションレベルのトレースを有効にし、要求の数を20に設定しています。

<configuration>
 <system.web>
  <trace enabled="true" requestLimit="20" />
</system.web>
</configuration>

 <trace>ノードには次の属性があります。

属性説明
enabledアプリケーションのトレースを有効にするには、この属性をtrueに設定します。それ以外の場合はfalseに設定します。既定値はfalseです。
pageOutputトレース情報をトレースページと「trace.axd」ファイルの両方に出力する場合は、この属性をtrueに設定します。それ以外の場合はfalseに設定します。既定値はfalseです。
たとえばpageOutputfalseに設定してenabledtrueに設定した場合は、ページ上にトレース出力が表示されないので、トレース情報を確認するには「trace.axd」ファイルを開く必要があります(@PageディレクティブのTrace属性がfalseに設定されていることが前提です)。
requestLimitこの属性では、ASP.NETがトレース情報を格納する要求の最大数を指定します。既定値は10です。
traceMode@PageディレクティブのTraceMode属性と同じ機能です。SortByTimeSortByCategoryのいずれかの値を取ります。既定値はSortByTimeです。
localOnlyこの属性では、「trace.axd」ファイルをローカルサーバーからのみアクセス可能にするか(true)、他のコンピュータからもアクセス可能にするか(false)を指定します。既定値はtrueです。

 アプリケーション全体のトレースを有効にした場合、ASP.NETは、<trace>ノードのrequestLimit属性に指定した要求数に達するまで、すべての要求に対するトレース出力を格納し始めます。

 アプリケーションレベルのトレースを有効にした場合に、ASP.NETがそのWebアプリケーションに関して記録したすべてのトレースを見るためには、Webアプリケーションの「trace.axd」ファイルを参照する必要があります。「trace.axd」ファイルを参照するためのジェネリックURLは次のとおりです。

http://<サーバー名>/webapp/trace.axd

 私のマシン上でテスト用のWebサイト(/wa)を参照したときの様子を図8に示します。

図8
図8

 最大要求数に達するまでは、すべての要求がメモリに格納されます。右端の列に表示されている「View Details(詳細の表示)」リンクをクリックすると、その要求に関するトレースの詳細が表示されます。

 ASP.NETのトレースをいろいろ試していて気が付いた重要な点の1つは、.configファイルを変更すると、アプリケーションのトレースがリサイクルされて、メモリ内のトレースがクリアされてしまうということです。

 ASP.NETのトレースのしくみは以上ですが、実働環境のアプリケーションではトレースを使用するべきではありません。トレースはアプリケーションのパフォーマンスに深刻な影響を与えるからです。実働環境に配備したASP.NETアプリケーションでトレース情報を取得したい場合は、System.Diagnostics名前空間のクラスを使用することを検討してください。この記事の前半で説明したSystem.Diagnostics名前空間のクラスの詳細は、ASP.NETアプリケーションにもすべて適用できます。ASP.NETアプリケーション内でこれらのクラスをさまざまに活用することができます。

まとめ

 この記事では、トレースの概要と利用方法について解説しました。独自のトレースリスナの作成方法についても触れました。.NETのトレースは非常に洗練されたオブジェクト指向的な方法で実装されており、.configファイルとカスタムリスナのおかげで、非常に柔軟でカスタマイズしやすいものになっています。

 ASP.NET Webアプリケーションで1つ注意してほしいのは、開発時にトレースを有効にすることはかまいませんが、実働環境のアプリケーション内でASP.NETトレースを有効にすると、アプリケーションのパフォーマンスに深刻な影響を与えるおそれがあるという点です(System.Diagnostics名前空間のクラスを利用したトレースは問題ありません)。したがって、ASP.NETトレースを使用するときは十分に注意してください。

 一般的には、アプリケーションの開発時には広範囲に渡ってトレースを使用することをお勧めします。アプリケーションをリリースできる段階になったら、開発固有のトレースメッセージをコードから取り除けばよいのです(ヒント:トレースレベルを使用します)。ある種のトレースは、アプリケーション内のエラーや問題を調査するときに大きな助けになります。

著者紹介

Mansoor Ahmed Siddiqui(Mansoor Ahmed Siddiqui)
アメリカで活動するソフトウェアコンサルタント兼テクニカルライター。コンピュータ工学の学位を持ち、1997年からソフトウェア開発に携わる。専門分野はWebベースアプリケーション、クライアント/サーバーアプリケーション、およびn層アプリケーションの設計開発で、特に中間層とWin32プログラミングを得意とする。
Microsoft. NET Framework、ASP.NET、C#、Visual Studio .NET、Webサービス、ADO.NET、ASP、JavaScript、eXtensible Markup Language(XML)、Simple Object Access Protocol(SOAP)、Visual C++、Microsoft Foundation Class Library(MFC)、Active Template Library(ATL)、Visual Basic 6.0、ActiveX Data Objects(ADO)、COM/DCOM/COM+、Microsoft Transaction Server(MTS)、Microsoft Message Queue(MSMQ)、SQL Server 7.0/2000、OMGのUnified Modeling Language(UML)、Rational Software Corp.のRational Rose、Java、Java Server Page(JSP)、サーブレット、Enterprise JavaBeans(EJB)、Java 2 Platform Enterprise Edition(J2EE)についての専門知識を持つ。
現在はVisual Studio 7.0とMicrosoft .NETプラットフォームを使用。MCSD資格のほか、さまざまな言語のBrainbench認定資格を持つ。
テクニカルライティングの他には、音楽鑑賞、水泳、クリケット、ビリヤード、友人との付き合いを楽しむ。連絡先はmansoorasiddiqui@hotmail.comおよびICQ 151707288。
Graphic Design Forum
【Graphic Design Forum】
流動的媒体と静的媒体に関する見解(11月18日)
スマートにソーシャルウェブを構築しよう
スマートにソーシャルウェブを構築しよう
オバマ大統領も絶賛。メイヨークリニックのソーシャルメディアポリシー(11月24日)
アイレップの SEM フロンティア
アイレップの SEM フロンティア
検索技術の進化で広がる SEO 領域―2010年以降に要求される事は?(11月24日)
百式のネットビジネス研究
百式のネットビジネス研究
外国で見かけた標識を写真に撮ると翻訳してくれる iPhone アプリ「PicTranslator」(11月24日)
DevX
DevX
HTML 5のフォーム要素(11月24日)
エンジニア転職ノウハウ開発室
エンジニア転職ノウハウ開発室
エンジニア的「合わない」と思う瞬間/理系の人々(11月24日)
「IT の耳」
「IT の耳」
【書評】『Hyper-V スタートアップバイブル』――仮想化についてのすぐれた解説書(11月20日)
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(11月19日)
海外ソーシャルウェブに学ぶ成功の秘訣
海外ソーシャルウェブに学ぶ成功の秘訣
ゲーム業界を襲う世界的な激震。ソーシャルゲーム急成長のインパクト(11月19日)
今さら聞けない初歩からのアクセス解析
今さら聞けない初歩からのアクセス解析
サイトリニューアル前のアクセス解析活用法(11月19日)
成約率、反応率を上げる Web 文章術
成約率、反応率を上げる Web 文章術
文章力を磨き、キャッシュを生み出す Web サイト に(11月19日)
Copyright 2009 Japan Internet.com K.K. All Rights Reserved.http://www.internet.com/