【发布时间】:2018-08-22 17:02:18
【问题描述】:
我有一个 log4net 实现,它保存在一个类中,该类是从静态 ExceptionHandler 类访问的(以避免更改一堆用法,因为这是一个遗留代码库)。因此,当记录异常时,它们看起来像这样:
System.Timers.Timer.MyTimerCallback >
InternalMethod1 >
InternalMethod2 >
ExceptionHandler.HandleException >
Logger.Log
我真的不希望最后两个出现在调用堆栈中,因为它们混淆了实际记录错误的位置,即InternalMethod2。但是,我看到这样做的唯一方法是将实际记录器暴露给InternalMethod2,我也不想这样做。
有没有一种方法可以整理我的堆栈跟踪,以便准确地显示情况?
我的记录器类:
public class Logger : ILogger
{
public void Log(Exception ex, string message)
{
log4net.LogManager.Get("MyLog").Error(ex, message);
}
}
我的 ExceptionHandler 类:
public static class ExceptionHandler
{
private readonly static Logger MyLogger = new Logger();
HandleException(Exception ex, string message)
{
MyLogger.Log(ex, message);
}
}
我在InternalMethod2的电话:
void InternalMethod2()
{
// do some stuff
try
{
// do other stuff
}
catch (Exception e)
{
ExceptionHandler.HandleException(e, "An error occurred");
}
}
【问题讨论】:
-
能否将代码包含在 ExceptionHandler、Logger.Log 和 InternalMethod2 示例中?
-
@A.Chiesa 我已经这样做了。如您所见,调用堆栈将显示在我的记录器类中“抛出”的异常。此外,
%location变量将显示我的记录器类的位置 -
代码是完整的还是简化的?您的代码中没有任何内容可能会更改异常的堆栈跟踪。寻找
throw e;呼叫而不是throw;。 -
@A.Chiesa 代码已简化,但所有
throw语句都出现在方法内或方法调用的方法内。我在进行转换时发现了几个throw e;语句,我更改了这些语句,但Logger.Log中没有出现任何语句。此外,我正在谈论的堆栈跟踪是一个log4net变量,所以我不确定它是如何设置的 -
您使用了错误的模式:%exception 标记格式化异常文本包括异常的堆栈跟踪。相反,您使用的是 %stacktrace 令牌,根据文档 (logging.apache.org/log4net/release/sdk/?topic=html/…),它指的是日志调用的堆栈跟踪。就个人而言,我更喜欢自己预先格式化异常,解开最终的内部异常,为包中的每个异常记录消息和堆栈跟踪。