ASP.NET の状態監視でエラーの詳細をログに記録する (C#)
Microsoft の稼働状況の監視システムには、ハンドルされない例外を含めた、さまざまな Web イベントをログするための簡単でカスタマイズ可能な方法があります。 このチュートリアルでは、ハンドルされない例外をデータベースにログし、開発者に電子メール メッセージを介して通知するように稼働状況の監視システムを設定する手順について説明します。
はじめに
ログは、配置されたアプリケーションの正常性を監視し、発生する可能性のある問題を診断するための便利なツールです。 特に、配置されたアプリケーションで発生したエラーを、解決できるようにログすることが重要です。 Error
イベントは、ASP.NET アプリケーションでハンドルされない例外が生じるたびに発生します。前のチュートリアルでは、エラーを開発者に通知し、Error
イベントのイベント ハンドラーを作成してその詳細をログする方法を示しました。 ただし、エラーの詳細をログして開発者に通知する Error
イベント ハンドラーを作成する必要はありません。このタスクは ASP NET の "稼働状況の監視システム" で実行できるためです。
ASP.NET 2.0 で導入された稼働状況の監視システムは、アプリケーションまたは要求の有効期間中に発生したイベントをログすることによって、配置された ASP.NET アプリケーションの正常性を監視するように設計されています。 稼働状況の監視システムによってログされるイベントは、"正常性監視イベント" または "Web イベント" と呼ばれ、次のものが含まれます。
- アプリケーションの起動や停止などのアプリケーションの有効期間に関するイベント
- ログイン試行の失敗や URL 認可要求の失敗などのセキュリティ イベント
- ハンドルされない例外、ビュー状態解析の例外、要求検証の例外、コンパイル エラー (その他の種類のエラーも含まれます) などのアプリケーション エラー。
稼働状況の監視イベントが発生すると、指定した任意の数の "ログ ソース" にログできます。 稼働状況の監視システムには、Web イベントを Microsoft SQL Server データベース、Windows イベント ログ、または電子メール メッセージなどにログする、ログ ソースが付属しています。 独自のログ ソースを作成することもできます。
稼働状況の監視システムでログされるイベントは、使用されるログ ソースと共に、Web.config
で定義されます。 数行の構成マークアップで、稼働状況の監視を使用して、ハンドルされないすべての例外をデータベースにログし、電子メールで例外の通知を受けることができます。
稼働状況の監視システムの構成の探索
稼働状況の監視システムの動作は、Web.config
の <healthMonitoring>
要素にある構成情報によって定義されます。 この構成セクションでは、特に次の 3 つの重要な情報が定義されます。
- 発生したときにログする必要がある稼働状況の監視イベント、
- ログ ソース、および
- (1) で定義されているそれぞれの稼働状況の監視イベントを、(2) で定義されたログ ソースにマップする方法。
この情報は、3 つの子構成要素 <eventMappings>
、<providers>
、および <rules>
でそれぞれ指定されます。
既定の稼働状況の監視システムの構成情報は、%WINDIR%\Microsoft.NET\Framework\version\CONFIG
フォルダー内の Web.config
ファイルにあります。 この既定の構成情報を、簡略化のため一部のマークアップを削除して次に示します。
<configuration>
<system.web>
<healthMonitoring>
<eventMappings>
<add name="All Errors" type="System.Web.Management.WebBaseErrorEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647"/>
<add name="Failure Audits" type="System.Web.Management.WebFailureAuditEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647"/>
</eventMappings>
<providers>
<add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"/>
<add connectionStringName="LocalSqlServer" maxEventDetailsLength="1073741823" buffer="false" bufferMode="Notification" name="SqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
<rules>
<add name="All Errors Default" eventName="All Errors" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom=""/>
<add name="Failure Audits Default" eventName="Failure Audits" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom=""/>
</rules>
</healthMonitoring>
</system.web>
</configuration>
対象となる稼働状況の監視イベントは、稼働状況の監視イベントのクラスにわかりやすい名前を付ける <eventMappings>
要素で定義されます。 上記のマークアップで、<eventMappings>
要素はわかりやすい名前 "All Errors" を型 WebBaseErrorEvent
の稼働状況の監視イベントに割り当て、名前 "Failure Audits" を型 WebFailureAuditEvent
の稼働状況の監視イベントに割り当てます。
<providers>
要素はログ ソースを定義し、わかりやすい名前を付け、ログ ソース固有の構成情報を指定します。 最初の <add>
要素は、EventLogWebEventProvider
クラスを使用して指定された稼働状況の監視イベントをログする "EventLogProvider" プロバイダーを定義します。 EventLogWebEventProvider
クラスは、イベントを Windows イベント ログにログします。 2 番目の <add>
要素は、SqlWebEventProvider
クラスを介して Microsoft SQL Server データベースにイベントをログする "SqlWebEventProvider" プロバイダーを定義します。 "SqlWebEventProvider" 構成は、他の構成オプションの中からデータベースの接続文字列 (connectionStringName
) を指定します。
<rules>
要素は、<eventMappings>
要素で指定されたイベントを <providers>
要素内のログ ソースに マップします。 既定では、ASP.NET Web アプリケーションは、すべてのハンドルされない例外と監査エラーを Windows イベント ログにログします。
データベースへのイベントのログ
稼働状況の監視システムの既定の構成は、アプリケーションの Web.config
ファイルに <healthMonitoring>
セクションを追加することで、Web アプリケーションごとにカスタマイズできます。 <add>
要素を使用して、<eventMappings>
、<providers>
、および <rules>
のセクションに追加の要素を含めることができます。 既定の構成から設定を削除するには、<remove>
要素を使用するか、<clear />
を使用してこれらのセクションのいずれかからすべての既定値を削除します。 SqlWebEventProvider
クラスを使用して、すべてのハンドルされない例外を Microsoft SQL Server データベースにログするように Book Reviews Web アプリケーションを構成してみましょう。
SqlWebEventProvider
クラスは稼働状況の監視システムの一部であり、稼働状況の監視イベントを指定された SQL Server データベースにログします。 SqlWebEventProvider
クラスは、指定したデータベースに aspnet_WebEvent_LogEvent
という名前のストアド プロシージャが含まれていることを想定しています。 このストアド プロシージャには、イベントの詳細が渡され、イベントの詳細を格納するタスクが課されます。 しかし、イベントの詳細を格納するために、このストアド プロシージャもテーブルも作成する必要はありません。 aspnet_regsql.exe
ツールを使用して、これらのオブジェクトをデータベースに追加できます。
Note
aspnet_regsql.exe
ツールについては、ASP.NET のアプリケーション サービスのサポートを追加したときに、"アプリケーション サービスを使用する Web サイトを構成する" チュートリアルで説明しました。 したがって、Book Reviews Web サイトのデータベースには、イベント情報を aspnet_WebEvent_Events
という名前のテーブルに格納する aspnet_WebEvent_LogEvent
ストアド プロシージャが既に含まれています。
必要なストアド プロシージャとテーブルをデータベースに追加したら、後はすべてのハンドルされない例外をデータベースにログするように、稼働状況の監視に指示するだけです。 これを実現するには、Web サイトの Web.config
ファイルに次のマークアップを追加します。
<configuration>
...
<system.web>
...
<healthMonitoring enabled="true">
<eventMappings>
<clear />
<add name="All Errors" type="System.Web.Management.WebBaseErrorEvent"
startEventCode="0" endEventCode="2147483647" />
</eventMappings>
<providers>
<clear />
<add connectionStringName="ReviewsConnectionString" maxEventDetailsLength="1073741823"
buffer="false" name="SqlWebEventProvider"
type="System.Web.Management.SqlWebEventProvider" />
</providers>
<rules>
<clear />
<add name="All Errors Default" eventName="All Errors" provider="SqlWebEventProvider"
profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" />
</rules>
</healthMonitoring>
</system.web>
</configuration>
上記の稼働状況の監視構成のマークアップでは、<clear />
要素を使用して、定義済みの稼働状況の監視構成情報を <eventMappings>
、<providers>
、および <rules>
のセクションからワイプします。 次に、これらの各セクションに 1 つのエントリを追加します。
<eventMappings>
要素は、ハンドルされない例外が生じるたびに発生する、"All Errors" という名前の対象となる単一の稼働状況の監視イベントを定義します。<providers>
要素は、SqlWebEventProvider
クラスを使用する "SqlWebEventProvider" という名前の単一のログ ソースを定義します。connectionStringName
属性が "ReviewsConnectionString" に設定されています。これは、<connectionStrings>
セクションで定義されている接続文字列の名前です。- 最後の <rules> 要素は、"All Errors" イベントが発生したときに、"SqlWebEventProvider" プロバイダーを使用してログされることを示します。
この構成情報は、すべてのハンドルされない例外を Book Reviews データベースにログするように稼働状況の監視システムに指示します。
Note
WebBaseErrorEvent
イベントはサーバー エラーに対してのみ発生します。見つからない ASP.NET リソースに対する要求などの HTTP エラーでは発生しません。 これは、サーバーと HTTP の両方のエラーで発生する HttpApplication
クラスの Error
イベントの動作とは異なります。
稼働状況の監視システムの動作を確認するには、Web サイトにアクセスし、Genre.aspx?ID=foo
にアクセスしてランタイム エラーを生成します。 例外の詳細の死のイエロー スクリーン (ローカルにアクセスした場合) またはカスタムのエラー ページ (運用環境のサイトにアクセスした場合) のどちらかエラー ページが適宜表示されるはずです。 バックグラウンドでは、稼働状況の監視システムによってエラー情報がデータベースに記録されています。 aspnet_WebEvent_Events
テーブルには 1 つのレコードが存在するはずです (図 1 を参照)。このレコードには、発生したばかりのランタイム エラーに関する情報が含まれています。
図 1: エラーの詳細が aspnet_WebEvent_Events
テーブルに記録された
(クリックするとフルサイズの画像が表示されます)
Web ページでのエラー ログの表示
Web サイトの現在の構成では、稼働状況の監視システムによって、ハンドルされない例外がすべてデータベースにログされます。 ただし、稼働状況の監視には、Web ページを介してエラー ログを表示するメカニズムはありません。 ただし、データベースからこの情報を表示する ASP.NET ページを作成することができます。 (一時的にしか表示されないので、エラーの詳細を電子メール メッセージとして送信することを選択できます。)
このようなページを作成する場合は、許可されているユーザーのみがエラーの詳細を表示できるようにするステップを実行してください。 ご利用のサイトで既にユーザー アカウントが使用されている場合は、URL 認可規則を使用して、ページへのアクセスを特定のユーザーまたはロールに制限できます。 ログインしているユーザーに基づいて Web ページへのアクセスを許可または制限する方法の詳細については、Web サイトのセキュリティに関するチュートリアルを参照してください。
Note
以降のチュートリアルでは、ELMAH という名前の、別のエラー ログおよび通知システムについて詳しく見ていきます。 ELMAH には、Web ページと RSS フィードの両方からエラー ログを表示するメカニズムが組み込まれています。
電子メールへのイベントのログ
稼働状況の監視システムには、イベントを電子メール メッセージに "ログする" ログ ソース プロバイダーが含まれています。 ログ ソースには、データベースにログされるのと同じ情報が電子メール メッセージ本文として含まれます。 このログ ソースを使用して、特定の稼働状況の監視イベントが発生したときに開発者に通知できます。
例外が発生するたびに電子メールを受信できるように、Book Reviews Web サイトの構成を更新しましょう。 これを実現するには、次の 3 つのタスクを実行する必要があります。
- 電子メールを送信するように ASP.NET Web アプリケーションを構成します。 これは、
<system.net>
構成要素を介して電子メール メッセージを送信する方法を指定することで実現されます。 ASP.NET アプリケーションで電子メール メッセージを送信する方法の詳細については、ASP.NET での電子メールの送信と System.Net.Mail に関する FAQ の記事を参照してください。 - 電子メール ログ ソース プロバイダーを
<providers>
要素に登録します。そして - ステップ (2) で追加したログ ソース プロバイダーに "All Errors" イベントをマップするエントリを
<rules>
要素に追加します。
稼働状況の監視システムには、SimpleMailWebEventProvider
と TemplatedMailWebEventProvider
という 2 つの電子メール ログ ソース プロバイダーのクラスが含まれています。 SimpleMailWebEventProvider
クラスは、イベントの詳細を含むプレーンテキストの電子メール メッセージを送信するもので、電子メール本文のカスタマイズはほとんどできません。 TemplatedMailWebEventProvider
クラスでは、レンダリングされたマークアップが電子メール メッセージの本文として使用される ASP.NET ページが指定されます。 TemplatedMailWebEventProvider
クラスを使用すると、電子メール メッセージの内容と形式をより詳細に制御できますが、電子メール メッセージの本文を生成する ASP.NET ページを作成する必要があるため、少し早めに作業する必要があります。 このチュートリアルでは、SimpleMailWebEventProvider
クラスの使用に重点を置いています。
SimpleMailWebEventProvider
クラスのログ ソースが含まれるように、Web.config
ファイルの稼働状況の監視システムの <providers>
要素を更新します。
<providers>
<clear />
<add type="System.Web.Management.SimpleMailWebEventProvider"
name="EmailWebEventProvider" buffer="false"
from="support@example.com" to="support@example.com"
subjectPrefix="Book Reviews Runtime Error: " />
<add connectionStringName="ReviewsConnectionString" maxEventDetailsLength="1073741823"
buffer="false" name="SqlWebEventProvider"
type="System.Web.Management.SqlWebEventProvider" />
</providers>
上記のマークアップでは、SimpleMailWebEventProvider
クラスをログ ソース プロバイダーとして使用して、"EmailWebEventProvider" というフレンドリ名を割り当てています。 さらに、<add>
属性には、電子メール メッセージの宛先や差出人のアドレスなどの追加の構成オプションが含まれています。
電子メール ログ ソースが定義されたら、後はこのソースを使用してハンドルされない例外を "ログする" ように稼働状況の監視システムに指示するだけです。 これを実現するには、<rules>
セクションに新しい規則を追加します。
<rules>
<clear />
<add name="All Errors To Email" eventName="All Errors" provider="EmailWebEventProvider"
profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" />
<add name="All Errors To Database" eventName="All Errors" provider="SqlWebEventProvider"
profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" />
</rules>
<rules>
セクションに、2 つの規則が含まれるようになりました。 最初の "All Errors To Email" という名前のものは、すべてのハンドルされない例外を "EmailWebEventProvider" ログ ソースに送信します。 この規則には、Web サイトのエラーに関する詳細を指定された宛先アドレスに送信する効果があります。 "All Errors To Database" 規則は、エラーの詳細をサイトのデータベースにログします。 したがって、サイトでハンドルされない例外が発生するたびに、その詳細がデータベースにログされ、指定された電子メール アドレスに送信されます。
図 2 は、Genre.aspx?ID=foo
へのアクセス時に SimpleMailWebEventProvider
クラスによって生成された電子メールを示しています。
図 2: エラーの詳細が電子メール メッセージで送信される
(クリックするとフルサイズの画像が表示されます)
まとめ
ASP.NET の稼働状況の監視システムは、管理者が配置された Web アプリケーションの正常性を監視できるように設計されています。 稼働状況の監視イベントは、アプリケーションが停止したとき、ユーザーがサイトに正常にログオンしたとき、ハンドルされない例外が発生したときなど、特定のアクションが展開されたときに発生します。 これらのイベントは、任意の数のログ ソースにログできます。 このチュートリアルでは、ハンドルされない例外の詳細をデータベースと電子メール メッセージでログする方法について説明しました。
このチュートリアルでは、稼働状況の監視を使用してハンドルされない例外をログすることに重点を置いていましたが、稼働状況の監視は、配置された ASP.NET アプリケーションの全体的な正常性を測定するように設計されており、ここでは説明されていない稼働状況の監視イベントとログ ソースが多数含まれていることに注意してください。 さらに、必要に応じて、独自の稼働状況の監視イベントとログ ソースを作成することもできます。 稼働状況の監視の詳細について関心がある場合は、まず、Erik Reitan の稼働状況の監視に関する FAQ を参照することをお勧めします。 その後、「方法: ASP.NET 2.0 で稼働状況の監視を使用する」を参照してください。
プログラミングに満足!
もっと読む
この記事で説明したトピックの詳細については、次のリソースを参照してください。