【问题标题】:How to log stack trace using log4net (C#)如何使用 log4net (C#) 记录堆栈跟踪
【发布时间】:2012-02-16 22:05:53
【问题描述】:

如何使用log4net 记录堆栈跟踪?我正在使用.Net 版本。

他们的方式是Log.Error(ex)

谢谢

【问题讨论】:

  • 您对 Log.Error(ex) 的输出是否有特殊问题?

标签: c# log4net


【解决方案1】:

使用这个:

void Error(object message,Exception t)

原因在 void Error(object message) 的 log4net 文档中:

警告请注意,将异常传递给此方法将打印异常的名称,但不会打印堆栈跟踪。要打印堆栈跟踪,请改用void Error(object,Exception) 表单。

Error(object message, Exception t) 是记录异常数据最灵活的方式,因为它作为异常而不是对象,并且可以在附加程序中用于将日志缩小到特定异常类(而不是通过搜索一个较慢且不太一致)

所有接受消息和异常的非格式日志记录方法都有特殊版本:

namespace log4net
{
    public interface ILog
    {
        ...
        /* Log a message object and exception */
        void Debug(object message, Exception t);
        void Info(object message, Exception t);
        void Warn(object message, Exception t);
        void Error(object message, Exception t);
        void Fatal(object message, Exception t);
        ...
    }
}

【讨论】:

    【解决方案2】:

    您需要确保布局模式的定义是结构化的,以输出您想要的格式和数据。

    log4Net Pattern Layout

    用于输出日志事件的堆栈跟踪堆栈跟踪级别说明符可以用大括号括起来。例如,%stacktrace{level}。如果没有给出堆栈跟踪级别说明符,则假定为 1

    输出使用格式:type3.MethodCall3 > type2.MethodCall2 > type1.MethodCall1

    此模式不适用于 Compact Framework 程序集。

    【讨论】:

    • 1 级表示什么?我在文档中没有看到它。
    【解决方案3】:

    有两种基本形式,一种显式地接受对象和异常:

    catch(Exception ex)
    {
        // the form that takes two args has an exception as second, prints trace...
        _log.Error("My custom message", ex);
    }
    

    一个接受任何对象并对其执行ToString()

    catch(Exception ex)
    {
        // the form that takes one arg uses ToString()
        _log.Error(ex);
    }
    

    前者允许您首先在日志条目上附加更有意义的消息,以提供您想要的任何其他详细信息。后者将完成这项工作,但仅使用ToString() 打印异常详细信息,这将为您提供:

    ToString的默认实现是获取类名 抛出当前异常,消息,调用结果 内部异常上的 ToString,以及调用的结果 环境.StackTrace。如果这些成员中的任何一个是 Nothing,则其值 不包含在返回的字符串中。

    【讨论】:

      【解决方案4】:

      您可以扩展 ILog 以拥有一个仅使用堆栈跟踪记录异常的方法。

      public static void ErrorWithStackTrace(this ILog log, Exception exception)
       {
          log.Error(exception.Message,exception);
         }
      

      【讨论】:

      • 为什么不使用已经支持此功能的现有 ILog 实现?
      【解决方案5】:
      public static Logger SetIfNeededAndGetLogger(string serviceName, string methodName)
      {
          Logger logger = null;
      
          try
          {
              if (!string.IsNullOrWhiteSpace(serviceName) && !string.IsNullOrWhiteSpace(methodName))
              {
                  ILog log = null;
                  var traceSourceName = string.Format("{0}{1}", serviceName, methodName);
                  if (!string.IsNullOrWhiteSpace(traceSourceName))
                  {
                      logger = LogSources.FirstOrDefault(x => x.ServiceLogType == traceSourceName);
                      if (logger == null)
                      {
                          log = LogManager.GetLogger(traceSourceName);
                          //logger = new Logger(log, IHEService.MediLogClientGuid, traceSourceName, methodName);
                          logger = new Logger(log, System.Guid.NewGuid(), traceSourceName, methodName);
                          SetLoggingSource(logger);
                      }
                  }
              }
          }
          catch (Exception)
          {
              //silent faiure
          }
      
          return logger;
      }
      
      private static void SetLoggingSource(Logger value)
      {
          LogSources.Add(value);
      }
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
      猜你喜欢
      • 2021-02-07
      • 1970-01-01
      • 2011-04-06
      • 1970-01-01
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      • 2013-11-16
      • 2012-03-22
      相关资源
      最近更新 更多