Search code examples
javaloggingjava.util.logging

Using Logger with a file size limit and number of files limit


I was wondering if anyone can help me with this issue. My current code is set up, to use the Logger in java.util.logging we write the log to a single file and when we need access to the log we just read the file.

    String filename = name + ".log";
    Logger logger = Logger.getLogger(name);
    logger.setLevel(Level.ALL);
    final FileHandler fileHandler = new FileHandler(filename, true);
    final SimpleFormatter formatter = new LogFormatter();
    fileHandler.setFormatter(formatter);
    logger.addHandler(fileHandler);

The contents of the log is then obtained by

    Files.readAllLines(Paths.get(filename));

An issue has occurred where the file size may become too big and so I want to limit it. Reading around the documentation I can do the following

    final FileHandler fileHandler = new FileHandler(filename, 1000000, 3, true);

This will create up to three, 1MB files, cycling through when the third one is filled, clearing the first file and writing from there again. This is a perfect solution, but comes with two issues I am uncertain how to resolve.

Firstly is there an easy way to find the name of all the files created? (More precisely is there an easy way to do this? I appreciate I can just look for filename.0, filename.1 ... up to the limit).

Secondly how do I find which is the "active" file. Example. Lets say that one cycle has already been completed and there are three files ("file.0", "file.1", "file.2"). If the Logger is currently writing to file.1, how do I determine this, so therefore when I produce the log as List the top of the log is the oldest content (file.2 in this example)

Thank you for any response.


Solution

  • Okay I've worked out a solution, which is simple enough that I'm happy enough with it. As jmehrens mentioned there isn't a direct way, but I thought I would post it here in case anyone else has the same issue.

    String filename = name + ".log";
    // To make life easy create a directory to output logs into
    final File directory = new File("log");
    directory.mkdir();
    
    // Create a java.io.FileFilter object to filter only the files I am looking for 
    // ignoring the locked file (this answers my first question)
    FileFilter filter = (pathname) -> {
            final String name = pathname.getName();
            return name.contains(filename) && !name.endsWith(".lck");
        };
    
    // Uses the filter to find all files in the directory associated with 
    // the log and deletes them
    Arrays.asList(directory.listFiles(filter)).forEach(file -> file.delete());
    
    // Create logger as before 
    logger = Logger.getLogger(name);
    logger.setLevel(Level.ALL);
    final FileHandler fileHandler = new FileHandler("log/" + filename, limit, 
    numberOfFiles, true);
    final SimpleFormatter formatter = new LogFormatter();
    fileHandler.setFormatter(formatter);
    logger.addHandler(fileHandler);
    

    Getting the output of the logs is then simply using the same filter on the previously determined directory. Sorting by date last modified and then reading all the lines.

    final List<File> logFiles = Arrays.asList(directory.listFiles(filter));
    logFiles.sort((file0, file1) -> {
        final Long date1 = file0.lastModified();
        final Long date2 = file1.lastModified();
        return date1.compareTo(date2);
    });
    // Iterate through logFiles and read the lines