从Log4Net删除顶级堆栈跟踪

时间:2018-08-22 17:02:18

标签: c# logging 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);
    }
}

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

1 个答案:

答案 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());
    }

希望有帮助。