📄 logmanager.java
字号:
* <P> * Any log level definitions in the new configuration file will be * applied using Logger.setLevel(), if the target Logger exists. * <p> * A PropertyChangeEvent will be fired after the properties are read. * * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). * @exception IOException if there are IO problems reading the configuration. */ public void readConfiguration() throws IOException, SecurityException { checkAccess(); // if a configuration class is specified, load it and use it. String cname = System.getProperty("java.util.logging.config.class"); String contextLoadingConfig = System.getProperty("java.util.logging.manager.altclassloader"); if (cname != null) { try { // Instantiate the named class. It its contructor's // repsonsibility to initialize the logging configuration, by // calling readConfiguration(InputStream) with a suitable stream. try { Class clz = ClassLoader.getSystemClassLoader().loadClass(cname); clz.newInstance(); return; } catch (ClassNotFoundException ex) { if (null != contextLoadingConfig) { Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname); clz.newInstance(); return; }else { throw ex; } } } catch (Exception ex) { System.err.println("Logging configuration class \"" + cname + "\" failed"); System.err.println("" + ex); // keep going and useful config file. } } String fname = System.getProperty("java.util.logging.config.file"); if (fname == null) { fname = System.getProperty("java.home"); if (fname == null) { throw new Error("Can't find java.home ??"); } File f = new File(fname, "lib"); f = new File(f, "logging.properties"); fname = f.getCanonicalPath(); } InputStream in = new FileInputStream(fname); BufferedInputStream bin = new BufferedInputStream(in); try { readConfiguration(bin); } finally { if (in != null) { in.close(); } } } /** * Reset the logging configuration. * <p> * For all named loggers, the reset operation removes and closes * all Handlers and (except for the root logger) sets the level * to null. The root logger's level is set to Level.INFO. * * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ public void reset() throws SecurityException { checkAccess(); synchronized (this) { props = new Properties(); // Since we are doing a reset we no longer want to initialize // the global handlers, if they haven't been initialized yet. initializedGlobalHandlers = true; } Enumeration enum = getLoggerNames(); while (enum.hasMoreElements()) { String name = (String)enum.nextElement(); resetLogger(name); } } // Private method to reset an invidual target logger. private void resetLogger(String name) { Logger logger = getLogger(name); if (logger == null) { return; } // Close all the Logger's handlers. Handler[] targets = logger.getHandlers(); for (int i = 0; i < targets.length; i++) { Handler h = targets[i]; logger.removeHandler(h); try { h.close(); } catch (Exception ex) { // Problems closing a handler? Keep going... } } if (name != null && name.equals("")) { // This is the root logger. logger.setLevel(defaultLevel); } else { logger.setLevel(null); } } // get a list of whitespace separated classnames from a property. private String[] parseClassNames(String propertyName) { String hands = getProperty(propertyName); if (hands == null) { return new String[0]; } hands = hands.trim(); int ix = 0; Vector result = new Vector(); while (ix < hands.length()) { int end = ix; while (end < hands.length()) { if (Character.isWhitespace(hands.charAt(end))) { break; } if (hands.charAt(end) == ',') { break; } end++; } String word = hands.substring(ix, end); ix = end+1; word = word.trim(); if (word.length() == 0) { continue; } result.add(word); } return (String[]) result.toArray(new String[result.size()]); } /** * Reinitialize the logging properties and reread the logging configuration * from the given stream, which should be in java.util.Properties format. * A PropertyChangeEvent will be fired after the properties are read. * <p> * Any log level definitions in the new configuration file will be * applied using Logger.setLevel(), if the target Logger exists. * * @param ins stream to read properties from * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). * @exception IOException if there are problems reading from the stream. */ public void readConfiguration(InputStream ins) throws IOException, SecurityException { checkAccess(); reset(); // Load the properties props.load(ins); // Instantiate new configuration objects. String names[] = parseClassNames("config"); for (int i = 0; i < names.length; i++) { String word = names[i]; try { Class clz = ClassLoader.getSystemClassLoader().loadClass(word); clz.newInstance(); } catch (Exception ex) { System.err.println("Can't load config class \"" + word + "\""); System.err.println("" + ex); // ex.printStackTrace(); } } // Set levels on any pre-existing loggers, based on the new properties. setLevelsOnExistingLoggers(); // Notify any interested parties that our properties have changed. changes.firePropertyChange(null, null, null); // Note that we need to reinitialize global handles when // they are first referenced. synchronized (this) { initializedGlobalHandlers = false; } } /** * Get the value of a logging property. * @param name property name * @return property value */ public String getProperty(String name) { return props.getProperty(name); } // Package private method to get a String property. // If the property is not defined we return the given // default value. String getStringProperty(String name, String defaultValue) { String val = getProperty(name); if (val == null) { return defaultValue; } return val.trim(); } // Package private method to get an integer property. // If the property is not defined or cannot be parsed // we return the given default value. int getIntProperty(String name, int defaultValue) { String val = getProperty(name); if (val == null) { return defaultValue; } try { return Integer.parseInt(val.trim()); } catch (Exception ex) { return defaultValue; } } // Package private method to get a boolean property. // If the property is not defined or cannot be parsed // we return the given default value. boolean getBooleanProperty(String name, boolean defaultValue) { String val = getProperty(name); if (val == null) { return defaultValue; } val = val.toLowerCase(); if (val.equals("true") || val.equals("1")) { return true; } else if (val.equals("false") || val.equals("0")) { return false; } return defaultValue; } // Package private method to get a Level property. // If the property is not defined or cannot be parsed // we return the given default value. Level getLevelProperty(String name, Level defaultValue) { String val = getProperty(name); if (val == null) { return defaultValue; } try { return Level.parse(val.trim()); } catch (Exception ex) { return defaultValue; } } // Package private method to get a filter property. // We return an instance of the class named by the "name" // property. If the property is not defined or has problems // we return the defaultValue. Filter getFilterProperty(String name, Filter defaultValue) { String val = getProperty(name); try { if (val != null) { Class clz = ClassLoader.getSystemClassLoader().loadClass(val); return (Filter) clz.newInstance(); } } catch (Exception ex) { // We got one of a variety of exceptions in creating the // class or creating an instance. // Drop through. } // We got an exception. Return the defaultValue. return defaultValue; } // Package private method to get a formatter property. // We return an instance of the class named by the "name" // property. If the property is not defined or has problems // we return the defaultValue. Formatter getFormatterProperty(String name, Formatter defaultValue) { String val = getProperty(name); try { if (val != null) { Class clz = ClassLoader.getSystemClassLoader().loadClass(val); return (Formatter) clz.newInstance(); } } catch (Exception ex) { // We got one of a variety of exceptions in creating the // class or creating an instance. // Drop through. } // We got an exception. Return the defaultValue. return defaultValue; } // Private method to load the global handlers. // We do the real work lazily, when the global handlers // are first used. private synchronized void initializeGlobalHandlers() { if (initializedGlobalHandlers) { return; } initializedGlobalHandlers = true; if (deathImminent) { // Aaargh... // The VM is shutting down and our exit hook has been called. // Avoid allocating global handlers. return; } // We need to raise privilege here. All our decisions will // be made based on the logging configuration, which can // only be modified by trusted code. AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // Add new global handlers. String names[] = parseClassNames("handlers"); for (int i = 0; i < names.length; i++) { String word = names[i]; try { Class clz = ClassLoader.getSystemClassLoader().loadClass(word); Handler h = (Handler) clz.newInstance(); try { // Check if there is a property defining the // handler's level. String levs = getProperty(word + ".level"); if (levs != null) { h.setLevel(Level.parse(levs)); } } catch (Exception ex) { System.err.println("Can't set level for " + word); // Probably a bad level. Drop through. } rootLogger.addHandler(h); } catch (Exception ex) { System.err.println("Can't load log handler \"" + word + "\""); System.err.println("" + ex); ex.printStackTrace(); } } return null; }}); } private Permission ourPermission = new LoggingPermission("control", null); /** * Check that the current context is trusted to modify the logging * configuration. This requires LoggingPermission("control"). * <p> * If the check fails we throw a SecurityException, otherwise * we return normally. * * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ public void checkAccess() throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm == null) { return; } sm.checkPermission(ourPermission); } // Nested class to represent a node in our tree of named loggers. private static class LogNode { HashMap children; Logger logger; LogNode parent; LogNode(LogNode parent) { this.parent = parent; } // Recursive method to walk the tree below a node and set // a new parent logger. void walkAndSetParent(Logger parent) { if (children == null) { return; } Iterator values = children.values().iterator(); while (values.hasNext()) { LogNode node = (LogNode) values.next(); if (node.logger == null) { node.walkAndSetParent(parent); } else { doSetParent(node.logger, parent); } } } } // We use a subclass of Logger for the root logger, so // that we only instantiate the global handlers when they // are first needed. private class RootLogger extends Logger { private RootLogger() { super("", null); setLevel(defaultLevel); } public void log(LogRecord record) { // Make sure that the global handlers have been instantiated. initializeGlobalHandlers(); super.log(record); } public void addHandler(Handler h) { initializeGlobalHandlers(); super.addHandler(h); } public void removeHandler(Handler h) { initializeGlobalHandlers(); super.removeHandler(h); } public Handler[] getHandlers() { initializeGlobalHandlers(); return super.getHandlers(); } } // Private method to be called when the configuration has // changed to apply any level settings to any pre-existing loggers. synchronized private void setLevelsOnExistingLoggers() { Enumeration enum = props.propertyNames(); while (enum.hasMoreElements()) { String key = (String)enum.nextElement(); if (!key.endsWith(".level")) { // Not a level definition. continue; } int ix = key.length() - 6; String name = key.substring(0, ix); Level level = getLevelProperty(key, null); if (level == null) { System.err.println("Bad level value for property: " + key); continue; } Logger l = getLogger(name); if (l == null) { continue; } l.setLevel(level); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -