记录抢占

问题描述:

外部记录可能很昂贵。因此,我可以关闭日志记录或提高日志记录阈值级别以减少生产模式下的日志记录(每个人都知道!)记录抢占

但是,如何调用向记录器语句提供参数的例程?

考虑记录器声明。

logger.info(“number of windows =”+ wins.size());

其中wins.size()是一个极其昂贵的操作 - 说,只是为了说明我的(错误)理解问题。

如果关闭信息日志记录,wins.size()仍然会运行。

因为当我进行调试时,wins.size()在log.info()之前首先被越过。如果是这样,如果记录器被关闭,你的策略是什么以防止记录器语句中的昂贵函数被执行?

在C#3.0中,您可以使用lambdas仅在日志记录打开时执行对日志记录功能的调用。这是例如使用C#Common.Logging

Logger.Trace(m=>m("number of windows="+wins.size())); 

其中跟踪的定义,像这样:

void Trace(Action<FormatMessageHandler> formatMessageCallback); 

和FormatMessageHandler是

public delegate string FormatMessageHandler(string format, params object[] args); 

所以会发生什么是,如果跟踪被打开了m=>m("number of windows="+wins.size())拉姆达被调用。如果它关闭,昂贵的调用窗口大小从来没有做过。

您应该始终检查是否启用日志记录级别之前,尤其是在日志记录,如果你打算记录需要特别昂贵的计算的东西。 Apache的共享记录为Java允许你把守卫领先你的代码,所以你可以这样做:

if (logger.isInfoEnabled()) { 
     logger.info("number of windows="+wins.size()); 
} 

如果信息记录被关闭,wins.size()保证不会运行。您可以使用Log4j和内置的Java记录器类来做类似的事情。

我最近在项目上采用了类似于此的策略,以避免必须在任何地方进行像logger.IsDebugEnabled()这样的检查。实质上,我从基础记录器实现中派生出来并添加了一个额外的方法,该方法接受调用了昂贵方法的Closure。传递闭包不会执行代码,直到您真正调用它。日志记录应尽可能以面向方面为导向,并且它应该无需在所有代码中进行更改即可正常工作。

在C#和Ruby中,方法是类似的:传递一个lambda或一个块,并推迟代码的执行,直到它在运行时真正需要。双赢!

This article谈论与Java有关的通用日志记录方法。优秀的阅读。