.NET TIPS

[ASP.NET]アプリケーション内で発生したエラー情報をロギングするには?

山田 祥寛
2004/06/11

 別稿「TIPS:[ASP.NET]独自のエラー・ページを設定するには?」でも紹介したように、ASP.NETでは、構成ファイルweb.configの<customErrors>要素を設定することで、アプリケーション独自のエラー・ページを設定できる。

 リダイレクト先のエラー・ページは、静的なHTMLファイルでも、動的なWebフォーム(.aspxファイル)でも構わないが、後々のメンテナンスなどを考慮した場合には、できるだけ静的なHTMLファイルにしておくのが好ましいだろう。というのも、実運用中のアプリケーションでは、障害発生時に必ずしもASP.NETアプリケーションに精通した人間がエラー・ページをメンテナンスするとは限らないからだ。障害状況、復旧の予定などのコンテンツをASP.NETプログラマでない人間でも間違いなく更新するには、静的なHTMLファイルが無難であることは間違いない。

 しかし、エラー・ページの役割は、何も一般ユーザーに障害情報などを知らせるばかりではない。障害復旧のために例外発生時の状況をロギングしたい、そもそもの障害発生をリアルタイムにシステム管理者にメール通知したい、などのケースも多々あるはずだ。このようなケースでも、個々のエラー・ページにプログラム・コードを記述しなくても済むよう、ASP.NETではアプリケーション共通のエラー処理を規定するための方法を提供している。それがGlobal.asaxだ。

 Global.asaxについては、別稿「TIPS:[ASP.NET]アプリケーション共通のロギングを行うには?(Global.asax編)」でも詳説しているので、あわせて参照してほしい。Global.asaxでは、クライアントからの要求ごとに必ず発生する「リクエスト・イベント」のほかに、以下のような「条件付きイベント」を規定している。

 条件付きイベントは、リクエスト・イベントとは異なり、セッションが開始されたタイミングなど、ある特定の条件を満たした場合にだけ発生するイベントだ。次の表に、Global.asaxで用意されている6つの条件付きイベントをまとめておく。

イベント・ハンドラ 呼び出されるタイミング
Application_OnStart アプリケーションの初回起動時に発生。アプリケーション変数など、アプリケーションで利用するリソースを初期化するために使用する
Session_OnStart ユーザー・セッションの初回起動時に発生。セッション変数など、セッション内部で使用するリソースを初期化するために使用する
Session_OnEnd ユーザー・セッションの終了時に発生(ただし、インプロセス・モードの場合のみ)。セッション内で使用したリソースを解放するために使用する
Application_OnEnd アプリケーションが破棄されたタイミングで発生。アプリケーション変数など、アプリケーションで利用するリソースを初期化するために使用する
Application_OnDisposed CLRがASP.NETアプリケーションを最終的にメモリから破棄するタイミングで発生。本イベントを利用するケースはほとんどない
Application_OnError アプリケーション内で処理されない例外が発生した場合に発生。主にその例外を処理するために使用する
Global.asaxが対応している条件付きイベント

 本稿では、アプリケーション内で処理されない例外(エラー)が発生した場合に呼び出されるApplication_OnErrorイベント・ハンドラを利用して、アプリケーション共通のエラー・ロギング処理を実装してみることにしよう。具体的な記述例は次のようになる。

<%@ Application Description="Insider.NET Sample" %>
<%@ Import Namespace="System.IO" %>
<script Language="VB" runat="Server">
Sub Application_OnError(sender As Object, e As EventArgs)
  ' ログ・ファイルerr.logへの出力ストリームを生成
  Dim objSw As New StreamWriter( _
    Server.MapPath("/netIns/err.log"), _
    True,Encoding.GetEncoding("Shift_JIS"))
  ' 最後に発生したエラーの原因情報をExceptionオブジェクトとして取得
  Dim objErr As Exception=Server.GetLastError().InnerException
  ' 日付、ソース・コード、エラー・メッセージ、エラー原因となった
  ' メソッドをタブ区切りテキストで記録

  Dim objBld As New StringBuilder()
  objBld.Append(DateTime.Now.ToString())
  objBld.Append(Chr(9))
  objBld.Append(objErr.Source)
  objBld.Append(Chr(9))
  objBld.Append(objErr.Message)
  objBld.Append(Chr(9))
  objBld.Append(objErr.TargetSite.ToString())
  objSw.WriteLine(objBld.ToString())
  objSw.Close()
End Sub
</script>
エラー情報をロギングする処理を実装したGlobal.asax(VB.NET版)
Application_OnErrorイベント・ハンドラを利用して、アプリケーション共通のエラー・ロギングを実現している。
 
<%@ Application Description="Insider.NET Sample" %>
<%@ Import Namespace="System.IO" %>
<script Language="C#" runat="Server">
void Application_OnError(Object sender, EventArgs e) {
  // ログ・ファイルerr.logへの出力ストリームを生成
  StreamWriter objSw = new StreamWriter(
    Server.MapPath("/netIns/err.log"),
    true,Encoding.GetEncoding("Shift_JIS"));
  // 最後に発生したエラー原因情報をExceptionオブジェクトとして取得
  Exception objErr = Server.GetLastError().InnerException;
  // 日付、ソース・コード、エラー・メッセージ、エラー原因となった
  // メソッドをタブ区切りテキストで記録

  StringBuilder objBld = new StringBuilder();
  objBld.Append(DateTime.Now.ToString());
  objBld.Append("\t");
  objBld.Append(objErr.Source);
  objBld.Append("\t");
  objBld.Append(objErr.Message);
  objBld.Append("\t");
  objBld.Append(objErr.TargetSite.ToString());
  objSw.WriteLine(objBld.ToString());
  objSw.Close();
}
</script>
エラー情報をロギングする処理を実装したGlobal.asax(C#版)
Application_OnErrorイベント・ハンドラを利用して、アプリケーション共通のエラー・ロギングを実現している。

 以上のGlobal.asaxファイルをアプリケーション・ルートの直下に配置すれば完了だ。アプリケーション配下の任意のファイル(サブフォルダを含む)で何かしら例外が発生した場合、自動的にその例外情報がログ・ファイル「err.log」に記録されていく。

ログ・ファイル「err.log」に記録された例外情報の例

 本稿では、単なるロギングの仕組みを紹介しているだけだが、冒頭で挙げたように、Windowsのイベント・ログに例外情報を記録したり、あらかじめ登録しておいた管理者にメール通知を行ったりすることも可能である。詳細については、後日公開予定の別稿「TIPS:[ASP.NET]アプリケーション内で発生したエラー情報をアプリケーション管理者に通知するには?」を参照いただきたい。End of Article

カテゴリ:Webフォーム 処理対象:ログ
カテゴリ:Webフォーム 処理対象:Global.asax
関連TIPS:[ASP.NET]独自のエラー・ページを設定するには?
関連TIPS:[ASP.NET]アプリケーション共通のロギングを行うには?(Global.asax編)
関連TIPS:[ASP.NET]アプリケーション内で発生したエラー情報をアプリケーション管理者に通知するには?(後日公開予定)
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]独自のエラー・ページを設定するには?
[ASP.NET]アプリケーション共通のロギングを行うには?(Global.asax編)
[ASP.NET AJAX]非同期通信時に発生した例外情報をロギングするには?
[ASP.NET AJAX]非同期通信で発生した例外の処理方法を変更するには?
[ASP.NET]アプリケーション共通のロギングを行うには?(HTTPモジュール編)
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間