题
像许多log4j用户,我们往往必须调试水平记录,是昂贵的评估。因此,我们保护这些情况代码,如:
if( _logger.isDebugEnabled )
_logger.debug("Interesting, my foojes are goofed up: " + getFullDetails())
然而,这是丑陋的不单单是一个_logger.调试呼吁,而有时该程序并没有意识到评估可能是昂贵的。
现在看来似乎应该相当简单的编写程序,需要编译罐和警卫的所有_logger.调试话与isDebugEnabled检查。我们可能愿意接受的额外开销的检查isDebugEnabled在所有情况。
有没有人尝试过这种做法,或者做类似的后处理的一个罐子里?
解决方案
你看过 AspectJ 吗?这支持使用字节码编织的方面,并且可以拦截到以前编译的.jar文件
其他提示
我没有考虑修改jar,而是使用字节码仪表。问题是要识别要包装在 .isDebugEnabled()
中的代码部分 - 您必须识别仅用于log4j调用的对象。
我相信一个好的解决办法是, 该守则将是有效的,为的是.
考虑log4j已被否决。它的作者本身离开它,以避免破坏兼容性,但是他创造了一个新的一个,SLF4J(http://www.slf4j.org/ ).他提供了一个门面和执行情况,根据区分公共记录/log4j,但是没有缺陷的每一个...
我认为,在这个新的记录工具,可以发送对象参数,以记录和水平进行评估之前转换的对象(字符串或其他行为)。想法是使用一种格式串,并参数。
我们的代码不使用slf4j,但我们具有实用方法,这样做。它是编码的大致如下(从存储器):
public enum LogLevel {
FATAL, ERROR, WARNING, INFO, DEBUG;
public void log(Logger logger, String format, Object... parameters) {
if (isEnabled(logger)) {
logImpl(logger, String.format(format, parameters));
}
}
public boolean isEnabled(Logger logger) {
switch(this) {
case WARNING : return logger.isWarningEnabled();
case INFO : return logger.isInfoEnabled();
case DEBUG : return logger.isDebugEnabled();
default: return true;
}
}
private void logImpl(Logger logger, String message) {
switch(this) {
case WARNING : logger.warn(message);
// other cases
}
}
}
它是作为:
public void myMethod(Object param) {
LogLevel.WARNING.log(LOGGER, "What is my message ....", "myMethod", param);
}
更新 :如果你需要打电话的方法的日志...
一种可能性是使用
toString
法。这是合适的 如果你的日志记录'技术', 并且将用还在调试。如果你的日志记录更多的功能 (不针对开发人员),我建议定义的接口(在功能上它的声音在这种情况下,因此有必要提供的意思):
public interface Detailable { // the name could also suggest logging? String getFullDetails(); }
实现该接口在的任何对象,需要通过作为记录目的,一个复杂的计算,以生成的记录。