从 Log4Net 中删除堆栈跟踪的顶级



我有一个保存在类中的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);
}
}

我的异常处理程序类:

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");
}
}

根据此处的文档。%stacktrace令牌插入堆栈跟踪,引用输出日志的方法。当使用与您的模式不同的模式时,即在每个类中插入一个ILog时,这很有用。像这样:

private static log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(ThisClass));

输出异常详细信息时,可以使用%exception令牌。

但是,我使用的方法略有不同:我使用ILog接口的扩展方法预先格式化异常详细信息。

/// <summary>
/// Logs an exception as an error in the provided logger,
/// formatting message and stacktrace.
/// </summary>
/// <param name="logger"></param>
/// <param name="e"></param>
public static void ErrorFromException(this ILog logger, Exception e)
{
ErrorFromException(logger, null, e);
}
/// <summary>
/// Logs an exception as an error in the provided logger,
/// formatting message and stacktrace.
/// </summary>
/// <param name="logger"></param>
/// <param name="prefix"></param>
/// <param name="e"></param>
public static void ErrorFromException(this ILog logger, string prefix, Exception e)
{
if (logger == null) return;
if (e == null)
{
logger.Error(
"LogExtension.ErrorFromException: A null exception was formatted. Probably there is a bug in the logging call.");
return;
}
var sb = new StringBuilder(400);
if (!String.IsNullOrEmpty(prefix))
sb.AppendLine(prefix);
sb.AppendLine("Caught exception (" + e.GetType().Name + "): " + e.Message);
sb.AppendLine(e.StackTrace);
var innerEx = e;
while (innerEx.InnerException != null)
{
innerEx = innerEx.InnerException;
sb.AppendLine("Inner exception (" + innerEx.GetType().Name + "): " + innerEx.Message);
sb.AppendLine(innerEx.StackTrace);
}
sb.AppendLine();
logger.Error(sb.ToString());
}

希望对您有所帮助。

最新更新