⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logmanager.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * @(#)LogManager.java	1.28 04/06/08 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.util.logging;import java.io.*;import java.util.*;import java.security.*;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeSupport;import java.net.URL;import sun.security.action.GetPropertyAction;/** * There is a single global LogManager object that is used to * maintain a set of shared state about Loggers and log services. * <p> * This LogManager object: * <ul> * <li> Manages a hierarchical namespace of Logger objects.  All *      named Loggers are stored in this namespace. * <li> Manages a set of logging control properties.  These are *      simple key-value pairs that can be used by Handlers and *      other logging objects to configure themselves. * </ul> * <p> * The global LogManager object can be retrieved using LogManager.getLogManager(). * The LogManager object is created during class initialization and * cannot subsequently be changed. * <p> * At startup the LogManager class is located using the  * java.util.logging.manager system property. * <p> * By default, the LogManager reads its initial configuration from  * a properties file "lib/logging.properties" in the JRE directory. * If you edit that property file you can change the default logging * configuration for all uses of that JRE. * <p> * In addition, the LogManager uses two optional system properties that * allow more control over reading the initial configuration: * <ul> * <li>"java.util.logging.config.class" * <li>"java.util.logging.config.file" * </ul> * These two properties may be set via the Preferences API, or as * command line property definitions to the "java" command, or as * system property definitions passed to JNI_CreateJavaVM. * <p> * If the "java.util.logging.config.class" property is set, then the * property value is treated as a class name.  The given class will be * loaded, an object will be instantiated, and that object's constructor * is responsible for reading in the initial configuration.  (That object * may use other system properties to control its configuration.)  The * alternate configuration class can use <tt>readConfiguration(InputStream)</tt> * to define properties in the LogManager. * <p> * If "java.util.logging.config.class" property is <b>not</b> set, * then the "java.util.logging.config.file" system property can be used * to specify a properties file (in java.util.Properties format). The * initial logging configuration will be read from this file. * <p> * If neither of these properties is defined then, as described * above, the LogManager will read its initial configuration from  * a properties file "lib/logging.properties" in the JRE directory. * <p> * The properties for loggers and Handlers will have names starting * with the dot-separated name for the handler or logger. * <p> * The global logging properties may include: * <ul> * <li>A property "handlers".  This defines a whitespace separated * list of class names for handler classes to load and register as * handlers on the root Logger (the Logger named "").  Each class * name must be for a Handler class which has a default constructor. * Note that these Handlers may be created lazily, when they are * first used. * * <li>A property "config".  This property is intended to allow * arbitrary configuration code to be run.  The property defines a * whitespace separated list of class names.  A new instance will be * created for each named class.  The default constructor of each class * may execute arbitrary code to update the logging configuration, such as * setting logger levels, adding handlers, adding filters, etc. * </ul> * <p> * Note that all classes loaded during LogManager configuration must * be on the system class path.  That includes the LogManager class, * any config classes, and any handler classes. * <p> * Loggers are organized into a naming hierarchy based on their * dot separated names.  Thus "a.b.c" is a child of "a.b", but * "a.b1" and a.b2" are peers. * <p> * All properties whose names end with ".level" are assumed to define * log levels for Loggers.  Thus "foo.level" defines a log level for * the logger called "foo" and (recursively) for any of its children * in the naming hierarchy.  Log Levels are applied in the order they  * are defined in the properties file.  Thus level settings for child * nodes in the tree should come after settings for their parents. * The property name ".level" can be used to set the level for the * root of the tree. * <p>  * All methods on the LogManager object are multi-thread safe. * * @version 1.28, 06/08/04 * @since 1.4*/public class LogManager {    // The global LogManager object    private static LogManager manager;    private final static Handler[] emptyHandlers = { };    private Properties props = new Properties();    private PropertyChangeSupport changes			 = new PropertyChangeSupport(LogManager.class);    private final static Level defaultLevel = Level.INFO;    // Table of known loggers.  Maps names to Loggers.    private Hashtable loggers = new Hashtable();    // Tree of known loggers    private LogNode root = new LogNode(null);    private Logger rootLogger;    // Have we done the primordial reading of the configuration file?    // (Must be done after a suitable amount of java.lang.System    // initialization has been done)    private volatile boolean readPrimordialConfiguration;    // Have we initialized global (root) handlers yet?    // This gets set to false in readConfiguration    private boolean initializedGlobalHandlers = true;    // True if JVM death is imminent and the exit hook has been called.    private boolean deathImminent;    static {	AccessController.doPrivileged(new PrivilegedAction() {                public Object run() {                    String cname = null;		    String contextLoading = null;                    try {                        cname = System.getProperty("java.util.logging.manager");                        if (cname != null) {			    try {                                Class clz = ClassLoader.getSystemClassLoader().loadClass(cname);                                manager = (LogManager) clz.newInstance();			    } catch (ClassNotFoundException ex) {				contextLoading = System.getProperty("java.util.logging.manager.altclassloader");				if (contextLoading != null) {				    Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname);				    manager = (LogManager) clz.newInstance();				} else {				    throw ex;				}			    }                        }                    } catch (Exception ex) {                        System.err.println("Could not load Logmanager \"" + cname + "\"");                        ex.printStackTrace();                    }                    if (manager == null) {                        manager = new LogManager();                    }                    // Create and retain Logger for the root of the namespace.                    manager.rootLogger = manager.new RootLogger();                    manager.addLogger(manager.rootLogger);                    // We don't call readConfiguration() here, as we may be running                    // very early in the JVM startup sequence.  Instead readConfiguration                    // will be called lazily in getLogManager().                    return null;                }            });    }    // This private class is used as a shutdown hook.    // It does a "reset" to close all open handlers.    private class Cleaner extends Thread {	public void run() {	    // If the global handlershaven't been initialized yet, we	    // don't want to initialize them just so we can close them!	    synchronized (LogManager.this) {		// Note that death is imminent.	        deathImminent = true;		initializedGlobalHandlers = true;	    }	    // Do a reset to close all active handlers.	    reset(); 	}    }    /**          * Protected constructor.  This is protected so that container applications     * (such as J2EE containers) can subclass the object.  It is non-public as     * it is intended that there only be one LogManager object, whose value is     * retrieved by calling Logmanager.getLogManager.     */    protected LogManager() {	// Add a shutdown hook to close the global handlers.	try {	    Runtime.getRuntime().addShutdownHook(new Cleaner());	} catch(IllegalStateException e) {	    // If the VM is already shutting down,	    // We do not need to register shutdownHook.	}    }    /**     * Return the global LogManager object.     */    public static LogManager getLogManager() {        if (manager != null) {            manager.readPrimordialConfiguration();        }	return manager;    }    private void readPrimordialConfiguration() {        if (!readPrimordialConfiguration) {            synchronized (this) {                if (!readPrimordialConfiguration) {                    // If System.in/out/err are null, it's a good                    // indication that we're still in the                    // bootstrapping phase                    if (System.out == null) {                        return;                    }                    readPrimordialConfiguration = true;                    try {                        AccessController.doPrivileged(new PrivilegedExceptionAction() {                                public Object run() throws Exception {                                    readConfiguration();                                    return null;                                }                            });                    } catch (Exception ex) {                        // System.err.println("Can't read logging configuration:");                        // ex.printStackTrace();                    }                }            }        }    }    /**     * Add an event listener to be invoked when the logging     * properties are re-read.     *     * @param l  event listener     * @exception  SecurityException  if a security manager exists and if     *             the caller does not have LoggingPermission("control").     */    public void addPropertyChangeListener(PropertyChangeListener l) throws SecurityException {	checkAccess();	changes.addPropertyChangeListener(l);    }    /**     * Remove an event listener for property change events.     * <P>     * Returns silently if the given listener is not found.     *      * @param l  event listener      * @exception  SecurityException  if a security manager exists and if     *             the caller does not have LoggingPermission("control").     */    public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException {	checkAccess();	changes.removePropertyChangeListener(l);    }    /**     * Add a named logger.  This does nothing and returns false if a logger     * with the same name is already registered.     * <p>     * The Logger factory methods call this method to register each     * newly created Logger.     * <p>     * The application should retain its own reference to the Logger      * object to avoid it being garbage collected.  The LogManager     * may only retain a weak reference.     *     * @param   logger the new logger.     * @return  true if the argument logger was registered successfully,     *          false if a logger of that name already exists.     * @exception NullPointerException if the logger name is null.     */    public synchronized boolean addLogger(Logger logger) {	String name = logger.getName();	if (name == null) {	    throw new NullPointerException();	}	Logger old = (Logger) loggers.get(name);	if (old != null) {	    // We already have a registered logger with the given name.	    return false;	}	// We're adding a new logger.	// Note that we are creating a strong reference here that will	// keep the Logger in existence indefinitely.	loggers.put(name, logger);	// Apply any initial level defined for the new logger.	Level level = getLevelProperty(name+".level", null);	if (level != null) {	    doSetLevel(logger, level);	}	// If any of the logger's parents have levels defined,	// make sure they are instantiated.	int ix = 1;	for (;;) {	    int ix2 = name.indexOf(".", ix);	    if (ix2 < 0) {		break;	    }	    String pname = name.substring(0,ix2);	    if (getProperty(pname+".level") != null) {		// This pname has a level definition.  Make sure it exists.		Logger plogger = Logger.getLogger(pname);	    }	    ix = ix2+1;	}	// Find the new node and its parent.	LogNode node = findNode(name);	node.logger = logger;	Logger parent = null;	LogNode nodep = node.parent;	while (nodep != null) {	    if (nodep.logger != null) {		parent = nodep.logger;		break;	    }	    nodep = nodep.parent;	}	if (parent != null) {            doSetParent(logger, parent);	}	// Walk over the children and tell them we are their new parent.	node.walkAndSetParent(logger);	return true;    }    // Private method to set a level on a logger.    // If necessary, we raise privilege before doing the call.    private static void doSetLevel(final Logger logger, final Level level) {	SecurityManager sm = System.getSecurityManager();	if (sm == null) {	    // There is no security manager, so things are easy.	    logger.setLevel(level);	    return;	} 	// There is a security manager.  Raise privilege before	// calling setLevel.	AccessController.doPrivileged(new PrivilegedAction() {	    public Object run() {	        logger.setLevel(level);		return null;	    }});    }    // Private method to set a parent on a logger.    // If necessary, we raise privilege before doing the setParent call.    private static void doSetParent(final Logger logger, final Logger parent) {	SecurityManager sm = System.getSecurityManager();	if (sm == null) {	    // There is no security manager, so things are easy.	    logger.setParent(parent);	    return;	} 	// There is a security manager.  Raise privilege before	// calling setParent.	AccessController.doPrivileged(new PrivilegedAction() {	    public Object run() {		logger.setParent(parent);		return null;	    }});    }    // Find a node in our tree of logger nodes.    // If necessary, create it.    private LogNode findNode(String name) {	if (name == null || name.equals("")) {	    return root;	}	LogNode node = root;	while (name.length() > 0) {	    int ix = name.indexOf(".");	    String head;	    if (ix > 0) {		head = name.substring(0,ix);		name = name.substring(ix+1);	    } else {		head = name;		name = "";	    }	    if (node.children == null) {		node.children = new HashMap();	    }	    LogNode child = (LogNode)node.children.get(head);	    if (child == null) {		child = new LogNode(node);		node.children.put(head, child);	    }	    node = child;	}	return node;    }    /**     * Method to find a named logger.     * <p>     * Note that since untrusted code may create loggers with     * arbitrary names this method should not be relied on to     * find Loggers for security sensitive logging.     * <p>     * @param name name of the logger      * @return  matching logger or null if none is found     */    public synchronized Logger getLogger(String name) {	return (Logger) loggers.get(name);    }    /**     * Get an enumeration of known logger names.     * <p>     * Note:  Loggers may be added dynamically as new classes are loaded.     * This method only reports on the loggers that are currently registered.     * <p>     * @return  enumeration of logger name strings     */    public synchronized Enumeration getLoggerNames() {	return loggers.keys();    }    /**     * Reinitialize the logging properties and reread the logging configuration.     * <p>     * The same rules are used for locating the configuration properties     * as are used at startup.  So normally the logging properties will     * be re-read from the same file that was used at startup.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -