如何正确实现 WebApi 2.1 的 ExceptionLogger,以便 log4net 记录方法、位置和行的正确值?
我想要实现的是一个全局异常记录器,用于在运行 .NET 4.5.1 的 WebAPI 2.1 v5.1.2 应用程序中记录所有未处理的异常。我已经阅读了很多文章,包括下面链接的一篇解释如何实现 ExceptionLogger 的文章,它工作得很好,除了我无法让 log4net 输出我真正想要记录的值。
例如,如果我从控制器记录异常,则一切都是正确的。当我从 ExceptionLogger 记录时,我从 Logger 本身获取值,而不是从引发异常的方法。我尝试了下面代码中列出的一些东西,但它们并不完全正确。这就是我得到的。
我知道文本很小,但表格显示了 log4net 写入的不同值。第一个日志来自控制器,一切都很好。第二个条目来自代码片段中的 log.Logger.Log。最后一个条目来自代码段中的 log.Error。
片段中的最后一个方法尝试使用我从 log4net 包装器的其他实现中读取的限制类型,但它只是抛出错误,如片段中所述。
那么,当使用 GLOBAL ExceptionLogger 时,我如何获得与从控制器调用时收到的值一样的值?
public class GlobalExceptionLogger: ExceptionLogger
{
//private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public override void Log(ExceptionLoggerContext context)
{
StackTrace stackTrace = new StackTrace(context.Exception);
Type methodDeclaringType = stackTrace.GetFrame(2).GetMethod().DeclaringType;
ILog log = LogManager.GetLogger(methodDeclaringType);
string message = context.ExceptionContext.Exception.Message;
//this methods works but writes the location, method name and line from this method, not the caller
//location: System.Web.Http.ExceptionHandling.ExceptionLogger.LogAsync(:0)
//method: LogAsync
//line: 0
log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, log4net.Core.Level.Error, message, context.ExceptionContext.Exception);
//this methods works but writes the location, method name and line from this method, not the caller
//location: Company.AppName.Api.GlobalExceptionLogger.Log(c:\TFS\AppName\AppName.Api\GlobalExceptionLogger.cs:38)
//method: Log
//line: 38
log.Error(message, context.ExceptionContext.Exception);
//this method throws an error in the log4net debug: log4net:ERROR loggingEvent.LocationInformation.StackFrames was null or empty.
log.Logger.Log(methodDeclaringType, log4net.Core.Level.Error, message, context.ExceptionContext.Exception);
}
}