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

Moo*_*oHa 3 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; 
    }
}
Run Code Online (Sandbox Code Playgroud)

rad*_*dai 10

不,它绝对不是:-)

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

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

   //rest of the code
}
Run Code Online (Sandbox Code Playgroud)

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

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

public class SomeSecurityRelatedClass {

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

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