Source Code Cross Referenced for LogManager.java in  » 6.0-JDK-Core » Collections-Jar-Zip-Logging-regex » java » util » logging » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » Collections Jar Zip Logging regex » java.util.logging 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.util.logging;
0027
0028        import java.io.*;
0029        import java.util.*;
0030        import java.security.*;
0031        import java.lang.ref.WeakReference;
0032        import java.beans.PropertyChangeListener;
0033        import java.beans.PropertyChangeSupport;
0034        import java.net.URL;
0035        import sun.security.action.GetPropertyAction;
0036
0037        /**
0038         * There is a single global LogManager object that is used to
0039         * maintain a set of shared state about Loggers and log services.
0040         * <p>
0041         * This LogManager object:
0042         * <ul>
0043         * <li> Manages a hierarchical namespace of Logger objects.  All
0044         *      named Loggers are stored in this namespace.
0045         * <li> Manages a set of logging control properties.  These are
0046         *      simple key-value pairs that can be used by Handlers and
0047         *      other logging objects to configure themselves.
0048         * </ul>
0049         * <p>
0050         * The global LogManager object can be retrieved using LogManager.getLogManager().
0051         * The LogManager object is created during class initialization and
0052         * cannot subsequently be changed.
0053         * <p>
0054         * At startup the LogManager class is located using the 
0055         * java.util.logging.manager system property.
0056         * <p>
0057         * By default, the LogManager reads its initial configuration from 
0058         * a properties file "lib/logging.properties" in the JRE directory.
0059         * If you edit that property file you can change the default logging
0060         * configuration for all uses of that JRE.
0061         * <p>
0062         * In addition, the LogManager uses two optional system properties that
0063         * allow more control over reading the initial configuration:
0064         * <ul>
0065         * <li>"java.util.logging.config.class"
0066         * <li>"java.util.logging.config.file"
0067         * </ul>
0068         * These two properties may be set via the Preferences API, or as
0069         * command line property definitions to the "java" command, or as
0070         * system property definitions passed to JNI_CreateJavaVM.
0071         * <p>
0072         * If the "java.util.logging.config.class" property is set, then the
0073         * property value is treated as a class name.  The given class will be
0074         * loaded, an object will be instantiated, and that object's constructor
0075         * is responsible for reading in the initial configuration.  (That object
0076         * may use other system properties to control its configuration.)  The
0077         * alternate configuration class can use <tt>readConfiguration(InputStream)</tt>
0078         * to define properties in the LogManager.
0079         * <p>
0080         * If "java.util.logging.config.class" property is <b>not</b> set,
0081         * then the "java.util.logging.config.file" system property can be used
0082         * to specify a properties file (in java.util.Properties format). The
0083         * initial logging configuration will be read from this file.
0084         * <p>
0085         * If neither of these properties is defined then, as described
0086         * above, the LogManager will read its initial configuration from 
0087         * a properties file "lib/logging.properties" in the JRE directory.
0088         * <p>
0089         * The properties for loggers and Handlers will have names starting
0090         * with the dot-separated name for the handler or logger.
0091         * <p>
0092         * The global logging properties may include:
0093         * <ul>
0094         * <li>A property "handlers".  This defines a whitespace or comma separated
0095         * list of class names for handler classes to load and register as
0096         * handlers on the root Logger (the Logger named "").  Each class
0097         * name must be for a Handler class which has a default constructor.
0098         * Note that these Handlers may be created lazily, when they are
0099         * first used.
0100         *
0101         * <li>A property "&lt;logger&gt;.handlers". This defines a whitespace or
0102         * comma separated list of class names for handlers classes to
0103         * load and register as handlers to the specified logger. Each class
0104         * name must be for a Handler class which has a default constructor.
0105         * Note that these Handlers may be created lazily, when they are
0106         * first used.
0107         *
0108         * <li>A property "&lt;logger&gt;.useParentHandlers". This defines a boolean
0109         * value. By default every logger calls its parent in addition to
0110         * handling the logging message itself, this often result in messages
0111         * being handled by the root logger as well. When setting this property
0112         * to false a Handler needs to be configured for this logger otherwise
0113         * no logging messages are delivered.
0114         *
0115         * <li>A property "config".  This property is intended to allow
0116         * arbitrary configuration code to be run.  The property defines a
0117         * whitespace or comma separated list of class names.  A new instance will be
0118         * created for each named class.  The default constructor of each class
0119         * may execute arbitrary code to update the logging configuration, such as
0120         * setting logger levels, adding handlers, adding filters, etc.
0121         * </ul>
0122         * <p>
0123         * Note that all classes loaded during LogManager configuration are
0124         * first searched on the system class path before any user class path.  
0125         * That includes the LogManager class, any config classes, and any 
0126         * handler classes.
0127         * <p>
0128         * Loggers are organized into a naming hierarchy based on their
0129         * dot separated names.  Thus "a.b.c" is a child of "a.b", but
0130         * "a.b1" and a.b2" are peers.
0131         * <p>
0132         * All properties whose names end with ".level" are assumed to define
0133         * log levels for Loggers.  Thus "foo.level" defines a log level for
0134         * the logger called "foo" and (recursively) for any of its children
0135         * in the naming hierarchy.  Log Levels are applied in the order they 
0136         * are defined in the properties file.  Thus level settings for child
0137         * nodes in the tree should come after settings for their parents.
0138         * The property name ".level" can be used to set the level for the
0139         * root of the tree.
0140         * <p> 
0141         * All methods on the LogManager object are multi-thread safe.
0142         *
0143         * @version 1.60, 05/18/07
0144         * @since 1.4
0145         */
0146
0147        public class LogManager {
0148            // The global LogManager object
0149            private static LogManager manager;
0150
0151            private final static Handler[] emptyHandlers = {};
0152            private Properties props = new Properties();
0153            private PropertyChangeSupport changes = new PropertyChangeSupport(
0154                    LogManager.class);
0155            private final static Level defaultLevel = Level.INFO;
0156
0157            // Table of known loggers.  Maps names to Loggers.
0158            private Hashtable<String, WeakReference<Logger>> loggers = new Hashtable<String, WeakReference<Logger>>();
0159            // Tree of known loggers
0160            private LogNode root = new LogNode(null);
0161            private Logger rootLogger;
0162
0163            // Have we done the primordial reading of the configuration file?
0164            // (Must be done after a suitable amount of java.lang.System
0165            // initialization has been done)
0166            private volatile boolean readPrimordialConfiguration;
0167            // Have we initialized global (root) handlers yet?
0168            // This gets set to false in readConfiguration
0169            private boolean initializedGlobalHandlers = true;
0170            // True if JVM death is imminent and the exit hook has been called.
0171            private boolean deathImminent;
0172
0173            static {
0174                AccessController.doPrivileged(new PrivilegedAction<Object>() {
0175                    public Object run() {
0176                        String cname = null;
0177                        try {
0178                            cname = System
0179                                    .getProperty("java.util.logging.manager");
0180                            if (cname != null) {
0181                                try {
0182                                    Class clz = ClassLoader
0183                                            .getSystemClassLoader().loadClass(
0184                                                    cname);
0185                                    manager = (LogManager) clz.newInstance();
0186                                } catch (ClassNotFoundException ex) {
0187                                    Class clz = Thread.currentThread()
0188                                            .getContextClassLoader().loadClass(
0189                                                    cname);
0190                                    manager = (LogManager) clz.newInstance();
0191                                }
0192                            }
0193                        } catch (Exception ex) {
0194                            System.err.println("Could not load Logmanager \""
0195                                    + cname + "\"");
0196                            ex.printStackTrace();
0197                        }
0198                        if (manager == null) {
0199                            manager = new LogManager();
0200                        }
0201
0202                        // Create and retain Logger for the root of the namespace.
0203                        manager.rootLogger = manager.new RootLogger();
0204                        manager.addLogger(manager.rootLogger);
0205
0206                        // Adding the global Logger. Doing so in the Logger.<clinit>
0207                        // would deadlock with the LogManager.<clinit>.
0208                        Logger.global.setLogManager(manager);
0209                        manager.addLogger(Logger.global);
0210
0211                        // We don't call readConfiguration() here, as we may be running
0212                        // very early in the JVM startup sequence.  Instead readConfiguration
0213                        // will be called lazily in getLogManager().
0214                        return null;
0215                    }
0216                });
0217            }
0218
0219            // This private class is used as a shutdown hook.
0220            // It does a "reset" to close all open handlers.
0221            private class Cleaner extends Thread {
0222                public void run() {
0223                    // This is to ensure the LogManager.<clinit> is completed
0224                    // before synchronized block. Otherwise deadlocks are possible.
0225                    LogManager mgr = manager;
0226
0227                    // If the global handlers haven't been initialized yet, we
0228                    // don't want to initialize them just so we can close them!
0229                    synchronized (LogManager.this ) {
0230                        // Note that death is imminent.
0231                        deathImminent = true;
0232                        initializedGlobalHandlers = true;
0233                    }
0234
0235                    // Do a reset to close all active handlers.
0236                    reset();
0237                }
0238            }
0239
0240            /**     
0241             * Protected constructor.  This is protected so that container applications
0242             * (such as J2EE containers) can subclass the object.  It is non-public as
0243             * it is intended that there only be one LogManager object, whose value is
0244             * retrieved by calling Logmanager.getLogManager.
0245             */
0246            protected LogManager() {
0247                // Add a shutdown hook to close the global handlers.
0248                try {
0249                    Runtime.getRuntime().addShutdownHook(new Cleaner());
0250                } catch (IllegalStateException e) {
0251                    // If the VM is already shutting down,
0252                    // We do not need to register shutdownHook. 
0253                }
0254            }
0255
0256            /**
0257             * Return the global LogManager object.
0258             */
0259            public static LogManager getLogManager() {
0260                if (manager != null) {
0261                    manager.readPrimordialConfiguration();
0262                }
0263                return manager;
0264            }
0265
0266            private void readPrimordialConfiguration() {
0267                if (!readPrimordialConfiguration) {
0268                    synchronized (this ) {
0269                        if (!readPrimordialConfiguration) {
0270                            // If System.in/out/err are null, it's a good
0271                            // indication that we're still in the
0272                            // bootstrapping phase
0273                            if (System.out == null) {
0274                                return;
0275                            }
0276                            readPrimordialConfiguration = true;
0277                            try {
0278                                AccessController
0279                                        .doPrivileged(new PrivilegedExceptionAction<Object>() {
0280                                            public Object run()
0281                                                    throws Exception {
0282                                                readConfiguration();
0283                                                return null;
0284                                            }
0285                                        });
0286                            } catch (Exception ex) {
0287                                // System.err.println("Can't read logging configuration:");
0288                                // ex.printStackTrace();
0289                            }
0290                        }
0291                    }
0292                }
0293            }
0294
0295            /**
0296             * Adds an event listener to be invoked when the logging
0297             * properties are re-read. Adding multiple instances of
0298             * the same event Listener results in multiple entries
0299             * in the property event listener table.
0300             *
0301             * @param l  event listener
0302             * @exception  SecurityException  if a security manager exists and if
0303             *             the caller does not have LoggingPermission("control").
0304             * @exception NullPointerException if the PropertyChangeListener is null.
0305             */
0306            public void addPropertyChangeListener(PropertyChangeListener l)
0307                    throws SecurityException {
0308                if (l == null) {
0309                    throw new NullPointerException();
0310                }
0311                checkAccess();
0312                changes.addPropertyChangeListener(l);
0313            }
0314
0315            /**
0316             * Removes an event listener for property change events.
0317             * If the same listener instance has been added to the listener table
0318             * through multiple invocations of <CODE>addPropertyChangeListener</CODE>,
0319             * then an equivalent number of 
0320             * <CODE>removePropertyChangeListener</CODE> invocations are required to remove
0321             * all instances of that listener from the listener table.
0322             * <P>
0323             * Returns silently if the given listener is not found.
0324             * 
0325             * @param l  event listener (can be null)
0326             * @exception  SecurityException  if a security manager exists and if
0327             *             the caller does not have LoggingPermission("control").
0328             */
0329            public void removePropertyChangeListener(PropertyChangeListener l)
0330                    throws SecurityException {
0331                checkAccess();
0332                changes.removePropertyChangeListener(l);
0333            }
0334
0335            // Package-level method.
0336            // Find or create a specified logger instance. If a logger has
0337            // already been created with the given name it is returned.
0338            // Otherwise a new logger instance is created and registered
0339            // in the LogManager global namespace.
0340            synchronized Logger demandLogger(String name) {
0341                Logger result = getLogger(name);
0342                if (result == null) {
0343                    result = new Logger(name, null);
0344                    addLogger(result);
0345                    result = getLogger(name);
0346                }
0347                return result;
0348            }
0349
0350            // If logger.getUseParentHandlers() returns 'true' and any of the logger's
0351            // parents have levels or handlers defined, make sure they are instantiated.
0352            private void processParentHandlers(Logger logger, String name) {
0353                int ix = 1;
0354                for (;;) {
0355                    int ix2 = name.indexOf(".", ix);
0356                    if (ix2 < 0) {
0357                        break;
0358                    }
0359                    String pname = name.substring(0, ix2);
0360
0361                    if (getProperty(pname + ".level") != null
0362                            || getProperty(pname + ".handlers") != null) {
0363                        // This pname has a level/handlers definition.
0364                        // Make sure it exists.
0365                        demandLogger(pname);
0366                    }
0367                    ix = ix2 + 1;
0368                }
0369            }
0370
0371            // Add new per logger handlers.
0372            // We need to raise privilege here. All our decisions will
0373            // be made based on the logging configuration, which can
0374            // only be modified by trusted code.
0375            private void loadLoggerHandlers(final Logger logger,
0376                    final String name, final String handlersPropertyName) {
0377                AccessController.doPrivileged(new PrivilegedAction<Object>() {
0378                    public Object run() {
0379                        if (logger != rootLogger) {
0380                            boolean useParent = getBooleanProperty(name
0381                                    + ".useParentHandlers", true);
0382                            if (!useParent) {
0383                                logger.setUseParentHandlers(false);
0384                            }
0385                        }
0386
0387                        String names[] = parseClassNames(handlersPropertyName);
0388                        for (int i = 0; i < names.length; i++) {
0389                            String word = names[i];
0390                            try {
0391                                Class clz = ClassLoader.getSystemClassLoader()
0392                                        .loadClass(word);
0393                                Handler hdl = (Handler) clz.newInstance();
0394                                try {
0395                                    // Check if there is a property defining the
0396                                    // this handler's level.
0397                                    String levs = getProperty(word + ".level");
0398                                    if (levs != null) {
0399                                        hdl.setLevel(Level.parse(levs));
0400                                    }
0401                                } catch (Exception ex) {
0402                                    System.err.println("Can't set level for "
0403                                            + word);
0404                                    // Probably a bad level. Drop through.
0405                                }
0406                                // Add this Handler to the logger
0407                                logger.addHandler(hdl);
0408                            } catch (Exception ex) {
0409                                System.err.println("Can't load log handler \""
0410                                        + word + "\"");
0411                                System.err.println("" + ex);
0412                                ex.printStackTrace();
0413                            }
0414                        }
0415                        return null;
0416                    }
0417                });
0418            }
0419
0420            /**
0421             * Add a named logger.  This does nothing and returns false if a logger
0422             * with the same name is already registered.
0423             * <p>
0424             * The Logger factory methods call this method to register each
0425             * newly created Logger.
0426             * <p>
0427             * The application should retain its own reference to the Logger 
0428             * object to avoid it being garbage collected.  The LogManager
0429             * may only retain a weak reference.
0430             *
0431             * @param   logger the new logger.
0432             * @return  true if the argument logger was registered successfully,
0433             *          false if a logger of that name already exists.
0434             * @exception NullPointerException if the logger name is null.
0435             */
0436            public synchronized boolean addLogger(Logger logger) {
0437                final String name = logger.getName();
0438                if (name == null) {
0439                    throw new NullPointerException();
0440                }
0441
0442                WeakReference<Logger> ref = loggers.get(name);
0443                if (ref != null) {
0444                    if (ref.get() == null) {
0445                        // Hashtable holds stale weak reference 
0446                        // to a logger which has been GC-ed.
0447                        // Allow to register new one.
0448                        loggers.remove(name);
0449                    } else {
0450                        // We already have a registered logger with the given name.
0451                        return false;
0452                    }
0453                }
0454
0455                // We're adding a new logger.
0456                // Note that we are creating a weak reference here.
0457                loggers.put(name, new WeakReference<Logger>(logger));
0458
0459                // Apply any initial level defined for the new logger.
0460                Level level = getLevelProperty(name + ".level", null);
0461                if (level != null) {
0462                    doSetLevel(logger, level);
0463                }
0464
0465                // Do we have a per logger handler too?
0466                // Note: this will add a 200ms penalty 
0467                loadLoggerHandlers(logger, name, name + ".handlers");
0468                processParentHandlers(logger, name);
0469
0470                // Find the new node and its parent.
0471                LogNode node = findNode(name);
0472                node.loggerRef = new WeakReference<Logger>(logger);
0473                Logger parent = null;
0474                LogNode nodep = node.parent;
0475                while (nodep != null) {
0476                    WeakReference<Logger> nodeRef = nodep.loggerRef;
0477                    if (nodeRef != null) {
0478                        parent = nodeRef.get();
0479                        if (parent != null) {
0480                            break;
0481                        }
0482                    }
0483                    nodep = nodep.parent;
0484                }
0485
0486                if (parent != null) {
0487                    doSetParent(logger, parent);
0488                }
0489                // Walk over the children and tell them we are their new parent.
0490                node.walkAndSetParent(logger);
0491
0492                return true;
0493            }
0494
0495            // Private method to set a level on a logger.
0496            // If necessary, we raise privilege before doing the call.
0497            private static void doSetLevel(final Logger logger,
0498                    final Level level) {
0499                SecurityManager sm = System.getSecurityManager();
0500                if (sm == null) {
0501                    // There is no security manager, so things are easy.
0502                    logger.setLevel(level);
0503                    return;
0504                }
0505                // There is a security manager.  Raise privilege before
0506                // calling setLevel.
0507                AccessController.doPrivileged(new PrivilegedAction<Object>() {
0508                    public Object run() {
0509                        logger.setLevel(level);
0510                        return null;
0511                    }
0512                });
0513            }
0514
0515            // Private method to set a parent on a logger.
0516            // If necessary, we raise privilege before doing the setParent call.
0517            private static void doSetParent(final Logger logger,
0518                    final Logger parent) {
0519                SecurityManager sm = System.getSecurityManager();
0520                if (sm == null) {
0521                    // There is no security manager, so things are easy.
0522                    logger.setParent(parent);
0523                    return;
0524                }
0525                // There is a security manager.  Raise privilege before
0526                // calling setParent.
0527                AccessController.doPrivileged(new PrivilegedAction<Object>() {
0528                    public Object run() {
0529                        logger.setParent(parent);
0530                        return null;
0531                    }
0532                });
0533            }
0534
0535            // Find a node in our tree of logger nodes.
0536            // If necessary, create it.
0537            private LogNode findNode(String name) {
0538                if (name == null || name.equals("")) {
0539                    return root;
0540                }
0541                LogNode node = root;
0542                while (name.length() > 0) {
0543                    int ix = name.indexOf(".");
0544                    String head;
0545                    if (ix > 0) {
0546                        head = name.substring(0, ix);
0547                        name = name.substring(ix + 1);
0548                    } else {
0549                        head = name;
0550                        name = "";
0551                    }
0552                    if (node.children == null) {
0553                        node.children = new HashMap<String, LogNode>();
0554                    }
0555                    LogNode child = node.children.get(head);
0556                    if (child == null) {
0557                        child = new LogNode(node);
0558                        node.children.put(head, child);
0559                    }
0560                    node = child;
0561                }
0562                return node;
0563            }
0564
0565            /**
0566             * Method to find a named logger.
0567             * <p>
0568             * Note that since untrusted code may create loggers with
0569             * arbitrary names this method should not be relied on to
0570             * find Loggers for security sensitive logging.
0571             * <p>
0572             * @param name name of the logger 
0573             * @return  matching logger or null if none is found
0574             */
0575            public synchronized Logger getLogger(String name) {
0576                WeakReference<Logger> ref = loggers.get(name);
0577                if (ref == null) {
0578                    return null;
0579                }
0580                Logger logger = ref.get();
0581                if (logger == null) {
0582                    // Hashtable holds stale weak reference 
0583                    // to a logger which has been GC-ed.
0584                    loggers.remove(name);
0585                }
0586                return logger;
0587            }
0588
0589            /**
0590             * Get an enumeration of known logger names.
0591             * <p>
0592             * Note:  Loggers may be added dynamically as new classes are loaded.
0593             * This method only reports on the loggers that are currently registered.
0594             * <p>
0595             * @return  enumeration of logger name strings
0596             */
0597            public synchronized Enumeration<String> getLoggerNames() {
0598                return loggers.keys();
0599            }
0600
0601            /**
0602             * Reinitialize the logging properties and reread the logging configuration.
0603             * <p>
0604             * The same rules are used for locating the configuration properties
0605             * as are used at startup.  So normally the logging properties will
0606             * be re-read from the same file that was used at startup.
0607             * <P>
0608             * Any log level definitions in the new configuration file will be 
0609             * applied using Logger.setLevel(), if the target Logger exists.
0610             * <p>
0611             * A PropertyChangeEvent will be fired after the properties are read.
0612             * 
0613             * @exception  SecurityException  if a security manager exists and if
0614             *             the caller does not have LoggingPermission("control").
0615             * @exception  IOException if there are IO problems reading the configuration.
0616             */
0617            public void readConfiguration() throws IOException,
0618                    SecurityException {
0619                checkAccess();
0620
0621                // if a configuration class is specified, load it and use it.
0622                String cname = System
0623                        .getProperty("java.util.logging.config.class");
0624                if (cname != null) {
0625                    try {
0626                        // Instantiate the named class.  It is its constructor's
0627                        // responsibility to initialize the logging configuration, by
0628                        // calling readConfiguration(InputStream) with a suitable stream.
0629                        try {
0630                            Class clz = ClassLoader.getSystemClassLoader()
0631                                    .loadClass(cname);
0632                            clz.newInstance();
0633                            return;
0634                        } catch (ClassNotFoundException ex) {
0635                            Class clz = Thread.currentThread()
0636                                    .getContextClassLoader().loadClass(cname);
0637                            clz.newInstance();
0638                            return;
0639                        }
0640                    } catch (Exception ex) {
0641                        System.err.println("Logging configuration class \""
0642                                + cname + "\" failed");
0643                        System.err.println("" + ex);
0644                        // keep going and useful config file.
0645                    }
0646                }
0647
0648                String fname = System
0649                        .getProperty("java.util.logging.config.file");
0650                if (fname == null) {
0651                    fname = System.getProperty("java.home");
0652                    if (fname == null) {
0653                        throw new Error("Can't find java.home ??");
0654                    }
0655                    File f = new File(fname, "lib");
0656                    f = new File(f, "logging.properties");
0657                    fname = f.getCanonicalPath();
0658                }
0659                InputStream in = new FileInputStream(fname);
0660                BufferedInputStream bin = new BufferedInputStream(in);
0661                try {
0662                    readConfiguration(bin);
0663                } finally {
0664                    if (in != null) {
0665                        in.close();
0666                    }
0667                }
0668            }
0669
0670            /**
0671             * Reset the logging configuration.
0672             * <p>
0673             * For all named loggers, the reset operation removes and closes
0674             * all Handlers and (except for the root logger) sets the level
0675             * to null.  The root logger's level is set to Level.INFO.
0676             *
0677             * @exception  SecurityException  if a security manager exists and if
0678             *             the caller does not have LoggingPermission("control").
0679             */
0680
0681            public void reset() throws SecurityException {
0682                checkAccess();
0683                synchronized (this ) {
0684                    props = new Properties();
0685                    // Since we are doing a reset we no longer want to initialize
0686                    // the global handlers, if they haven't been initialized yet.
0687                    initializedGlobalHandlers = true;
0688                }
0689                Enumeration enum_ = getLoggerNames();
0690                while (enum_.hasMoreElements()) {
0691                    String name = (String) enum_.nextElement();
0692                    resetLogger(name);
0693                }
0694            }
0695
0696            // Private method to reset an individual target logger.
0697            private void resetLogger(String name) {
0698                Logger logger = getLogger(name);
0699                if (logger == null) {
0700                    return;
0701                }
0702                // Close all the Logger's handlers.
0703                Handler[] targets = logger.getHandlers();
0704                for (int i = 0; i < targets.length; i++) {
0705                    Handler h = targets[i];
0706                    logger.removeHandler(h);
0707                    try {
0708                        h.close();
0709                    } catch (Exception ex) {
0710                        // Problems closing a handler?  Keep going...
0711                    }
0712                }
0713                if (name != null && name.equals("")) {
0714                    // This is the root logger.
0715                    logger.setLevel(defaultLevel);
0716                } else {
0717                    logger.setLevel(null);
0718                }
0719            }
0720
0721            // get a list of whitespace separated classnames from a property.
0722            private String[] parseClassNames(String propertyName) {
0723                String hands = getProperty(propertyName);
0724                if (hands == null) {
0725                    return new String[0];
0726                }
0727                hands = hands.trim();
0728                int ix = 0;
0729                Vector<String> result = new Vector<String>();
0730                while (ix < hands.length()) {
0731                    int end = ix;
0732                    while (end < hands.length()) {
0733                        if (Character.isWhitespace(hands.charAt(end))) {
0734                            break;
0735                        }
0736                        if (hands.charAt(end) == ',') {
0737                            break;
0738                        }
0739                        end++;
0740                    }
0741                    String word = hands.substring(ix, end);
0742                    ix = end + 1;
0743                    word = word.trim();
0744                    if (word.length() == 0) {
0745                        continue;
0746                    }
0747                    result.add(word);
0748                }
0749                return result.toArray(new String[result.size()]);
0750            }
0751
0752            /**
0753             * Reinitialize the logging properties and reread the logging configuration
0754             * from the given stream, which should be in java.util.Properties format.
0755             * A PropertyChangeEvent will be fired after the properties are read.
0756             * <p>
0757             * Any log level definitions in the new configuration file will be 
0758             * applied using Logger.setLevel(), if the target Logger exists.
0759             * 
0760             * @param ins	stream to read properties from
0761             * @exception  SecurityException  if a security manager exists and if
0762             *             the caller does not have LoggingPermission("control").
0763             * @exception  IOException if there are problems reading from the stream.
0764             */
0765            public void readConfiguration(InputStream ins) throws IOException,
0766                    SecurityException {
0767                checkAccess();
0768                reset();
0769
0770                // Load the properties
0771                props.load(ins);
0772                // Instantiate new configuration objects.
0773                String names[] = parseClassNames("config");
0774
0775                for (int i = 0; i < names.length; i++) {
0776                    String word = names[i];
0777                    try {
0778                        Class clz = ClassLoader.getSystemClassLoader()
0779                                .loadClass(word);
0780                        clz.newInstance();
0781                    } catch (Exception ex) {
0782                        System.err.println("Can't load config class \"" + word
0783                                + "\"");
0784                        System.err.println("" + ex);
0785                        // ex.printStackTrace();
0786                    }
0787                }
0788
0789                // Set levels on any pre-existing loggers, based on the new properties.
0790                setLevelsOnExistingLoggers();
0791
0792                // Notify any interested parties that our properties have changed.
0793                changes.firePropertyChange(null, null, null);
0794
0795                // Note that we need to reinitialize global handles when 
0796                // they are first referenced.
0797                synchronized (this ) {
0798                    initializedGlobalHandlers = false;
0799                }
0800            }
0801
0802            /**
0803             * Get the value of a logging property.
0804             * The method returns null if the property is not found.
0805             * @param name	property name
0806             * @return		property value
0807             */
0808            public String getProperty(String name) {
0809                return props.getProperty(name);
0810            }
0811
0812            // Package private method to get a String property.
0813            // If the property is not defined we return the given
0814            // default value.
0815            String getStringProperty(String name, String defaultValue) {
0816                String val = getProperty(name);
0817                if (val == null) {
0818                    return defaultValue;
0819                }
0820                return val.trim();
0821            }
0822
0823            // Package private method to get an integer property.
0824            // If the property is not defined or cannot be parsed
0825            // we return the given default value.
0826            int getIntProperty(String name, int defaultValue) {
0827                String val = getProperty(name);
0828                if (val == null) {
0829                    return defaultValue;
0830                }
0831                try {
0832                    return Integer.parseInt(val.trim());
0833                } catch (Exception ex) {
0834                    return defaultValue;
0835                }
0836            }
0837
0838            // Package private method to get a boolean property.
0839            // If the property is not defined or cannot be parsed
0840            // we return the given default value.
0841            boolean getBooleanProperty(String name, boolean defaultValue) {
0842                String val = getProperty(name);
0843                if (val == null) {
0844                    return defaultValue;
0845                }
0846                val = val.toLowerCase();
0847                if (val.equals("true") || val.equals("1")) {
0848                    return true;
0849                } else if (val.equals("false") || val.equals("0")) {
0850                    return false;
0851                }
0852                return defaultValue;
0853            }
0854
0855            // Package private method to get a Level property.
0856            // If the property is not defined or cannot be parsed
0857            // we return the given default value.
0858            Level getLevelProperty(String name, Level defaultValue) {
0859                String val = getProperty(name);
0860                if (val == null) {
0861                    return defaultValue;
0862                }
0863                try {
0864                    return Level.parse(val.trim());
0865                } catch (Exception ex) {
0866                    return defaultValue;
0867                }
0868            }
0869
0870            // Package private method to get a filter property.
0871            // We return an instance of the class named by the "name" 
0872            // property. If the property is not defined or has problems
0873            // we return the defaultValue.
0874            Filter getFilterProperty(String name, Filter defaultValue) {
0875                String val = getProperty(name);
0876                try {
0877                    if (val != null) {
0878                        Class clz = ClassLoader.getSystemClassLoader()
0879                                .loadClass(val);
0880                        return (Filter) clz.newInstance();
0881                    }
0882                } catch (Exception ex) {
0883                    // We got one of a variety of exceptions in creating the
0884                    // class or creating an instance.
0885                    // Drop through.
0886                }
0887                // We got an exception.  Return the defaultValue.
0888                return defaultValue;
0889            }
0890
0891            // Package private method to get a formatter property.
0892            // We return an instance of the class named by the "name" 
0893            // property. If the property is not defined or has problems
0894            // we return the defaultValue.
0895            Formatter getFormatterProperty(String name, Formatter defaultValue) {
0896                String val = getProperty(name);
0897                try {
0898                    if (val != null) {
0899                        Class clz = ClassLoader.getSystemClassLoader()
0900                                .loadClass(val);
0901                        return (Formatter) clz.newInstance();
0902                    }
0903                } catch (Exception ex) {
0904                    // We got one of a variety of exceptions in creating the
0905                    // class or creating an instance.
0906                    // Drop through.
0907                }
0908                // We got an exception.  Return the defaultValue.
0909                return defaultValue;
0910            }
0911
0912            // Private method to load the global handlers.
0913            // We do the real work lazily, when the global handlers
0914            // are first used.
0915            private synchronized void initializeGlobalHandlers() {
0916                if (initializedGlobalHandlers) {
0917                    return;
0918                }
0919
0920                initializedGlobalHandlers = true;
0921
0922                if (deathImminent) {
0923                    // Aaargh...
0924                    // The VM is shutting down and our exit hook has been called.
0925                    // Avoid allocating global handlers.
0926                    return;
0927                }
0928                loadLoggerHandlers(rootLogger, null, "handlers");
0929            }
0930
0931            private Permission ourPermission = new LoggingPermission("control",
0932                    null);
0933
0934            /**
0935             * Check that the current context is trusted to modify the logging
0936             * configuration.  This requires LoggingPermission("control").
0937             * <p>
0938             * If the check fails we throw a SecurityException, otherwise
0939             * we return normally.
0940             *
0941             * @exception  SecurityException  if a security manager exists and if
0942             *             the caller does not have LoggingPermission("control").
0943             */
0944            public void checkAccess() throws SecurityException {
0945                SecurityManager sm = System.getSecurityManager();
0946                if (sm == null) {
0947                    return;
0948                }
0949                sm.checkPermission(ourPermission);
0950            }
0951
0952            // Nested class to represent a node in our tree of named loggers.
0953            private static class LogNode {
0954                HashMap<String, LogNode> children;
0955                WeakReference<Logger> loggerRef;
0956                LogNode parent;
0957
0958                LogNode(LogNode parent) {
0959                    this .parent = parent;
0960                }
0961
0962                // Recursive method to walk the tree below a node and set
0963                // a new parent logger.
0964                void walkAndSetParent(Logger parent) {
0965                    if (children == null) {
0966                        return;
0967                    }
0968                    Iterator<LogNode> values = children.values().iterator();
0969                    while (values.hasNext()) {
0970                        LogNode node = values.next();
0971                        WeakReference<Logger> ref = node.loggerRef;
0972                        Logger logger = (ref == null) ? null : ref.get();
0973                        if (logger == null) {
0974                            node.walkAndSetParent(parent);
0975                        } else {
0976                            doSetParent(logger, parent);
0977                        }
0978                    }
0979                }
0980            }
0981
0982            // We use a subclass of Logger for the root logger, so
0983            // that we only instantiate the global handlers when they
0984            // are first needed.
0985            private class RootLogger extends Logger {
0986
0987                private RootLogger() {
0988                    super ("", null);
0989                    setLevel(defaultLevel);
0990                }
0991
0992                public void log(LogRecord record) {
0993                    // Make sure that the global handlers have been instantiated.
0994                    initializeGlobalHandlers();
0995                    super .log(record);
0996                }
0997
0998                public void addHandler(Handler h) {
0999                    initializeGlobalHandlers();
1000                    super .addHandler(h);
1001                }
1002
1003                public void removeHandler(Handler h) {
1004                    initializeGlobalHandlers();
1005                    super .removeHandler(h);
1006                }
1007
1008                public Handler[] getHandlers() {
1009                    initializeGlobalHandlers();
1010                    return super .getHandlers();
1011                }
1012            }
1013
1014            // Private method to be called when the configuration has
1015            // changed to apply any level settings to any pre-existing loggers.
1016            synchronized private void setLevelsOnExistingLoggers() {
1017                Enumeration enum_ = props.propertyNames();
1018                while (enum_.hasMoreElements()) {
1019                    String key = (String) enum_.nextElement();
1020                    if (!key.endsWith(".level")) {
1021                        // Not a level definition.
1022                        continue;
1023                    }
1024                    int ix = key.length() - 6;
1025                    String name = key.substring(0, ix);
1026                    Level level = getLevelProperty(key, null);
1027                    if (level == null) {
1028                        System.err.println("Bad level value for property: "
1029                                + key);
1030                        continue;
1031                    }
1032                    Logger l = getLogger(name);
1033                    if (l == null) {
1034                        continue;
1035                    }
1036                    l.setLevel(level);
1037                }
1038            }
1039
1040            // Management Support
1041            private static LoggingMXBean loggingMXBean = null;
1042            /**
1043             * String representation of the
1044             * {@link javax.management.ObjectName} for {@link LoggingMXBean}.
1045             * @since 1.5
1046             */
1047            public final static String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
1048
1049            /**
1050             * Returns <tt>LoggingMXBean</tt> for managing loggers. 
1051             * The <tt>LoggingMXBean</tt> can also obtained from the 
1052             * {@link java.lang.management.ManagementFactory#getPlatformMBeanServer
1053             * platform <tt>MBeanServer</tt>} method.
1054             *
1055             * @return a {@link LoggingMXBean} object.
1056             *
1057             * @see java.lang.management.ManagementFactory
1058             * @since 1.5
1059             */
1060            public static synchronized LoggingMXBean getLoggingMXBean() {
1061                if (loggingMXBean == null) {
1062                    loggingMXBean = new Logging();
1063                }
1064                return loggingMXBean;
1065            }
1066
1067        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.