カテゴリー
Microsoft

【ASP.NET MVC5】例外発生を補足して自動的にログ書き込みを行う方法

前提条件

ASP.NET MVC5 では、開発中に例外が発生しますとビューに自動的に例外情報を表示してくださいます。

本番の時も、自動的に知らせて欲しいですの!ですけれども、画面に表示するわけにはまいりません。ログに出力したいですの♪

今回、例外が発生したら自動的にログに書き込む方法を残します。

例外発生を自動的にロギングするコード

  • Global.asax ファイル を利用する。
  • Application_Error メソッド宣言には override 不要。
  • エラーは、Application_Error メソッドの引数ではなく、Server.GetLastError() で取得する。

Global.asax

protected void Application_Error(object sender, EventArgs e)
{
 var exception = Server.GetLastError();
 if (exception == null)
 {
  return;
 }
 logger.Error(exception.Message, exception);
}

無理やり発生させた結果を確認

配列を宣言して、配列の要素外の数字で値を取得しようとして、わざと例外を発生させました。

これでログファイルに例外の内容が書き込まれていれば、成功です♪

controllers\homecontroller.cs

public ActionResult About()
{
 var str = new String[] { };
 var error = str[3];
 ViewBag.Message = "Your application description page.";
 return View();
}

結果は、、、もちろん成功ですの♪画面にエラー内容が案内されたのと同じ内容が、ログファイルに記述されておりましたの!

自動的に書き込まれたログ

2015-10-22 21:12:17,048 [6] ERROR Sample1.MvcApplication [(null)] – インデックスが配列の境界外です。
System.IndexOutOfRangeException: インデックスが配列の境界外です。
場所 Sample1.Controllers.HomeController.About() 場所 C:\xxx\Visual Studio 2015\Projects\Sample1\Sample1\Controllers\HomeController.cs:行 27
場所 lambda_method(Closure , ControllerBase , Object[] )
場所 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
場所 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters)
場所 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 parameters)
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d()
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.b__3f()
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.b__32(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.b__1c()
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.b__1e(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
場所 System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
場所 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
場所 System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult, Controller controller)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
場所 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
場所 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
場所 System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
場所 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
場所 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
場所 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
場所 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

課題

  • ロガー名が、Sample1.MvcApplication などとなる。これは例外発生した場所ではない、ログ処理を発生させた Global.asax である、という問題がある。
    ※スタックトレースを読むと場所がわかることが多いけれども。

おわりに

次のページが Global.asax の Application_Error メソッドへの書き方で大変参考になりました。このページは、エラー画面の表示方法も解説されており、総合的に参考にできる素晴らしいページでした♪ありがとう存じます。

以上です。

コメントを残す