Building upon my previous answer you just need to build out the proxy implementation inferred in that answer. The idea is to install a proxy handler which allows you to open and close the FileHandler object. This enabled the rotation you need. Below is working example that will rotate when the date changes. The test case is included and the output will appear in the home folder by default.
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.logging.ErrorManager;
import java.util.logging.FileHandler;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.logging.XMLFormatter;
public class DailyFileHandler extends Handler {
public static void main(String[] args) throws IOException {
DailyFileHandler dfh = new DailyFileHandler();
try {
dfh.setFormatter(new SimpleFormatter());
LogRecord r1 = new LogRecord(Level.SEVERE, "test 1");
LogRecord r2 = new LogRecord(Level.SEVERE, "test 2");
r2.setMillis(r1.getMillis() + (24L * 60L * 60L * 1000L));
dfh.publish(r1);
dfh.publish(r2);
} finally {
dfh.close();
}
}
private Calendar current = Calendar.getInstance();
private FileHandler target;
public DailyFileHandler() throws IOException {
target = new FileHandler(pattern(), limit(), count(), false);
init();
}
public DailyFileHandler(String pattern, int limit, int count)
throws IOException {
target = new FileHandler(pattern, limit, count, false);
init();
}
private void init() {
super.setLevel(level());
super.setFormatter(formatter());
super.setFilter(filter());
try {
super.setEncoding(encoding());
} catch (UnsupportedEncodingException impossible) {
throw new AssertionError(impossible);
}
initTarget();
}
private void initTarget() {
target.setErrorManager(super.getErrorManager());
target.setLevel(super.getLevel());
target.setFormatter(super.getFormatter());
target.setFilter(super.getFilter());
try {
target.setEncoding(super.getEncoding());
} catch (UnsupportedEncodingException impossible) {
throw new AssertionError(impossible);
}
}
private void rotate() {
String pattern = pattern();
int count = count();
int limit = limit();
try {
super.setErrorManager(target.getErrorManager());
target.close();
FileHandler rotate = new FileHandler(pattern, 0, count, false);
rotate.setFormatter(new SimpleFormatter()); //empty tail.
rotate.close();
current = Calendar.getInstance();
target = new FileHandler(pattern, limit, count, true);
initTarget();
} catch (RuntimeException | IOException e) {
this.reportError("", e, ErrorManager.OPEN_FAILURE);
}
}
private boolean shouldRotate(long millis) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
return cal.get(Calendar.DAY_OF_YEAR) != current.get(Calendar.DAY_OF_YEAR);
}
@Override
public synchronized void publish(LogRecord record) {
if (shouldRotate(record.getMillis())) {
rotate();
}
target.publish(record);
}
@Override
public synchronized void close() throws SecurityException {
target.close();
}
@Override
public synchronized void setEncoding(String encoding) throws SecurityException, UnsupportedEncodingException {
target.setEncoding(encoding);
super.setEncoding(encoding);
}
@Override
public synchronized boolean isLoggable(LogRecord record) {
return target.isLoggable(record);
}
@Override
public synchronized void flush() {
target.flush();
}
@Override
public synchronized void setFormatter(Formatter newFormatter) {
target.setFormatter(newFormatter);
super.setFormatter(newFormatter);
}
@Override
public synchronized Formatter getFormatter() {
return target.getFormatter();
}
@Override
public synchronized String getEncoding() {
return target.getEncoding();
}
@Override
public synchronized void setFilter(Filter newFilter) throws SecurityException {
target.setFilter(newFilter);
super.setFilter(newFilter);
}
@Override
public synchronized Filter getFilter() {
return target.getFilter();
}
@Override
public synchronized void setErrorManager(ErrorManager em) {
target.setErrorManager(em);
super.setErrorManager(em);
}
@Override
public synchronized ErrorManager getErrorManager() {
return target.getErrorManager();
}
@Override
public synchronized void setLevel(Level newLevel) throws SecurityException {
target.setLevel(newLevel);
super.setLevel(newLevel);
}
@Override
public synchronized Level getLevel() {
return target.getLevel();
}
private String pattern() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String pattern = m.getProperty(p + ".pattern");
if (pattern == null) {
pattern = "%h/java%u.log";
}
return pattern;
}
private int limit() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".limit");
int limit = v == null ? Integer.MAX_VALUE : Integer.parseInt(v);
return limit;
}
private int count() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".count");
int limit = v == null ? 7 : Integer.parseInt(v);
return limit;
}
private Level level() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".level");
if (v != null) {
try {
return Level.parse(v);
} catch (Exception e) {
this.reportError(v, e, ErrorManager.OPEN_FAILURE);
}
}
return Level.ALL;
}
private Formatter formatter() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".formatter");
if (v != null) {
try {
return Formatter.class.cast(Class.forName(v).newInstance());
} catch (Exception e) {
this.reportError("", e, ErrorManager.OPEN_FAILURE);
}
}
return new XMLFormatter();
}
private Filter filter() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".filter");
if (v != null) {
try {
return Filter.class.cast(Class.forName(v).newInstance());
} catch (Exception e) {
this.reportError("", e, ErrorManager.OPEN_FAILURE);
}
}
return null;
}
private String encoding() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".encoding");
if (v != null) {
try {
return Charset.forName(v).name();
} catch (Exception e) {
this.reportError(v, e, ErrorManager.OPEN_FAILURE);
}
}
return null;
}
}