package org.jacorb.config; import org.jacorb.config.JacORBLogFormatter.ClockFormat; import org.jacorb.util.ObjectUtil; import org.omg.CORBA.ORBSingleton; import java.io.File; import java.util.logging.ConsoleHandler; import java.util.logging.FileHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; /** * A LoggingInitializer for the JDK logging system. * @author Andre Spiegel {@literal <spiegel@gnu.org>} */ public class JdkLoggingInitializer extends LoggingInitializer { /** * True if the currently used SLF4J backend is the * JDK logging implementation. This is true if and only if * the SLF4J-to-JDK adapter can be found on the classpath. */ private static final boolean ISJDKLOGGING; /** * Use to determine whether a Java Logging configuration file has been * supplied to override the JacORB configuration. */ private static final boolean USEJACORBCONFIG; static { USEJACORBCONFIG = ( System.getProperty("java.util.logging.config.file") == null ); Class<?> c = null; try { c = ObjectUtil.classForName ("org.slf4j.impl.JDK14LoggerAdapter"); } catch (Exception ex) { } ISJDKLOGGING = (c != null); // This horror is to ensure that the Singleton logging is // always set up first. Otherwise what happens is either the // Singleton logging goes to console, or the full ORB logging // uses the Singleton log file. This is mainly because JDK // logging does not allow separate Logger('jacorb') // instances. Which means they use each others logfile. ORBSingleton.init (); } /** * Cache of the root logger for this system. */ private Logger rootLogger; /** * For a string that contains a number from 0 to 4, returns the * corresponding JDK log level. */ private Level toJdkLogLevel (String level) { if (level == null || level.length() == 0) { return Level.INFO; } else { try { int logLevel = Integer.parseInt (level.trim()); switch (logLevel) { // http://www.slf4j.org/apidocs/org/slf4j/bridge/SLF4JBridgeHandler.html case 0: return Level.OFF; case 1: return Level.SEVERE; case 2: return Level.WARNING; default: case 3: return Level.INFO; case 4: return Level.FINER; case 5: return Level.FINEST; } } catch (NumberFormatException ex) { throw new RuntimeException (ex); } } } @Override public void init (Configuration config) throws ConfigurationException { if (!ISJDKLOGGING || !USEJACORBCONFIG) { return; } String level = config.getAttribute (ATTR_LOG_VERBOSITY, "3"); String file = config.getAttribute (ATTR_LOG_FILE, null); boolean showThread = config.getAttributeAsBoolean (ATTR_LOG_THREAD_ID, false); boolean showSrcInfo = config.getAttributeAsBoolean (ATTR_LOG_SRC_INFO, false); String clockFormat = config.getAttribute(ATTR_LOG_CLOCK, ClockFormat.NONE.toString()); rootLogger = Logger.getLogger(LoggingInitializer.ATTR_LOG_NAME); rootLogger.setUseParentHandlers (false); rootLogger.setLevel (toJdkLogLevel (level)); // Ensure there is only one handler purgeHandlers (rootLogger); Handler handler; if (file != null && file.length() > 0) { if (new File (file).isDirectory()) { // Logging to a directory. Append $implname. file = file.concat(File.separatorChar + "$implname"); } try { handler = new FileHandler ( substituteImplname (file, config), config.getAttributeAsInteger (ATTR_LOG_SIZE, 0), config.getAttributeAsInteger (ATTR_LOG_ROTATE, 1), config.getAttributeAsBoolean (ATTR_LOG_APPEND, false) ); } catch (java.io.IOException ex) { System.err.println ("could not write log file"); ex.printStackTrace(); handler = new ConsoleHandler(); } catch (ConfigurationException ex) { System.err.println ("could not write log file due to configuration exception"); ex.printStackTrace(); handler = new ConsoleHandler(); } } else { handler = new ConsoleHandler(); } handler.setLevel(toJdkLogLevel(level)); handler.setFormatter (new JacORBLogFormatter(showThread, showSrcInfo, ClockFormat.getClockFormat(clockFormat))); rootLogger.addHandler (handler); } @Override public void shutdownLogging () { if (ISJDKLOGGING) { // Clear lock files. Handler handlers[] = rootLogger.getHandlers(); purgeHandlers (rootLogger); if (handlers.length > 0) { // So we don't loose any logs revert to console based logging. java.util.logging.Handler c = new java.util.logging.ConsoleHandler(); c.setFormatter (handlers[0].getFormatter()); c.setLevel (handlers[0].getLevel()); rootLogger.addHandler (c); } } } private void purgeHandlers (java.util.logging.Logger rootLogger) { // Ensure there is only one handler Handler[] handlers = rootLogger.getHandlers(); if (handlers != null && handlers.length > 0) { for (int i = 0; i < handlers.length; i++) { handlers[i].close(); rootLogger.removeHandler(handlers[i]); } } } }