SimpleLogFileHandler.java
package gov.usgs.util.logging;
import gov.usgs.util.StreamUtils;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
* A java.util.logging style Handler that does daily log rotation by default.
*/
public class SimpleLogFileHandler extends Handler {
/** Default format used. */
public static final String DEFAULT_FILENAME_FORMAT = "'log_'yyyyMMdd'.log'";
/** The directory where log files are written. */
private File logDirectory;
/** Used to generate filename for current log message. */
private SimpleDateFormat filenameFormat;
/** The last filename used when logging. */
private String currentFilename;
/** Handle to the current log file. */
private OutputStream currentStream;
/**
* Create a default SimpleLogHandler.
*
* Uses the system locale to roll log files once a day, and default filename
* format "log_YYYYMMDD.log".
*
* @param logDirectory
* the directory to write log files.
*/
public SimpleLogFileHandler(final File logDirectory) {
this(logDirectory, new SimpleDateFormat(DEFAULT_FILENAME_FORMAT));
}
/**
* Create a SimpleLogHandler with a custom filename format.
*
* @param logDirectory
* the directory to write log files.
* @param filenameFormat
* the format for log files. Files are opened as soon as the
* format output changes for a given log's message.
*/
public SimpleLogFileHandler(final File logDirectory,
final SimpleDateFormat filenameFormat) {
this.logDirectory = logDirectory;
this.filenameFormat = filenameFormat;
this.currentFilename = null;
this.currentStream = null;
}
/**
* Closes the current log file.
*/
public void close() throws SecurityException {
if (currentStream != null) {
try {
// log when the file was closed, if possible
currentStream.write(("\nClosing log file at "
+ new Date().toString() + "\n\n").getBytes());
} catch (IOException e) {
// ignore
} finally {
StreamUtils.closeStream(currentStream);
currentStream = null;
}
}
}
/**
* Attempts to flush any buffered content. If exceptions occur, the stream
* is closed.
*/
public void flush() {
if (currentStream != null) {
try {
currentStream.flush();
} catch (IOException e) {
close();
currentStream = null;
}
}
}
/**
* Retrieve the outputstream for the current log file.
*
* @param date
* the date of the message about to be logged.
* @return and OutputStream where the log message may be written.
* @throws IOException
* if errors occur.
*/
protected OutputStream getOutputStream(final Date date) throws IOException {
String filename = filenameFormat.format(date);
if (currentStream == null || currentFilename == null
|| !filename.equals(currentFilename)) {
// close any existing stream
close();
// filename is what is being opened
currentFilename = filename;
currentStream = StreamUtils.getOutputStream(new File(logDirectory,
filename), true);
// log when the file was opened
currentStream
.write(("Opened log file at " + new Date().toString() + "\n\n")
.getBytes());
currentStream.flush();
}
return currentStream;
}
/**
* Add a LogRecord to the log file.
*/
public void publish(LogRecord record) {
if (record == null) {
return;
}
String message = getFormatter().format(record);
try {
OutputStream stream = getOutputStream(new Date(record.getMillis()));
stream.write(message.getBytes());
flush();
} catch (Exception e) {
// close if any exceptions occur
close();
}
}
private static final Logger LOGGER = Logger
.getLogger(SimpleLogFileHandler.class.getName());
/**
* Testing for handler
* @param args CLI args
* @throws Exception if error occurs
*/
public static void main(final String[] args) throws Exception {
SimpleDateFormat ridiculouslyShortLogs = new SimpleDateFormat(
"'log_'yyyyMMddHHmmss'.log'");
File logDirectory = new File("log");
SimpleLogFileHandler handler = new SimpleLogFileHandler(logDirectory,
ridiculouslyShortLogs);
handler.setFormatter(new SimpleLogFormatter());
LOGGER.addHandler(handler);
// there should be at least 2 log files created, and more likely 3
LOGGER.info("message to log");
handler.close();
LOGGER.info("message to log");
Thread.sleep(1000);
LOGGER.info("another message to log");
Thread.sleep(250);
LOGGER.info("another message to log");
Thread.sleep(1000);
LOGGER.info("yet another message to log");
Thread.sleep(250);
LOGGER.info("yet another message to log");
}
}