我有一个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");
}
}
答案 0 :(得分:1)
根据文档here。
%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());
}
希望有帮助。