前提条件
- log4net 導入済み。↓参考
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)
2 parameters)
場所 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
場所 System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult)
1.End()
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
場所 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)
1.End()
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
場所 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)
1.End()
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
場所 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)
1.End()
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
場所 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)
1.End()
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
場所 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)
1.End()
場所 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
場所 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 メソッドへの書き方で大変参考になりました。このページは、エラー画面の表示方法も解説されており、総合的に参考にできる素晴らしいページでした♪ありがとう存じます。
以上です。