Search code examples
javaloggingthread-safetyjava.util.loggingfilehandler

How to write util.logger in thread safe execution?


I have MyLogger class which contains:

public class MyLogger {

    private final static Logger logger = Logger.getLogger(MyLogger.class.getName());
    private static FileHandler fileHandler;
    private static String loggerFileName;

    public MyLogger() { 
    }

    public static void createMyLogger(String filename){
        loggerFileName = filename;
        try {
            File loggerFile = new File(filename);
            boolean fileExists = loggerFile.exists();
            if(fileExists){
                loggerFile.delete();
                File lockFile = new File(filename+".lck");
                if(lockFile.exists())
                    lockFile.delete();
            }
            fileHandler = new FileHandler(filename,true);

        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.addHandler(fileHandler);
        SimpleFormatter simpleFormatter = new SimpleFormatter();
        fileHandler.setFormatter(simpleFormatter);
    }

    public static void log(String msg) {
        logger.log(Level.INFO, msg);
    }

    public static void log(Exception ex) {
        logger.log(Level.SEVERE, "Exception",ex);
    }


    public static String getLoggerFileName() {
        return loggerFileName;
    }


    public static void setLoggerFileName(String loggerFileName) {
        MyLogger.loggerFileName = loggerFileName;
    }

And I am having my further execution in threads, i.e. When I am starting first process then Logger File is created and logs are recorded, but when I starts another process then again different thread is created and also new logger file is created but because of static methods and reference It mixed up the both process logs in both logger files...

When I start process for every thread following method is called:

 public void start(String process) {
            try{
                String filename = process.replace(".com", "");
                MyLogger.createXPathLogger(filename.concat(WordUtils.capitalize(type))+ ".log");
                MyLogger.log("got parameters ===>> process : "+process);
                }catch (Exception e) {
                         MyLogger.log("Exception In main() method....");
                         MyLogger.log("*****"+process+" process failed In main() method.*****");
                         MyLogger.log(e);
              }
        }

So what can I do for this, Ho can I do thread safe logging? thanks in advance..


Solution

  • The idea here won't really work. One logger gets created and you add the each handler to the logger.

    What you really need is a concept of a log context. You need to isolate the creation of the logger on a per-thread basis which AFAIK you can't do with J.U.L.

    This is a very rough around the edges example of using JBoss Log Manager to do this:

    import java.io.File;
    import java.io.IOException;
    import java.util.logging.FileHandler;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import java.util.logging.SimpleFormatter;
    
    import org.jboss.logmanager.LogContext;
    public class MyLogger {
    
        private static final ThreadLocal<MyLogger> LOCAL_LOGGER = new ThreadLocal<MyLogger>();
    
        private final Logger logger;
    
        private MyLogger(final Logger logger) {
            this.logger = logger;
        }
    
        public static MyLogger createMyLogger(final String filename) {
            MyLogger result = LOCAL_LOGGER.get();
            if (result == null) {
                final LogContext logContext = LogContext.create();
                final Logger logger = logContext.getLogger(MyLogger.class.getName());
                final FileHandler fileHandler;
                try {
                    final File loggerFile = new File(filename);
                    if (loggerFile.exists()) {
                        loggerFile.delete();
                        File lockFile = new File(filename + ".lck");
                        if (lockFile.exists())
                            lockFile.delete();
                    }
                    fileHandler = new FileHandler(filename, true);
    
                } catch (IOException e) {
                    throw new RuntimeException("Could not create file handler", e);
                }
                logger.addHandler(fileHandler);
                fileHandler.setFormatter(new SimpleFormatter());
                final MyLogger myLogger = new MyLogger(logger);
                LOCAL_LOGGER.set(myLogger);
                result = myLogger;
            }
            return result;
        }
    
        public void log(String msg) {
            logger.log(Level.INFO, msg);
        }
    
        public void log(Exception ex) {
            logger.log(Level.SEVERE, "Exception", ex);
        }
    }