package com.ibm.nmon.util;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import org.slf4j.Logger;
import java.io.StringWriter;
import java.io.PrintWriter;
import com.ibm.nmon.parser.NMONParser;
/**
* <p>
* Custom {@link java.util.logging.Handler Handler} that writes log messages to an internal buffer.
* The buffer can be retrieved using the {@link #getMessages()} method.
* </p>
*
* <p>
* To allow tracking by the application, parsers should call {@link #setCurrentFilename(String)}
* when parsing a file.
* </p>
*
* <p>
* This class is a singleton to ensure that only on instance is added to the Logger for
* 'com.ibm.nmon.parser' package.
* </p>
*/
public final class ParserLog extends Handler {
private Logger logger;
private String currentFilename;
private StringWriter logBuffer;
private boolean hasData;
private ParserLog() {
// note the parser package, not this class' package
String loggerName = NMONParser.class.getPackage().getName();
// configure underlying JDK logger ...
java.util.logging.Logger parserLogger = java.util.logging.Logger.getLogger(loggerName);
parserLogger.addHandler(this);
// but expose SLF4J logger
logger = org.slf4j.LoggerFactory.getLogger(loggerName);
currentFilename = "";
logBuffer = new StringWriter(512);
hasData = false;
}
private static final ParserLog INSTANCE = new ParserLog();
public static synchronized ParserLog getInstance() {
return INSTANCE;
}
@Override
public void close() {
try {
logBuffer.close();
}
catch (java.io.IOException ioe) {
// ignore
}
finally {
logBuffer = null;
}
}
@Override
public void flush() {}
@Override
public synchronized void publish(LogRecord record) {
logBuffer.append(record.getLevel().getName());
logBuffer.append(" ");
logBuffer.append(record.getMessage());
logBuffer.append("\n");
if (record.getThrown() != null) {
PrintWriter pw = new PrintWriter(logBuffer);
record.getThrown().printStackTrace(pw);
pw.close();
}
hasData = true;
}
public Logger getLogger() {
return logger;
}
public synchronized boolean hasData() {
return hasData;
}
public synchronized String getCurrentFilename() {
return currentFilename;
}
public synchronized void setCurrentFilename(String currentFilename) {
if (currentFilename == null) {
this.currentFilename = "";
}
else {
this.currentFilename = currentFilename;
}
}
public synchronized String getMessages() {
String toReturn = logBuffer.toString();
close();
currentFilename = "";
logBuffer = new StringWriter(512);
hasData = false;
return toReturn;
}
}