1

Is it a good idea to use the same file handler in several loggers? I use the Java logging framework and I want different loggers to write into the same log file, but I don't know if this code example below is a good programming style.

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());
    }
}
Nurettin Armutcu
  • 335
  • 4
  • 10

3 Answers3

0

The Answer is yes.You can achieve this(for example) by making a singleton log class so any other class or thread tries creating a copy of it, will actually be using the same instance.

Example implementation with 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;
}
}

Then in your classes you will be using it like this:

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

I didn't see any issue with using one file handler for multiple loggers. However, It is always better practice to have the file handler configuration into separate property file or some configuration database

Yohannes Gebremariam
  • 2,225
  • 3
  • 17
  • 23
0

Usually you would just install a single handler on the root logger Logger.getLogger("") as that is the parent logger of both Alpha and Beta.

However, if you want to install a handler on siblings then you should use the LogManager config option or the java.util.logging.config.class system property to create your logging config.

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() {
    }
}
jmehrens
  • 10,580
  • 1
  • 38
  • 47