ILogger.Log方法declaringType参数

当我想使用log4net提供的不同日志级别时,我发现我需要使用ILogger.Log方法,它看起来像这样:

void Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception);

我们可以从我们通常的ILog引用中获得一个ILogger引用来调用此方法,并且通常建议将此调用包装为扩展方法。 我们得到的是以下内容:

//typical log4net ILog reference
private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

//suggested extension method
public static void Trace(this ILog logger, object message, Exception e)
{
    logger.Logger.Log(MethodBase.GetCurrentMethod().DeclaringType, log4net.Core.Level.Trace, message, e);
}

我注意到反射调用来获取声明类型看起来是多余的。 当我们检索到ILog引用时,我们已经将声明类型传递给了GetLogger。 为什么我们需要将另一个类型引用传递给Log方法,我们正在调用ILogger引用,该引用是从我们的ILog引用中检索的。 更重要的是,扩展方法中的声明类型将是包含扩展方法的类。 使用Log4NetExtensions等类名记录所有跟踪日志将毫无意义。 最后,反射应该是昂贵的,即使反思当前的方法可能会更便宜,每次我们登录时声音反射代码听起来不对。 所以我决定做一个测试:

//I just created a logger
var logger = logManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

//and then I called Log with different type parameters
logger.Logger.Log(MethodBase.GetCurrentMethod().DeclaringType, log4net.Core.Level.Info, "hello!", null);
logger.Logger.Log(logger.GetType(), log4net.Core.Level.Info, "hello!", null);
logger.Logger.Log(null, log4net.Core.Level.Info, "hello!", null);
logger.Logger.Log(typeof(System.Console), log4net.Core.Level.Info, "hello!", null);

生成的日志如下所示:

INFO  2015-05-29 11:06:57,200 [9] Foo.Program - hello!
INFO  2015-05-29 11:06:57,207 [9] Foo.Program - hello!
INFO  2015-05-29 11:06:57,207 [9] Foo.Program - hello!
INFO  2015-05-29 11:06:57,207 [9] Foo.Program - hello!

所以,这个方法的类型参数似乎被忽略了。 这很令人费解。 任何人都可以确认或否认这些结果? 有谁知道为什么这种方式的工作方式? 我打算为这个参数创建我的扩展方法为null。 你会建议一样吗? 我错过了什么吗?

以下是答案建议在扩展方法中使用声明类型的问题:

Log4net创建自定义级别

为什么log4Net中没有跟踪级别?

Log4net,如何记录详细的消息?


您传递给LogManager.GetLogger的类型用于命名返回的记录器,这就是为什么所有日志记录调用都标记为“Foo.Program”的原因。

传递给Logger.Log的类型虽然是“该调用的日志记录系统中堆栈边界的方法的声明类型”,用于确定在哪里停止记录堆栈跟踪 - 这是内部需要的,否则堆栈跟踪将包括log4net内部方法。

你当然可以创建一个扩展方法,它传递null作为callerStackBoundaryDeclaringType ,因为它将内部默认为typeof(Logger)


你不应该像你所建议的那样创建一个扩展方法。

因为ILog Logger是静态的,所以使用它作为参数值没有多大意义。 按照以下方式使用Log4Net:

private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // that part was ok

public static void Trace(object message, Exception e)
{
   Logger.DebugFormat(message, e); // Use InfoFormat or something else if needed
}

如果您仅使用标准功能,则直接调用DebugFormat()(或其他):

try {
  int i=7/0;
} catch (Exception e){
  Logger.ErrorFormat("Looks like you are not Jon Skeet",e); 
}

如果你没有添加任何东西,创建你自己的“跟踪” - 方法是没有意义的。

另外它(通常)在您记录某些内容时设置类型是没有意义的,但只有在初始化日志记录器

链接地址: http://www.djcxy.com/p/85491.html

上一篇: ILogger.Log method declaringType parameter

下一篇: How to use Serilog with Unity?