Prevent expensive log call if log level is below threshold

廉价感情. 提交于 2019-12-07 17:49:31

问题


If I do a NLog.Trace():

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

And my minlevel is on Error:

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

Will my object be deserialized for nothing? Yes, of course yes. But how can I avoid this?


回答1:


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

See IsTraceEnabled.

This is good practice for logging calls where the call itself can be expensive (like in your case above) or in a repetitive high call loop. For everything else there usually is no need to add the check as there framework itself performs the same check inside the call.




回答2:


Create an extension method like such

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

And change your call of trace to

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

So the myObject will only be serialized when the trace is enabled.




回答3:


One approach to 'lazy logging' is to use an expression (to create a function delegate that returns the message) rather than using direct evaluation:

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

This has its own downsides (construction of the delegate), but it can be cheaper than the expensive method. Typically you would provide this as an overload and only use it in the case where you know evaluating the expression is expensive.

Reference: https://stackoverflow.com/a/8347895/2073920



来源:https://stackoverflow.com/questions/39036258/prevent-expensive-log-call-if-log-level-is-below-threshold

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!