현재 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());
}
답변
답변
Error.aspx보기는 다음과 같이 정의됩니다.
namespace MvcApplication1.Views.Shared
{
public partial class Error : ViewPage<HandleErrorInfo>
{
}
}
HandleErrorInfo에는 세 가지 속성이 있습니다. string ActionName string ControllerName Exception Exception
HandleErrorInfo에 액세스 할 수 있어야하므로 뷰 내에서 예외가 발생합니다.
답변
HttpContext.Error를 검사 해 볼 수 있지만 확실하지 않습니다.