[asp.net-mvc] ASP.NET MVC에서 오류 로깅

현재 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 페이지 자체에 로깅 코드를 넣을 수 있다고 생각했지만 해당 수준에서 오류 정보를 검색하는 방법을 잘 모르겠습니다.



답변

Elmah 를 연결하여 웹 애플리케이션을 단순화하는 것을 고려할 것 입니다.

Elmah 어셈블리를 프로젝트에 추가 한 다음 web.config를 구성합니다. 그런 다음 컨트롤러 또는 페이지 수준에서 생성 된 예외를 기록합니다. 다양한 장소 (SQL Server, 이메일 등)에 기록하도록 구성 할 수 있습니다. 또한 웹 프런트 엔드를 제공하므로 예외 로그를 ​​탐색 할 수 있습니다.

내가 만든 asp.net mvc 앱에 가장 먼저 추가 한 것입니다.

나는 여전히 log4net을 사용하지만 디버그 / 정보 로깅에 사용하는 경향이 있으며 모든 예외는 Elmah에 남겨 둡니다.

ASP.NET 앱에서 오류 (예외)를 기록하는 방법 질문에서 자세한 정보를 찾을 수도 있습니다 . .


답변

Global.asax에서 OnError 이벤트에 연결할 수 있습니다.

이 같은:

/// <summary>
/// Handles the Error event of the Application control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void Application_Error(object sender, EventArgs e)
{
    if (Server != null)
    {
        Exception ex = Server.GetLastError();

        if (Response.StatusCode != 404 )
        {
            Logging.Error("Caught in Global.asax", ex);
        }

    }


}


답변

MVC3

HandleErrorInfoAttribute에서 상속되고 선택한 로깅을 포함하는 속성 만들기

public class ErrorLoggerAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        LogError(filterContext);
        base.OnException(filterContext);
    }

    public void LogError(ExceptionContext filterContext)
    {
       // You could use any logging approach here

        StringBuilder builder = new StringBuilder();
        builder
            .AppendLine("----------")
            .AppendLine(DateTime.Now.ToString())
            .AppendFormat("Source:\t{0}", filterContext.Exception.Source)
            .AppendLine()
            .AppendFormat("Target:\t{0}", filterContext.Exception.TargetSite)
            .AppendLine()
            .AppendFormat("Type:\t{0}", filterContext.Exception.GetType().Name)
            .AppendLine()
            .AppendFormat("Message:\t{0}", filterContext.Exception.Message)
            .AppendLine()
            .AppendFormat("Stack:\t{0}", filterContext.Exception.StackTrace)
            .AppendLine();

        string filePath = filterContext.HttpContext.Server.MapPath("~/App_Data/Error.log");

        using(StreamWriter writer = File.AppendText(filePath))
        {
            writer.Write(builder.ToString());
            writer.Flush();
        }
    }

Global.asax RegisterGlobalFilters에 특성 배치

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
       // filters.Add(new HandleErrorAttribute());
        filters.Add(new ErrorLoggerAttribute());
    }


답변

HandleError 속성을 확장하는 것에 대해 생각해 보셨습니까? 또한 Scott은 여기 에 컨트롤러 / 액션의 필터 인터셉터에 대한 좋은 블로그 게시물이 있습니다 .


답변

Error.aspx보기는 다음과 같이 정의됩니다.

namespace MvcApplication1.Views.Shared
{
    public partial class Error : ViewPage<HandleErrorInfo>
    {
    }
}

HandleErrorInfo에는 세 가지 속성이 있습니다. string ActionName string ControllerName Exception Exception

HandleErrorInfo에 액세스 할 수 있어야하므로 뷰 내에서 예외가 발생합니다.


답변

HttpContext.Error를 검사 해 볼 수 있지만 확실하지 않습니다.


답변