我应该继续将logger实例传递给不同的类

时间:2014-02-07 15:08:28

标签: java logging

我在main方法中创建一个logger实例,并将其设置为全局变量。如果我想使用相同的日志文件来记录消息,那么将相同的记录器实例传递给不同的类构造函数是一种好习惯。你怎么能这样做而不是通过。

public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
        Handler h = new FileHandler("../logs/MyLogFile_"
                + sdf.format(date) + ".log", true);
        h.setFormatter(new SingleLineFormatter());
        h.setLevel(Level.ALL);
        logger.setUseParentHandlers(false);
        logger.addHandler(h);
} 

public void go(XMLConfig config) throws Exception {      
    Controller.setGlobalErrorHandler(new ErrorHandler(logger));
} 

public class ErrorHandler implements FDSErrorHandler {

    private static Logger logger = Logger.getLogger("com.explore.lse");

    public ErrorHandler(Logger logger) {
        this.logger = logger; 
    }
}

1 个答案:

答案 0 :(得分:9)

不,它绝对不是: - )

使用日志记录框架的常见模式是在每个打印到日志的类中都有一个私有的最终静态记录器字段(假设您选择的框架的记录器当然是线程安全的。大多数都是):

public class MyClass {
   private final static Logger log = LoggerFactory.getLogger(MyClass.class); //or the equivalent for your logging framework

   //rest of the code
}

然后,您可以使用日志记录配置(通常为xml)控制哪些类(== loggers)进入哪些文件。

有时候(“有时候”很少,并且大部分都是由框架使用)你在检索记录器时会使用“主题名称”而不是类名。所以,例如:

public class SomeSecurityRelatedClass {

   public void authenticateUser(String username, String pass) {
      if (!passCorrect(...)) {
         LoggerFactory.getLogger("SECURITY").info("rejecting user .... //etc
      }
   }
}

而且即时通讯时,记录器名称的另一个常见滥用是人们想要以某种方式“标记”并发环境中的特定进程(例如,您希望所有与同一用户的请求相关的日志记录都转到同一个文件中-用户)。请勿滥用记录器名称。相反,要熟悉MDCs的概念。它们至少受log4jslf4j / Logback支持,可用于“标记”流程或将您想要的任何其他额外数据添加到日志中