简体   繁体   中英

Problem with java.util.logging and Lock file

I have an application that scans a set of files. And this scanning take place parallely. I mean if I upload 5 files, five process will be created and start executing the job parallely. Now For logging the exceptions for the jobs running, there is only one log file. The problem that is coming is, the logger creates a lot of logs files as -

mylogfile.log(actual log file)

mylogfile.log.1

mylogfile.log.2

mylogfile.log.3

mylogfile.log.4

mylogfile.log.5
...

with their respective lock files. Below is the code snippet that I used:

  public static Logger getLogger(final String className) {
    final Logger logger = Logger.getLogger(className);
    FileHandler fh;
    try {
        // This block configure the logger with handler and formatter
        fh = new FileHandler("mylogfile.log", true);
        logger.addHandler(fh);
        logger.setLevel(Level.ALL);
        logger.setUseParentHandlers(false);
        fh.setFormatter(new SimpleFormatter());
    } catch (final SecurityException e) {
        //          }
    } catch (final IOException e) {
        //
    }
    return logger;
}

How do I make sure that only one log file should be used to write the exception of all the jobs running parallely..??

Thanks,

Anish

I face the same problem and what I was missing is an standard programming practice that I should close the filehandler after I finish the logging. So you can create multiple loggers but make sure you close them at the end.

Following 2 lines in below example:

  • successLogFileHandler.close();
  • failureLogFileHandler.close();

class LoggerExample {
    private Logger  loggerFailure;
    private Logger  loggerSuccess;

    public void myLogger() {
        // some code block
        FileHandler successLogFileHandler = new FileHandler(successLogFile.getAbsolutePath());
        FileHandler failureLogFileHandler = new FileHandler(failureLogFile.getAbsolutePath());
        // Create loggers
        loggerFailure = createLogger(STR_FAILURE_LOG_FILE, failureLogFileHandler, Level.INFO, customFormatter);
        loggerSuccess = createLogger(STR_SUCCESS_LOG_FILE, successLogFileHandler, Level.INFO, customFormatter);
        // Write messages into loggers
        // and at the end close the file handlers
        successLogFileHandler.close();      
        failureLogFileHandler.close();
    }

    public static Logger createLogger(String strLoggerName, FileHandler handler, Level level, Formatter formatter) throws Exception
    {
        Logger logger = Logger.getLogger(strLoggerName);
        logger.setLevel(level);
        handler.setFormatter(formatter);
        logger.addHandler(handler);
        return logger;
    }
}

This does not have much to do with parallel calls. As well from single thread with each call to your getLogger (even with same string as argument) you create a new FileHandler and add it to existing logger.Maybe you do not want to do all of the setup each time when you call your getLogger-method.

//now we will create new Filehandler and set it to logger
getLogger("identifier").log(Level.SEVERE, "Log to   one file");
//now we have already one filehandler, but lets add one more
getLogger("identifier").log(Level.SEVERE, "Log to   two files");
//now we have already two filehandlers, but lets add one more
getLogger("identifier").log(Level.SEVERE, "Log to three files");       

Configure logging once and after that you can get reference to logger via java.util.loggingLogger.getLogger. Overview from Sun gives more ideas how to configure logging via properties files.

You can use a singlton locator class that you can retrieve the logger from, that would force your application to use one logger (which means you'll have one log file)

class LoggerLocator {

    private static LoggerLocator locator = new LoggerLocator();
    private Logger logger;

    /**
     * 
     */
    private LoggerLocator() {
        initLogger();
    }

    /**
     * @return
     */
    public static LoggerLocator getLocator(){
        return locator;
    }

    /**
     * @return
     */
    public Logger getLogger() {
        return logger;
    }

    /**
     * 
     */
    private void initLogger() {
        logger = Logger.getLogger("My General Logger");
        FileHandler fh;
        try {
            // This block configure the logger with handler and formatter
            fh = new FileHandler("mylogfile.log", true);
            logger.addHandler(fh);
            logger.setLevel(Level.ALL);
            logger.setUseParentHandlers(false);
            fh.setFormatter(new SimpleFormatter());
        } catch (final SecurityException e) {
            // }
        } catch (final IOException e) {
            //
        }
    }
}

In your jobs you will get the logger by the following call:

Logger logger = LoggerLocator.getLocator().getLogger();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM