从 Log4Net 中删除顶层堆栈跟踪
Remove top levels of stacktrace from Log4Net
我有一个保存在 class 中的 log4net 实现,并且 class 是从静态 ExceptionHandler
class 访问的(以避免更改一堆用法,因为这是遗留代码库)。因此,当记录异常时,它们看起来像这样:
System.Timers.Timer.MyTimerCallback >
InternalMethod1 >
InternalMethod2 >
ExceptionHandler.HandleException >
Logger.Log
我真的不希望最后两个出现在调用堆栈中,因为它们混淆了错误实际记录的位置,即 InternalMethod2
。但是,我看到这样做的唯一方法是将实际记录器暴露给 InternalMethod2
,我也不想这样做。
有什么方法可以管理我的堆栈跟踪以使其准确显示情况?
我的记录器Class:
public class Logger : ILogger
{
public void Log(Exception ex, string message)
{
log4net.LogManager.Get("MyLog").Error(ex, message);
}
}
我的异常处理程序class:
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");
}
}
根据文档 here。
%stacktrace
标记插入引用输出日志的方法的堆栈跟踪。这在使用与您不同的模式时很有用,即在每个 class 中插入一个 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());
}
希望对您有所帮助。
我有一个保存在 class 中的 log4net 实现,并且 class 是从静态 ExceptionHandler
class 访问的(以避免更改一堆用法,因为这是遗留代码库)。因此,当记录异常时,它们看起来像这样:
System.Timers.Timer.MyTimerCallback >
InternalMethod1 >
InternalMethod2 >
ExceptionHandler.HandleException >
Logger.Log
我真的不希望最后两个出现在调用堆栈中,因为它们混淆了错误实际记录的位置,即 InternalMethod2
。但是,我看到这样做的唯一方法是将实际记录器暴露给 InternalMethod2
,我也不想这样做。
有什么方法可以管理我的堆栈跟踪以使其准确显示情况?
我的记录器Class:
public class Logger : ILogger
{
public void Log(Exception ex, string message)
{
log4net.LogManager.Get("MyLog").Error(ex, message);
}
}
我的异常处理程序class:
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");
}
}
根据文档 here。
%stacktrace
标记插入引用输出日志的方法的堆栈跟踪。这在使用与您不同的模式时很有用,即在每个 class 中插入一个 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());
}
希望对您有所帮助。