不调试时的 Log4Net 消息构建成本 [英] Log4Net message construction cost when not debugging

查看:55
本文介绍了不调试时的 Log4Net 消息构建成本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 log4net文章,您应该检查如果在任何Log.Debug语句之前启用了调试,以消除该语句的构建成本.除了总是必须在任何日志语句之前检查if(Log.IsDebugEnabled)之外,还有其他更好的选择吗?

According to this log4net article you should check if debug is enabled prior to any Log.Debug statements to eliminiate the statement construction cost. Is there a better alternative to always having to check if(Log.IsDebugEnabled) prior to any log statements?

Log4Net示例:

Log4Net example:

if (log.IsDebugEnabled)
{ 
    log.Debug("This is entry number: " + i );
}

我不想支付语句构建的间接费用,但也不想在每个日志语句之前进行检查.

I don't want to pay the overhead cost of statement construction, but also don't want to check prior to every log statement.

推荐答案

但也不想在每个日志语句之前检查

but also don't want to check prior to every log statement

当您发现自己一遍又一遍地重复相同的代码时,听起来好像是一个通用的抽象顺序.在这种情况下,您可以例如为Log4Net创建自定义包装.就像这样简单:

When you find yourself repeating the same code over and over, it sounds like a common abstraction may be in order. In this case you can, for example, create a custom wrapper for Log4Net. Something as simple as:

public static class Logger
{
    private static ILog _log;

    static Logger()
    {
        log4net.Config.XmlConfigurator.Configure();
        _log = log4net.LogManager.GetLogger("Log4Net");
    }

    public static void Debug(string message)
    {
        if (_log.IsDebugEnabled)
            _log.Debug(message);
    }

    public static void Info(string message)
    {
        _log.Info(message);
    }

    public static void Warn(string message)
    {
        _log.Warn(message);
    }

    public static void Error(string message)
    {
        _log.Error(message);
    }

    public static void Error(string message, Exception ex)
    {
        _log.Error(message, ex);
    }

    public static void Fatal(string message)
    {
        _log.Fatal(message);
    }

    public static void Fatal(string message, Exception ex)
    {
        _log.Fatal(message, ex);
    }
}

在这种情况下,我将记录器实例设为静态.我不确定 100%是否会一直按预期工作.通常,我在依赖项注入框架后面使用它,并将记录器依赖项配置为由框架处理的单例.您可以改为使用实例方法将此实例设置为实例类,然后将其放在静态工厂类的后面.测试并根据需要进行调整.

In this case I made the logger instance static. I'm not 100% sure that will always work as expected. Normally I use this behind a dependency injection framework and configure the logger dependency to be a singleton, handled by the framework. You might instead make this an instance class with instance methods and put it behind a static factory class instead. Test and tweak as necessary.

这里有几个附加好处:

  1. 您在Log4Net中的依赖关系被隔离为一个类.因此,如果您想使用其他记录器,则只需更改一个类,而不需要更改整个项目中的所有内容.
  2. 您可以轻松地将其抽象到依赖项注入器后面.
  3. 要在所有日志记录语句中包含的任何其他常见功能都可以在此处轻松地全局包含.

我通常用于获得第三个好处的示例可能是这样的:

An example I commonly use for the third benefit might be something like this:

private static string GetLocation()
{
    var frame = new StackTrace(1).GetFrame(1);
    var method = frame.GetMethod();
    return string.Format("{0}:{1}.{2}({3})", Environment.MachineName, method.ReflectedType.FullName, method.Name, frame.GetFileLineNumber().ToString());
}

这将从运行时系统中获取更有意义的调试信息(尽管可能会影响性能,但对于大容量系统而言,它值得测试).所以我的传递错误日志记录功能可能看起来像这样:

This gets more meaningful debugging information from the runtime system (though there may be a performance hit, for high-volume systems it's worth testing). So my pass-through error logging function might look like this:

public void Error(string message, Exception ex)
{
    _log.Error(string.Format("{0}:{1}", GetLocation(), message), ex);
}

这篇关于不调试时的 Log4Net 消息构建成本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆