命名记录器上的log4net策略?

时间:2009-01-13 14:42:41

标签: logging log4net

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

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
            System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

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

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

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

4 个答案:

答案 0 :(得分:11)

我基本上使用

public class MyClass
{
    private static readonly ILog log = Log.Get<MyClass>();
}

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

return LogManager.GetLogger(typeof(T));

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

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

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

因此,我通常通过构造函数注入注入 ILog实例的路径,并将如何构建记录器外包给{{3} }:

public class MyClass
{
    readonly ILog _log;

    public class MyClass(ILog log)
    {
        _log = log;
    }
}

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

答案 1 :(得分:2)

以原始方式执行此操作的成本是ILog实现的一个实例,以及在启动时运行“System.Reflection.MethodBase.GetCurrentMethod()。DeclaringType”所需的时间。

我记得几年前看过它,我们的启动成本是每10000班1秒,而每10k班不到1兆。

鉴于成本如此之低,鉴于log4net提供了令人难以置信的灵活性,我从未回头。

注意:我不能在这里评论其他解决方案,因为我是新手......但是这一行:

method = new System.Diagnostics.StackTrace()。GetFrame(1).GetMethod();

昂贵,尤其是在每个日志消息都被调用时。

答案 2 :(得分:0)

可用于记录的工具是PostSharp(http://www.postsharp.org/)。有付费和免费(快递)版本。我只用它来记录方法边界,但我知道你也可以用它来处理错误。在两者之间,这将满足您的大多数日志记录需求,而无需在每个类中编写代码。

答案 3 :(得分:-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);
    }
}

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

样本用法:

Logger.Log.DebugFormat("Response [{0}]", xmlResponse);