在哪里定义静态应用程序范围的记录器?

时间:2010-11-05 13:39:39

标签: java logging

我的Java Web应用程序中有许多软件包。在其中一些我使用这个结构:

public class Foo {
  private static Logger logger = LoggerFactory.getLogger("com.XXX");
  public void bar() {
    Foo.logger.debug("Method bar() was just called");
  }
}

当然,这只是一个例子。一切正常,但我不喜欢许多类中记录器初始化的想法。这是一个明显的代码重复。我想将它移动到一个帮助类,让所有其他类访问它。这是一个正确的想法吗?或者也许还有其他“最佳实践”或模式?

7 个答案:

答案 0 :(得分:8)

说这是代码重复就像是说75%的类中有import java.util.*是代码重复。或者你发现自己经常写public class ...。它不是重复逻辑。它重复了样板代码。

代码重复只涉及复制逻辑时的设计气味。如果有太多的样板代码,那真的是语言设计。你真的不应该担心什么。

缺点是,如果放弃层级结构,则无法微调日志记录。

答案 1 :(得分:5)

如果你使用集中的全局静态记录器constrcut而不是常见的Log4J调用/ inits,我认为你不会赢得任何东西。

如果你写

private static Logger logger = LoggerFactory.getLogger("com.XXX");
logger.info("Hello World");

或类似的东西

GlobalLogger.info(this, "LogMessage");  //Singleton...

...不会让你的代码更“可读”。

答案 2 :(得分:3)

您可以编写自己的实用程序类,它包装全局记录器并实现对记录器方法的静态委托。然后只需对此类进行静态导入:

public class MyLogger {
  private static Logger logger = LoggerFactory.getLogger("application");

  public static void debug(String s) {logger.debug(s));}

  public static void debug(Class<?> caller, String s) {
     LoggerFactory.getLogger(caller.getName()).debug(s);
  }

  // ...
}

用法:

import static MyLogger.*;

public class Foo {
  public void bar() {
    // makes use of static import!
    debug("Method bar() was just called"); 
    debug(this.getClass(), "Method bar() was just called"); 
  }
}

添加了示例debug委托的重载版本,该委托采用类对象并使用相应的Logger。

答案 3 :(得分:1)

不建议这样做,因为您将失去Log4j的层次化日志记录功能(如果这是您正在使用的),在包树的不同级别添加不同的appender非常有用。我不会这样做,因为你会丢失有关哪个类创建了日志消息的信息。

答案 4 :(得分:1)

使用实用程序记录器类封装第三方依赖项(即Log4j)是有意义的。

例如,如果团队决定从Log4j切换到NextBigThingLogger,他们只需更新他们的MyLogger类,而不更新其他应用程序类。

更清洁,更容易维护。

Apache API,甚至Java语言本身都充斥着“设计气味”,但这并不意味着我们不应该回应它们。

答案 5 :(得分:0)

我认为你是在追随Singleton设计模式。不是java程序员,我从谷歌那里挖出来了:

http://www.javacoffeebreak.com/articles/designpatterns/index.html

答案 6 :(得分:0)

您可以为记录器创建Adapter pattern。就我而言,我扩展了记录器以包含所有记录器功能。然后将其制作成单身人士。

public class LoggerAdapter extends Logger {
    private LoggerAdapter instance;
    private Logger logger;

    private LoggerAdapter() {

    }

    public static LoggerAdapter getInstance(Clazz<?>  clazz) {
        if (instance == null) {
            instance = new LoggerAdapter();
        }
        instance.logger = logger = LoggerFactory.getLogger(clazz.getName());

        return instance;
    }

    @Override
    public void trace(Object object) {
        logger.trace(object);
    }

    //Other overridden methods here...
};

基本上是一个动态变化的记录器......