如何正确实现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包装器的其他实现中读取了它,但它只是抛出了一个错误,如代码片段中所述。
那么,如果使用全局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);
}
}
答案 0 :(得分:4)
建议不要使用获取堆栈跟踪的方法,因为代码在调试/发布或前置体系结构上的行为会有所不同。方法stackTrace.GetFrame(2).GetMethod()将为您提供实际堆栈上的方法,同时考虑处理器体系结构的运行时优化,linq重写等。
获取成员名称的另一种方法:
public static string LogError(Exception ex, [CallerMemberName] string callerName = "")
你应该看看这个问题: