現在、ASP.NET MVCアプリケーションでlog4netを使用して、例外をログに記録しています。これを行う方法は、すべてのコントローラーにBaseControllerクラスを継承させることです。BaseControllerのOnActionExecutingイベントで、発生した可能性のある例外をログに記録します。
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Log any exceptions
ILog log = LogManager.GetLogger(filterContext.Controller.GetType());
if (filterContext.Exception != null)
{
log.Error("Unhandled exception: " + filterContext.Exception.Message +
". Stack trace: " + filterContext.Exception.StackTrace,
filterContext.Exception);
}
}
これは、コントローラーのアクション中に未処理の例外が発生した場合に適切に機能します。
404エラーについては、web.configで次のようにカスタムエラーを設定しています。
<customErrors mode="On">
<error statusCode="404" redirect="~/page-not-found"/>
</customErrors>
そして、「page-not-found」URLを処理するコントローラーアクションで、リクエストされた元のURLをログに記録します。
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult PageNotFound()
{
log.Warn("404 page not found - " + Utils.SafeString(Request.QueryString["aspxerrorpath"]));
return View();
}
そして、これも機能します。
私が抱えている問題は、.aspxページ自体にあるエラーをログに記録する方法です。例外をスローするページまたはインラインコードのいずれかにコンパイルエラーがあるとします。
<% ThisIsNotAValidFunction(); %>
<% throw new Exception("help!"); %>
HandleError属性は、これをSharedフォルダーのError.aspxページに正しく再ルーティングしているようですが、BaseControllerのOnActionExecutedメソッドによって確実にキャッチされていません。Error.aspxページ自体にログコードを配置できると考えていましたが、そのレベルでエラー情報を取得する方法がわかりません。