How to manually roll over the logfile with JDK Logging
Asked Answered
P

3

1

I have an application which uses JDK Logging with a logging.properties file which configures a number of older log-file via java.util.logging.FileHandler.count.

At certain points in the application I would like to trigger a manual rollover of the logfile to have a new logfile started, e.g. before a scheduled activity starts.

Is this possible with JDK Logging?

In Log4j I am using the following, however in this case I would like to use JDK Logging!

Logger logger = Logger.getRootLogger();
Enumeration<Object> appenders = logger.getAllAppenders();
while(appenders.hasMoreElements()) {
    Object obj = appenders.nextElement();
    if(obj instanceof RollingFileAppender) {
        ((RollingFileAppender)obj).rollOver();
    }
}
Plunkett answered 28/8, 2012 at 11:40 Comment(2)
I'd suggest using SLF4J to "bridge" java.util.logging to logback or log4j at most. See: slf4j.org/legacy.html#jul-to-slf4j . With logback rolling, zpipping files etc. is just a matter of configuration.Stoup
Yes, sure, I could also switch to Log4j completely as it is not a big application, but I was interested if I can do it with JDK Logging itself. Also I am not interested in configuration possibilities, but rather doing the rollover at a specific point in the code.Plunkett
A
2

You would have to write your own handler in order to get a rotation to work. Something like JBoss Log Manager works with JDK logging and just replaces the logmanger parts. It already has a few different rotating handlers.

Ascomycete answered 29/8, 2012 at 16:32 Comment(1)
:(, I didn't want to go that deep into the logging framework, but it seems there is no other way...Plunkett
H
3

You can trigger a rotation by creating a throw away FileHandler with a zero limit and no append.

new FileHandler(pattern, 0, count, false).close();

  1. Remove and close your existing FileHandler
  2. Create and close the rotation FileHandler.
  3. Create and add your FileHandler using your default settings.

Otherwise you can resort to using reflection:

        Method m = FileHandler.class.getDeclaredMethod("rotate");
        m.setAccessible(true);
        if (!Level.OFF.equals(f.getLevel())) { //Assume not closed.
            m.invoke(f);
        }
Hubbell answered 30/12, 2014 at 20:33 Comment(0)
A
2

You would have to write your own handler in order to get a rotation to work. Something like JBoss Log Manager works with JDK logging and just replaces the logmanger parts. It already has a few different rotating handlers.

Ascomycete answered 29/8, 2012 at 16:32 Comment(1)
:(, I didn't want to go that deep into the logging framework, but it seems there is no other way...Plunkett
S
-1
RollingFileHandler fileHandler = new RollingFileHandler(path);
fileHandler.setFormatter( newFormatter );
fileHandler.setLevel(level);
logger.addHandler(fileHandler);



import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.logging.ErrorManager;
import java.util.logging.LogRecord;
import java.util.logging.StreamHandler;


public class RollingFileHandler extends StreamHandler {

    private static String dateFormat = "yyyy-MM-dd"; //default

    private String path = null;

 // Standard-Log-Puffer (vergrößert sich on Demand)
    static ByteArrayOutputStream bas = new ByteArrayOutputStream(1024*200*25);  

    /**
     * Constructor.
     */
    public RollingFileHandler() {
        super();
        setOutputStream(bas);
        // Write old data in Multithread-Environment
        flush();
    }

    public RollingFileHandler(String path) {
        this.path = path;
    }

    /**
     * Overwrites super.
     */
    public synchronized void publish(LogRecord record) {
        if (!isLoggable(record)) {
            return;
        }
        super.publish(record);
    }


    @Override
    public synchronized void flush() {

        // Puffer ist leer
        if (bas.size() == 0) {
            return;
        }

        super.flush();

        File file = null;

        try {

            String dateString = null;

            SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, Locale.getDefault());
            dateString = sdf.format(new Date());
            String fileName = "dummyFile_" + dateString + ".log";

            try {

                // Auf den Servern mapping, bei lokalem Test am Arbeitsplatz brauche ich kein Logfile-Mapping

                boolean windows = System.getProperty("os.name").toLowerCase().indexOf("win") >= 0 ;

                if (!windows 
                        && path != null) {

                    File unixLogDir = new File(path);

                    if (unixLogDir.exists()) {

                        // Versuchen in das neue Directory zu speichern
                        File logfile = new File (path + "/" + fileName);
                        if (!logfile.exists()) {
                            logfile.createNewFile();
                        }
                        file = logfile;
                    }
                } 

            } catch(Exception e) {
                e.printStackTrace();
            }


            if (file == null) {

                // Fallback - Umzug hat nicht geklappt
                file = new File(fileName);
                if (!file.exists()) {
                    file.createNewFile();
                }
            }

            FileOutputStream fos = new FileOutputStream(file,true);
                bas.flush();    
                bas.writeTo(fos);
                bas.reset();
            fos.close();


    } catch (Exception fnfe) {
        reportError(null, fnfe, ErrorManager.GENERIC_FAILURE);
        fnfe.printStackTrace(System.err);
        setOutputStream(System.out); //fallback stream
        try {
            bas.writeTo(System.out);
        } catch (IOException e) {
            // Da kann man nichts machen
        }

    }

}

}

Smarmy answered 3/3, 2016 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.