srinivasan
srinivasan

Reputation: 833

Periodic java logging

Can i flush all the logs based on time interval using configuration file. Searched a lot. Didn't find any. Short cut is using Timer ourselves and flush all loggers. But wanted to know whether configuraiton file allows it.

Upvotes: 1

Views: 1240

Answers (1)

jmehrens
jmehrens

Reputation: 11045

The configuration file options are explained in the LogManager documentation. At this time, the only way to do this is via the configuration file is to use the 'config' option to install your custom code to flush all loggers and perform the timer management. If you need to access to the JVM lifecycle, you can create a custom handler that ignores all log records but listens to constructor and close method calls.

public class FlushAllHandler extends Handler {

    private final ScheduledExecutorService ses;
    private final Future<?> task;

    public FlushAllHandler() {
        //TODO: Look these up from the LogManager.
        super.setLevel(Level.OFF); //Ignore all published records.
        ses = Executors.newScheduledThreadPool(1);
        long delay = 1L;
        TimeUnit unit = TimeUnit.HOURS;
        task = ses.scheduleWithFixedDelay(new Task(), delay, delay, unit);
    }

    @Override
    public void publish(LogRecord record) {
        //Allow a trigger filter to kick off a flush.
        if (isLoggable(record)) {
            ses.execute(new Task());
        }
    }

    @Override
    public void flush() {
    }

    @Override
    public void close() throws SecurityException {
        super.setLevel(Level.OFF);
        task.cancel(false);
        ses.shutdown();
        try {
            ses.awaitTermination(30, TimeUnit.SECONDS);
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
        ses.shutdownNow();
    }

    private static class Task implements Runnable {

        Task() {
        }

        @Override
        public void run() {
            final ArrayList<Handler> handlers = new ArrayList<>();
            final LogManager manager = LogManager.getLogManager();
            synchronized (manager) { //avoid ConcurrentModificationException
                final Enumeration<String> e = manager.getLoggerNames();
                while (e.hasMoreElements()) {
                    final Logger l = manager.getLogger(e.nextElement());
                    if (l != null) {
                        Collections.addAll(handlers, l.getHandlers());
                    }
                }
            }

            //Don't hold LogManager lock while flushing handlers.
            for (Handler h : handlers) {
                h.flush();
            }
        }
    }
}

Upvotes: 2

Related Questions