| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef _DECAF_UTIL_LOGGING_LOGMANAGER_H_ |
| #define _DECAF_UTIL_LOGGING_LOGMANAGER_H_ |
| |
| #include <map> |
| #include <list> |
| #include <string> |
| #include <vector> |
| |
| #include <decaf/lang/Pointer.h> |
| #include <decaf/util/Properties.h> |
| #include <decaf/util/concurrent/Mutex.h> |
| #include <decaf/util/Config.h> |
| |
| #include <decaf/io/IOException.h> |
| #include <decaf/lang/exceptions/NullPointerException.h> |
| #include <decaf/lang/exceptions/IllegalArgumentException.h> |
| |
| namespace decaf{ |
| namespace lang{ |
| class Runtime; |
| } |
| namespace io{ |
| class InputStream; |
| } |
| namespace util{ |
| namespace logging{ |
| |
| class Logger; |
| class LogManagerInternals; |
| class PropertyChangeListener; |
| |
| using decaf::lang::Pointer; |
| |
| /** |
| * There is a single global LogManager object that is used to maintain |
| * a set of shared state about Loggers and log services. |
| * |
| * This LogManager object: |
| * |
| * * Manages a hierarchical namespace of Logger objects. All named |
| * Loggers are stored in this namespace. |
| * * 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. |
| * |
| * The global LogManager object can be retrieved using |
| * LogManager::getLogManager(). The LogManager object is created during |
| * class initialization and cannot subsequently be changed. |
| * |
| * ***TODO**** |
| * 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. |
| * |
| * In addition, the LogManager uses two optional system properties that |
| * allow more control over reading the initial configuration: |
| * |
| * * "decaf.logger.config.class" |
| * * "decaf.logger.config.file" |
| * |
| * 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. |
| * |
| * 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 readConfiguration(InputStream) |
| * to define properties in the LogManager. |
| * |
| * If "decaf.util.logging.config.class" property is not set, then the |
| * "decaf.util.logging.config.file" system property can be used to specify |
| * a properties file (in decaf.util.Properties format). The initial |
| * logging configuration will be read from this file. |
| * |
| * 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 working directory. |
| * |
| * The properties for loggers and Handlers will have names starting with |
| * the dot-separated name for the handler or logger. |
| * ***TODO**** |
| * |
| * The global logging properties may include: |
| * |
| * * 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. |
| * * A property "<logger>.handlers". This defines a whitespace or |
| * comma separated list of class names for handlers classes to load |
| * and register as handlers to the specified logger. 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. |
| * * A property "<logger>.useParentHandlers". This defines a boolean |
| * value. By default every logger calls its parent in addition to |
| * handling the logging message itself, this often result in |
| * messages being handled by the root logger as well. When setting |
| * this property to false a Handler needs to be configured for this |
| * logger otherwise no logging messages are delivered. |
| * * 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. |
| * |
| * 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. |
| * |
| * 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. |
| * |
| * All methods on the LogManager object are multi-thread safe. |
| * |
| * @since 1.0 |
| */ |
| class DECAF_API LogManager { |
| private: |
| |
| // Change listener on this class's Properties |
| std::list<PropertyChangeListener*> listeners; |
| |
| // Properties of the Log Manager |
| util::Properties properties; |
| |
| // Data structure for LogManager Internal data. |
| LogManagerInternals* internal; |
| |
| public: |
| |
| virtual ~LogManager(); |
| |
| /** |
| * Add a named logger. This does nothing and returns false if a logger with |
| * the same name is already registered. |
| * |
| * The Logger factory methods call this method to register each newly created Logger. |
| * |
| * @param logger |
| * The new Logger instance to add to this LogManager. |
| * |
| * @throws NullPointerException if logger is NULL. |
| * @throws IllegalArgumentException if the logger has no name. |
| */ |
| bool addLogger( Logger* logger ); |
| |
| /** |
| * Retrieves or creates a new Logger using the name specified |
| * a new logger inherits the configuration of the logger's |
| * parent if there is no configuration data for the logger. |
| * @param name The name of the Logger. |
| */ |
| Logger* getLogger( const std::string& name ); |
| |
| /** |
| * Gets a list of known Logger Names from this Manager, new loggers added |
| * while this method is in progress are not garunteed to be in the list. |
| * |
| * @param names |
| * STL Vector to hold string logger names. |
| * |
| * @return names count of how many loggers were inserted. |
| */ |
| int getLoggerNames( const std::vector<std::string>& names ); |
| |
| /** |
| * Sets the Properties this LogManager should use to configure |
| * its loggers. Once set a properties change event is fired. |
| * @param properties Pointer to read the configuration from |
| */ |
| void setProperties( const util::Properties& properties ); |
| |
| /** |
| * Gets a reference to the Logging Properties used by this |
| * logger. |
| * @return The Logger Properties Pointer |
| */ |
| const util::Properties& getProperties() const { |
| return properties; |
| } |
| |
| /** |
| * Gets the value of a named property of this LogManager. |
| * |
| * @param name |
| * The name of the Property to retrieve. |
| * |
| * @return the value of the property |
| */ |
| std::string getProperty( const std::string& name ); |
| |
| /** |
| * Adds a change listener for LogManager Properties, adding the same |
| * instance of a change event listener does nothing. |
| * |
| * @param listener |
| * The PropertyChangeListener to add (can be NULL). |
| */ |
| void addPropertyChangeListener( PropertyChangeListener* listener ); |
| |
| /** |
| * Removes a properties change listener from the LogManager, if the |
| * listener is not found of the param is NULL this method returns |
| * silently. |
| * |
| * @param listener |
| * The PropertyChangeListener to remove from the listeners set. |
| */ |
| void removePropertyChangeListener( PropertyChangeListener* listener ); |
| |
| /** |
| * Reinitialize the logging properties and reread the logging configuration. |
| * |
| * 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. |
| * |
| * Any log level definitions in the new configuration file will be applied using |
| * Logger.setLevel(), if the target Logger exists. |
| * |
| * A PropertyChangeEvent will be fired after the properties are read. |
| * |
| * @throws IOException if an I/O error occurs. |
| */ |
| void readConfiguration(); |
| |
| /** |
| * Reinitialize the logging properties and reread the logging configuration from the |
| * given stream, which should be in decaf.util.Properties format. A PropertyChangeEvent |
| * will be fired after the properties are read. |
| * |
| * Any log level definitions in the new configuration file will be applied using |
| * Logger.setLevel(), if the target Logger exists. |
| * |
| * @param stream |
| * The InputStream to read the Properties from. |
| * |
| * @throws NullPointerException if stream is NULL. |
| * @throws IOException if an I/O error occurs. |
| */ |
| void readConfiguration( decaf::io::InputStream* stream ); |
| |
| /** |
| * Reset the logging configuration. |
| * |
| * For all named loggers, the reset operation removes and closes all Handlers and |
| * (except for the root logger) sets the level to INHERIT. The root logger's level |
| * is set to Level::INFO. |
| */ |
| void reset(); |
| |
| public: // Static Singleton Methods. |
| |
| /** |
| * Get the global LogManager instance. |
| * @return A reference to the global LogManager instance. |
| */ |
| static LogManager& getLogManager(); |
| |
| private: |
| |
| /** |
| * Initialize the Logging subsystem. |
| */ |
| static void initialize(); |
| |
| /** |
| * Shutdown the Logging subsystem. |
| */ |
| static void shutdown(); |
| |
| protected: |
| |
| /** |
| * Constructor, hidden to protect against direct instantiation |
| */ |
| LogManager(); |
| |
| /** |
| * Copy Constructor |
| * @param manager the Manager to copy |
| */ |
| LogManager( const LogManager& manager ); |
| |
| /** |
| * Assignment operator |
| * @param manager the manager to assign from |
| */ |
| void operator=( const LogManager& manager ); |
| |
| private: |
| |
| friend class decaf::lang::Runtime; |
| |
| }; |
| |
| }}} |
| |
| #endif /*_DECAF_UTIL_LOGGING_LOGMANAGER_H_*/ |