Tôi hiện đang sử dụng log4net trong ứng dụng ASP.NET MVC của mình để ghi các ngoại lệ. Cách tôi đang làm điều này là để tất cả các bộ điều khiển của tôi kế thừa từ một lớp BaseController. Trong sự kiện OnActionExecuting của BaseController, tôi ghi lại bất kỳ ngoại lệ nào có thể đã xảy ra:
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);
}
}
Điều này hoạt động tốt nếu một ngoại lệ chưa được xử lý xảy ra trong một hành động của bộ điều khiển.
Đối với lỗi 404, tôi có một lỗi tùy chỉnh được thiết lập trong web.config của mình như sau:
<customErrors mode="On">
<error statusCode="404" redirect="~/page-not-found"/>
</customErrors>
Và trong hành động trình điều khiển xử lý url "không tìm thấy trang", tôi ghi lại url ban đầu được yêu cầu:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult PageNotFound()
{
log.Warn("404 page not found - " + Utils.SafeString(Request.QueryString["aspxerrorpath"]));
return View();
}
Và điều này cũng hoạt động.
Vấn đề mà tôi gặp phải là làm thế nào để ghi lại các lỗi trên chính các trang .aspx. Giả sử tôi gặp lỗi biên dịch trên một trong các trang hoặc một số mã nội tuyến sẽ tạo ra một ngoại lệ:
<% ThisIsNotAValidFunction(); %>
<% throw new Exception("help!"); %>
Có vẻ như thuộc tính HandleError đang định tuyến lại chính xác trang này đến trang Error.aspx của tôi trong thư mục Chia sẻ, nhưng nó chắc chắn không bị phương thức OnActionExecuted của BaseController bắt giữ. Tôi đã nghĩ rằng mình có thể đặt mã ghi nhật ký trên chính trang Error.aspx, nhưng tôi không chắc về cách truy xuất thông tin lỗi ở cấp đó.