// -------------------------------------------------------- Private Methods private void resetLoggers( ClassLoaderLogManagerClassLoaderLogInfo clClassLoaderLogManagerClassLoaderLogInfo) { // This differs from LogManager#resetLogger() in that we close not all // handlers of all loggers, but only those that are present in our // ClassLoaderClassLoaderLogManagerClassLoaderLogInfo#handlers list. That is because our // #addLogger(..) // method can use handlers from the parent class loaders, and closing // handlers that the current class loader does not own would be not // good. synchronized (clClassLoaderLogManagerClassLoaderLogInfo) { for (Logger logger : clClassLoaderLogManagerClassLoaderLogInfo.getLoggers().values()) { Handler[] handlers = logger.getHandlers(); for (Handler handler : handlers) { logger.removeHandler(handler); } } for (Handler handler : clClassLoaderLogManagerClassLoaderLogInfo.getHandlers().values()) { try { handler.close(); } catch (Exception e) { // Ignore } } clClassLoaderLogManagerClassLoaderLogInfo.getHandlers().clear(); } }
private String findProperty(String name) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ClassLoaderLogManagerClassLoaderLogInfo info = getClassLoaderInfo(classLoader); String result = info.getProps().getProperty(name); // If the property was not found, and the current classloader had no // configuration (property list is empty), look for the parent classloader // properties. if ((result == null) && (info.getProps().isEmpty())) { ClassLoader current = classLoader.getParent(); while (current != null) { info = classLoaderLoggers.get(current); if (info != null) { result = info.getProps().getProperty(name); if ((result != null) || (!info.getProps().isEmpty())) { break; } } current = current.getParent(); } if (result == null) { result = super.getProperty(name); } } return result; }
/** * Load specified configuration. * * @param is InputStream to the properties file * @param classLoader for which the configuration will be loaded * @throws IOException If something wrong happens during loading */ protected void readConfiguration(InputStream is, ClassLoader classLoader) throws IOException { ClassLoaderLogManagerClassLoaderLogInfo info = classLoaderLoggers.get(classLoader); try { info.getProps().load(is); } catch (IOException e) { // Report error System.err.println("Configuration error"); e.printStackTrace(); } finally { try { is.close(); } catch (IOException ioe) { // Ignore } } // Create handlers for the root logger of this classloader String rootHandlers = info.getProps().getProperty(".handlers"); String handlers = info.getProps().getProperty("handlers"); Logger localClassLoaderLogManagerRootLogger = info.getRootNode().getLogger(); if (handlers != null) { StringTokenizer tok = new StringTokenizer(handlers, ","); while (tok.hasMoreTokens()) { String handlerName = (tok.nextToken().trim()); String handlerClassName = handlerName; String prefix = ""; if (handlerClassName.length() <= 0) { continue; } // Parse and remove a prefix (prefix start with a digit, such as // "10WebappFooHanlder.") if (Character.isDigit(handlerClassName.charAt(0))) { int pos = handlerClassName.indexOf('.'); if (pos >= 0) { prefix = handlerClassName.substring(0, pos + 1); handlerClassName = handlerClassName.substring(pos + 1); } } try { this.prefix.set(prefix); Handler handler = (Handler) classLoader.loadClass(handlerClassName).newInstance(); // The specification strongly implies all configuration should be done // during the creation of the handler object. // This includes setting level, filter, formatter and encoding. this.prefix.set(null); info.getHandlers().put(handlerName, handler); if (rootHandlers == null) { localClassLoaderLogManagerRootLogger.addHandler(handler); } } catch (Exception e) { // Report error System.err.println("Handler error"); e.printStackTrace(); } } } }
/** * Add the specified logger to the classloader local configuration. * * @param logger The logger to be added */ @Override public synchronized boolean addLogger(final Logger logger) { final String loggerName = logger.getName(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ClassLoaderLogManagerClassLoaderLogInfo info = getClassLoaderInfo(classLoader); if (info.getLoggers().containsKey(loggerName)) { return false; } info.getLoggers().put(loggerName, logger); // Apply initial level for new logger final String levelString = getProperty(loggerName + ".level"); if (levelString != null) { try { AccessController.doPrivileged( new PrivilegedAction<Void>() { @Override public Void run() { logger.setLevel(Level.parse(levelString.trim())); return null; } }); } catch (IllegalArgumentException e) { // Leave level set to null } } // Always instantiate parent loggers so that // we can control log categories even during runtime int dotIndex = loggerName.lastIndexOf('.'); if (dotIndex >= 0) { final String parentName = loggerName.substring(0, dotIndex); Logger.getLogger(parentName); } // Find associated node ClassLoaderLogManagerLogNode node = info.getRootNode().findNode(loggerName); node.setLogger(logger); // Set parent logger Logger parentLogger = node.findParentLogger(); if (parentLogger != null) { doSetParentLogger(logger, parentLogger); } // Tell children we are their new parent node.setParentLogger(logger); // Add associated handlers, if any are defined using the .handlers property. // In this case, handlers of the parent logger(s) will not be used String handlers = getProperty(loggerName + ".handlers"); if (handlers != null) { logger.setUseParentHandlers(false); StringTokenizer tok = new StringTokenizer(handlers, ","); while (tok.hasMoreTokens()) { String handlerName = (tok.nextToken().trim()); Handler handler = null; ClassLoader current = classLoader; while (current != null) { info = classLoaderLoggers.get(current); if (info != null) { handler = info.getHandlers().get(handlerName); if (handler != null) { break; } } current = current.getParent(); } if (handler != null) { logger.addHandler(handler); } } } // Parse useParentHandlers to set if the logger should delegate to its parent. // Unlike java.util.logging, the default is to not delegate if a list of handlers // has been specified for the logger. String useParentHandlersString = getProperty(loggerName + ".useParentHandlers"); if (Boolean.valueOf(useParentHandlersString).booleanValue()) { logger.setUseParentHandlers(true); } return true; }
/** * Read configuration for the specified classloader. * * @param classLoader * @throws IOException Error */ protected void readConfiguration(ClassLoader classLoader) throws IOException { InputStream is = null; // Special case for URL classloaders which are used in containers: // only look in the local repositories to avoid redefining loggers 20 times try { if (classLoader instanceof URLClassLoader) { URL logConfig = ((URLClassLoader) classLoader).findResource("logging.properties"); if (null != logConfig) { if (Boolean.getBoolean(DEBUG_PROPERTY)) System.err.println( getClass().getName() + ".readConfiguration(): " + "Found logging.properties at " + logConfig); is = classLoader.getResourceAsStream("logging.properties"); } else { if (Boolean.getBoolean(DEBUG_PROPERTY)) System.err.println( getClass().getName() + ".readConfiguration(): " + "Found no logging.properties"); } } } catch (AccessControlException ace) { // No permission to configure logging in context // Log and carry on ClassLoaderLogManagerClassLoaderLogInfo info = classLoaderLoggers.get(ClassLoader.getSystemClassLoader()); if (info != null) { Logger log = info.getLoggers().get(""); if (log != null) { Permission perm = ace.getPermission(); if (perm instanceof FilePermission && perm.getActions().equals("read")) { log.warning( "Reading " + perm.getName() + " is not permitted. See \"per context logging\" in the default catalina.policy file."); } else { log.warning( "Reading logging.properties is not permitted in some context. See \"per context logging\" in the default catalina.policy file."); log.warning("Original error was: " + ace.getMessage()); } } } } if ((is == null) && (classLoader == ClassLoader.getSystemClassLoader())) { String configFileStr = System.getProperty("java.util.logging.config.file"); if (configFileStr != null) { try { is = new FileInputStream(replace(configFileStr)); } catch (IOException e) { // Ignore } } // Try the default JVM configuration if (is == null) { File defaultFile = new File(new File(System.getProperty("java.home"), "lib"), "logging.properties"); try { is = new FileInputStream(defaultFile); } catch (IOException e) { // Critical problem, do something ... } } } Logger localClassLoaderLogManagerRootLogger = new ClassLoaderLogManagerRootLogger(); if (is == null) { // Retrieve the root logger of the parent classloader instead ClassLoader current = classLoader.getParent(); ClassLoaderLogManagerClassLoaderLogInfo info = null; while (current != null && info == null) { info = getClassLoaderInfo(current); current = current.getParent(); } if (info != null) { localClassLoaderLogManagerRootLogger.setParent(info.getRootNode().getLogger()); } } ClassLoaderLogManagerClassLoaderLogInfo info = new ClassLoaderLogManagerClassLoaderLogInfo( new ClassLoaderLogManagerLogNode(null, localClassLoaderLogManagerRootLogger)); classLoaderLoggers.put(classLoader, info); if (is != null) { readConfiguration(is, classLoader); } addLogger(localClassLoaderLogManagerRootLogger); }