多个记录器可以使用相同的处理程序吗?

Can multiple loggers use the same handler?

在多个记录器中使用相同的文件处理程序是个好主意吗?我使用 Java 日志框架,我希望不同的日志记录器写入同一个日志文件,但我不知道下面的代码示例是否是一种好的编程风格。

import java.io.*;
import java.util.logging.*;

public class Alpha {
    private static final Logger LOGGER = Logger.getLogger(Alpha.class.getName());
    private static FileHandler loggingHandler;

    static {
        try {
            loggingHandler = new FileHandler("logfile.log", true);
            LOGGER.addHandler(loggingHandler);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static FileHandler getLoggingHandler() {
        return loggingHandler;
    }
}

class Beta {
    private static final Logger LOGGER = Logger.getLogger(Beta.class.getName());

    static {
        LOGGER.addHandler(Alpha.getLoggingHandler());
    }
}

答案是 yes.You 可以通过制作 singleton 日志 class 来实现这一点(例如),以便任何其他 class 或线程尝试创建它的副本, 实际上将使用相同的实例。

使用 java.util.logging 的示例实现:

public class LogMe {        
    private static LogMe logMe;
    private static Logger logger;    
    private static FileHandler fh;
    private static Formatter sf;

    public LogMe() {
    //Make this class a singleton
        if (logMe != null) {
           return;
       }

        //Create the log file            
        try {
        fh = new FileHandler("../xyz/LogFile.log");
    } catch (Exception e) {
        e.printStackTrace();
    }

    sf = new SimpleFormatter();
    fh.setFormatter(sf);            
    logger.addHandler(fh);

    //Part of making this class a singleton
    logger = Logger.getLogger("LogMe");
    logMe = this;        
}

public Logger getLogger() {
    return LogMe.logger;
}
}

然后在你的 classes 中你将像这样使用它:

 class MyClass1 {
    LogMe logMe1 = new LogMe();
    Logger logger2 = logMe1.getLogger();
    logger.info("X 01");
}

我没有发现对多个记录器使用一个文件处理程序有任何问题。但是,将文件处理程序配置到单独的 属性 文件或某些配置数据库

中总是更好的做法

通常您只需在根记录器 Logger.getLogger("") 上安装一个处理程序,因为它是 AlphaBeta.

的父记录器

但是,如果您想在兄弟姐妹上安装处理程序,那么您应该使用 LogManager config option or the java.util.logging.config.class system property 创建您的日志记录配置。

package app.configs;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Logger;

public final class SharedHandlerConfig {

    private static final Logger[] LOGGERS
            = new Logger[]{Logger.getLogger(Alpha.class.getName()),
                Logger.getLogger(Beta.class.getName())};

    private static final FileHandler FILE;

    static {
        try {
            FileHandler f = new FileHandler("../xyz/logfile.log", true);
            try {
                for (Logger l : LOGGERS) {
                    l.addHandler(f);
                }
                FILE = f;
                f = null;
            } finally {
                if (f != null) {
                    f.close();
                    for (Logger l : LOGGERS) {
                        l.removeHandler(f);
                    }
                }
            }
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * From startup system property:
     * -Djava.util.logging.config.class=app.configs.SharedHandlerConfig
     * 
     * From logging.properties:
     * config=app.configs.SharedHandlerConfig
     */
    public SharedHandlerConfig() {
    }
}