如果日志级别低于阈值,则防止昂贵的日志调用

Prevent expensive log call if log level is below threshold

如果我执行 NLog.Trace():

logger.Trace("Json: {0}", Newtonsoft.Json.JsonConvert.DeserializeObject(myObject));

我的最低等级是错误的:

<logger name="*" minlevel="Error" writeTo="mail" enabled="false" />

我的对象会被反序列化吗?是的,当然是的。但是我怎样才能避免这种情况呢?

if(logger.IsTraceEnabled)
    logger.Trace("Json: {0}", Newtonsoft.Json.JsonConvert.SerializeObject(myObject));

IsTraceEnabled

这是记录调用本身可能很昂贵(如上述情况)或重复高调用循环中的调用的好习惯。对于其他所有内容,通常不需要添加检查,因为框架本身在调用中执行相同的检查。

像这样创建一个扩展方法

public static class NlogExtensions
{
    public static void Trace(this Logger logger, string format, Func<string> func)
    {
        if (logger.IsTraceEnabled)
        {
            logger.Trace(format, func());
        }
    }
}

并将您的跟踪调用更改为

logger.Trace("Json: {0}", () => Newtonsoft.Json.JsonConvert.DeserializeObject(myObject));

所以 myObject 只有在启用跟踪时才会被序列化。

'lazy logging' 的一种方法是使用表达式(创建 returns 消息的函数委托)而不是使用直接求值:

logger.Trace(() =>"Json: "+ Newtonsoft.Json.JsonConvert.DeserializeObject(myObject));

这有其自身的缺点(委托的构造),但它可以比昂贵的方法便宜。通常,您会将其作为重载提供,并且仅在您知道评估表达式的成本很高的情况下才使用它。

参考: