命名记录器上的log4net策略?

Jih*_*Han 5 logging log4net

我通常在每个班级中声明以下内容:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
            System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Run Code Online (Sandbox Code Playgroud)

并使用每个类中的静态成员来记录不同的级别(信息,调试等)

我在某个地方看到并且一直在使用它有点盲目,推断设置足够灵活,可以帮助我按命名空间过滤并记录各个类型,如果我想解决生产问题而不是.

但我很少使用精细伐木的"水平".所以,我想看看其他人在使用什么.您是否使用上述内容,因为我感觉很多人正在使用它,或者您是否创建了命名记录器,如"debug","trace","error","moduleA"等,并在不同类型之间共享记录器,组装?

Pet*_*old 11

我基本上用

public class MyClass
{
    private static readonly ILog log = Log.Get<MyClass>();
}
Run Code Online (Sandbox Code Playgroud)

其中Log.Get是一个基本上在内部执行此操作的类

return LogManager.GetLogger(typeof(T));
Run Code Online (Sandbox Code Playgroud)

启动成本甚至小于反射方式以及更清洁的imo.

更新:鉴于我以后几年的依赖注入,单元测试和假货的经验,我不能再说我宽恕上面概述的方法.该方法(我的和OP的方法)的问题在于代码具有关于如何创建日志实例的明确知识.

一方面,这种增加的耦合使得测试更加困难:没有简单的方法用ILog假的实例替换实例.另一方面,对我的Log类进行的更改将导致所有使用它的类中的更改波动.

因此,我走的路线注入ILog情况下,通常是通过构造函数注入,以及外包如何构建一个记录器选择我的DI框架:

public class MyClass
{
    readonly ILog _log;

    public class MyClass(ILog log)
    {
        _log = log;
    }
}
Run Code Online (Sandbox Code Playgroud)

这允许适当的去耦.代码不再需要知道如何构造记录器.大多数依赖注入框架都具有查看正在注入的类型然后使用它来构造日志实例的方法.这是log4net和Autofac方法.


emp*_*mpi -1

最近,我创建了这样的东西:

public static class Logger
{
    private static bool isLoaded = false;       

    public static ILog Log
    {
        get
        {
            System.Reflection.MethodBase method;
            method = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod();
            StringBuilder loggerName = new StringBuilder();
            loggerName.AppendFormat("{0}.{1}(", method.ReflectedType.FullName, method.Name);

            ParameterInfo[] parameters = method.GetParameters();
            string[] parametersStr = new string[parameters.Length];

            if (parameters.Length > 0)
            {
                for (int i = 0; i < parameters.Length; i++)
                {
                    parametersStr[i] = parameters[i].ToString();
                }
                loggerName.Append(String.Join(", ", parametersStr));
            }

            loggerName.Append(")");

            return GetLogger(loggerName.ToString());
        }
    }


    private static ILog GetLogger(string loggerName)
    {
        if (!isLoaded)
        {
            log4net.Config.XmlConfigurator.Configure();
        }
        return LogManager.GetLogger(loggerName);
    }
}
Run Code Online (Sandbox Code Playgroud)

它允许我使用 log4net,而无需在我需要使用它的每个类中创建其实例,并且我仍然可以获得记录操作的类名和方法。

使用示例:

Logger.Log.DebugFormat("Response [{0}]", xmlResponse);
Run Code Online (Sandbox Code Playgroud)

  • 你对此运行过分析器吗?这头野兽的执行速度是巨大的。即使您想在生产中关闭 DEBUG 日志记录级别,您也会产生相同的成本。如果您确实需要记录器中的方法名称,我可以在某种程度上明白这一点,但话又说回来,当发生异常时,您无论如何都会在异常堆栈跟踪中获得该名称...... (2认同)