package edu.stanford.nlp.util.logging;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
* Reroutes java.util.logging messages to the Redwood logging system.
*
* @author David McClosky
*/
public class JavaUtilLoggingAdaptor {
private static boolean addedRedwoodHandler; // = false;
private JavaUtilLoggingAdaptor() {
}
public static void adapt() {
// get the top Logger:
Logger topLogger = Logger.getLogger("");
Handler oldConsoleHandler = null;
// see if there is already a console handler
// hopefully reasonable assumption: there's only one ConsoleHandler
// TODO confirm that this will always give us all handlers (i.e. do we need to loop over all Loggers in java.util.LogManager and do this for each one?)
for (Handler handler : topLogger.getHandlers()) {
if (handler instanceof ConsoleHandler && !(handler instanceof RedwoodHandler)) {
// found the console handler
oldConsoleHandler = handler;
break;
}
}
if (oldConsoleHandler != null) {
// it's safe to call this after it's been removed
topLogger.removeHandler(oldConsoleHandler);
}
if (!addedRedwoodHandler) {
Handler redwoodHandler = new JavaUtilLoggingAdaptor.RedwoodHandler();
topLogger.addHandler(redwoodHandler);
addedRedwoodHandler = true;
}
}
/**
* This is the bridge class which actually adapts java.util.logging calls to Redwood calls.
*/
public static class RedwoodHandler extends ConsoleHandler {
/**
* This is a no-op since Redwood doesn't have this.
*/
@Override
public void close() throws SecurityException {
}
/**
* This is a no-op since Redwood doesn't have this.
*/
@Override
public void flush() {
}
/**
* Convert a java.util.logging call to its equivalent Redwood logging call.
* Currently, the WARNING log level becomes Redwood WARNING flag, the SEVERE log level becomes Redwood.ERR, and anything at FINE or lower becomes Redwood.DBG
* CONFIG and INFO don't map to a Redwood tag.
*/
@Override
public void publish(LogRecord record) {
String message = record.getMessage();
Level level = record.getLevel();
Object tag = null;
if (level == Level.WARNING) {
tag = Redwood.WARN;
} else if (level == Level.SEVERE) {
tag = Redwood.ERR;
} else if (level.intValue() <= Level.FINE.intValue()) {
tag = Redwood.DBG;
}
if (tag == null) {
Redwood.log(message);
} else {
Redwood.log(tag, message);
}
}
}
/**
* Simple test case.
*/
public static void main(String[] args) {
if (args.length > 0 && args[0].equals("redwood")) {
Redwood.log(Redwood.DBG, "at the top");
Redwood.startTrack("Adaptor test controlled by redwood");
Logger topLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
topLogger.warning("I'm warning you!");
topLogger.severe("Now I'm using my severe voice.");
topLogger.info("FYI");
Redwood.log(Redwood.DBG, "adapting");
JavaUtilLoggingAdaptor.adapt();
topLogger.warning("I'm warning you in Redwood!");
JavaUtilLoggingAdaptor.adapt(); // should be safe to call this twice
topLogger.severe("Now I'm using my severe voice in Redwood!");
topLogger.info("FYI: Redwood rocks");
// make sure original java.util.logging levels are respected
topLogger.setLevel(Level.OFF);
topLogger.severe("We shouldn't see this message.");
Redwood.log(Redwood.DBG, "at the bottom");
Redwood.endTrack("Adaptor test controlled by redwood");
} else {
// Reverse mapping
Logger topLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); // Can be Logger.getGlobal() in jdk1.7
// topLogger.addHandler(new ConsoleHandler());
Logger logger = Logger.getLogger(JavaUtilLoggingAdaptor.class.getName());
topLogger.info("Starting test");
logger.log(Level.INFO, "Hello from the class logger");
Redwood.log("Hello from Redwood!");
Redwood.rootHandler().addChild(
RedirectOutputHandler.fromJavaUtilLogging(topLogger));
Redwood.log("Hello from Redwood -> Java!");
Redwood.log("Hello from Redwood -> Java again!");
logger.log(Level.INFO, "Hello again from the class logger");
Redwood.startTrack("a track");
Redwood.log("Inside a track");
logger.log(Level.INFO, "Hello a third time from the class logger");
Redwood.endTrack("a track");
logger.log(Level.INFO, "Hello a fourth time from the class logger");
}
}
}