You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							325 lines
						
					
					
						
							12 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							325 lines
						
					
					
						
							12 KiB
						
					
					
				
								// -*- C++ -*-
							 | 
						|
								// Module:  Log4CPLUS
							 | 
						|
								// File:    hierarchy.h
							 | 
						|
								// Created: 6/2001
							 | 
						|
								// Author:  Tad E. Smith
							 | 
						|
								//
							 | 
						|
								//
							 | 
						|
								// Copyright 2001-2010 Tad E. Smith
							 | 
						|
								//
							 | 
						|
								// Licensed 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.
							 | 
						|
								
							 | 
						|
								/** @file */
							 | 
						|
								
							 | 
						|
								#ifndef LOG4CPLUS_HIERARCHY_HEADER_
							 | 
						|
								#define LOG4CPLUS_HIERARCHY_HEADER_
							 | 
						|
								
							 | 
						|
								#include <log4cplus/config.hxx>
							 | 
						|
								
							 | 
						|
								#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
							 | 
						|
								#pragma once
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#include <log4cplus/logger.h>
							 | 
						|
								#include <log4cplus/thread/syncprims.h>
							 | 
						|
								#include <map>
							 | 
						|
								#include <memory>
							 | 
						|
								#include <vector>
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								namespace log4cplus {
							 | 
						|
								    // Forward Declarations
							 | 
						|
								    class HierarchyLocker;
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * This class is specialized in retrieving loggers by name and
							 | 
						|
								     * also maintaining the logger hierarchy.
							 | 
						|
								     *
							 | 
						|
								     * <em>The casual user should not have to deal with this class
							 | 
						|
								     * directly.</em>  However, if you are in an environment where
							 | 
						|
								     * multiple applications run in the same process, then read on.
							 | 
						|
								     *
							 | 
						|
								     * The structure of the logger hierarchy is maintained by the
							 | 
						|
								     * {@link #getInstance} method. The hierarchy is such that children
							 | 
						|
								     * link to their parent but parents do not have any pointers to their
							 | 
						|
								     * children. Moreover, loggers can be instantiated in any order, in
							 | 
						|
								     * particular descendant before ancestor.
							 | 
						|
								     *
							 | 
						|
								     * In case a descendant is created before a particular ancestor,
							 | 
						|
								     * then it creates a provision node for the ancestor and adds itself
							 | 
						|
								     * to the provision node. Other descendants of the same ancestor add
							 | 
						|
								     * themselves to the previously created provision node.
							 | 
						|
								     */
							 | 
						|
								    class LOG4CPLUS_EXPORT Hierarchy
							 | 
						|
								    {
							 | 
						|
								    public:
							 | 
						|
								        // DISABLE_OFF should be set to a value lower than all possible
							 | 
						|
								        // priorities.
							 | 
						|
								        static const LogLevel DISABLE_OFF;
							 | 
						|
								        static const LogLevel DISABLE_OVERRIDE;
							 | 
						|
								
							 | 
						|
								      // Ctors
							 | 
						|
								        /**
							 | 
						|
								         * Create a new Logger hierarchy.
							 | 
						|
								         */
							 | 
						|
								        Hierarchy();
							 | 
						|
								
							 | 
						|
								      // Dtor
							 | 
						|
								        virtual ~Hierarchy();
							 | 
						|
								
							 | 
						|
								      // Methods
							 | 
						|
								        /**
							 | 
						|
								         * This call will clear all logger definitions from the internal
							 | 
						|
								         * hashtable. Invoking this method will irrevocably mess up the
							 | 
						|
								         * logger hierarchy.
							 | 
						|
								         *                     
							 | 
						|
								         * You should <em>really</em> know what you are doing before
							 | 
						|
								         * invoking this method.
							 | 
						|
								         */
							 | 
						|
								        virtual void clear();
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Returns <code>true </code>if the named logger exists 
							 | 
						|
								         * (in the default hierarchy).
							 | 
						|
								         *                
							 | 
						|
								         * @param name The name of the logger to search for.
							 | 
						|
								         */
							 | 
						|
								        virtual bool exists(const log4cplus::tstring& name);
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Similar to {@link #disable(LogLevel)} except that the LogLevel
							 | 
						|
								         * argument is given as a log4cplus::tstring.  
							 | 
						|
								         */
							 | 
						|
								        virtual void disable(const log4cplus::tstring& loglevelStr);
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Disable all logging requests of LogLevel <em>equal to or
							 | 
						|
								         * below</em> the ll parameter <code>p</code>, for
							 | 
						|
								         * <em>all</em> loggers in this hierarchy. Logging requests of
							 | 
						|
								         * higher LogLevel then <code>p</code> remain unaffected.
							 | 
						|
								         *
							 | 
						|
								         * Nevertheless, if the
							 | 
						|
								         * BasicConfigurator::DISABLE_OVERRIDE_KEY property is set to
							 | 
						|
								         * true, then logging requests are evaluated as usual.
							 | 
						|
								         *
							 | 
						|
								         * The "disable" family of methods are there for speed. They
							 | 
						|
								         * allow printing methods such as debug, info, etc. to return
							 | 
						|
								         * immediately after an integer comparison without walking the
							 | 
						|
								         * logger hierarchy. In most modern computers an integer
							 | 
						|
								         * comparison is measured in nanoseconds where as a logger walk is
							 | 
						|
								         * measured in units of microseconds.
							 | 
						|
								         */
							 | 
						|
								        virtual void disable(LogLevel ll);
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Disable all logging requests regardless of logger and LogLevel.
							 | 
						|
								         * This method is equivalent to calling {@link #disable} with the
							 | 
						|
								         * argument FATAL_LOG_LEVEL, the highest possible LogLevel.
							 | 
						|
								         */
							 | 
						|
								        virtual void disableAll();
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Disable all Debug logging requests regardless of logger.
							 | 
						|
								         * This method is equivalent to calling {@link #disable} with the
							 | 
						|
								         * argument DEBUG_LOG_LEVEL.
							 | 
						|
								         */
							 | 
						|
								        virtual void disableDebug();
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Disable all Info logging requests regardless of logger.
							 | 
						|
								         * This method is equivalent to calling {@link #disable} with the
							 | 
						|
								         * argument INFO_LOG_LEVEL.
							 | 
						|
								         */
							 | 
						|
								        virtual void disableInfo();
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Undoes the effect of calling any of {@link #disable}, {@link
							 | 
						|
								         * #disableAll}, {@link #disableDebug} and {@link #disableInfo}
							 | 
						|
								         * methods. More precisely, invoking this method sets the Logger
							 | 
						|
								         * class internal variable called <code>disable</code> to its
							 | 
						|
								         * default "off" value.
							 | 
						|
								         */
							 | 
						|
								        virtual void enableAll();
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Return a new logger instance named as the first parameter using
							 | 
						|
								         * the default factory. 
							 | 
						|
								         *                
							 | 
						|
								         * If a logger of that name already exists, then it will be
							 | 
						|
								         * returned.  Otherwise, a new logger will be instantiated and
							 | 
						|
								         * then linked with its existing ancestors as well as children.
							 | 
						|
								         *                                    
							 | 
						|
								         * @param name The name of the logger to retrieve.
							 | 
						|
								         */
							 | 
						|
								        virtual Logger getInstance(const log4cplus::tstring& name);
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Return a new logger instance named as the first parameter using
							 | 
						|
								         * <code>factory</code>.
							 | 
						|
								         *                
							 | 
						|
								         * If a logger of that name already exists, then it will be
							 | 
						|
								         * returned.  Otherwise, a new logger will be instantiated by the
							 | 
						|
								         * <code>factory</code> parameter and linked with its existing
							 | 
						|
								         * ancestors as well as children.
							 | 
						|
								         *                                         
							 | 
						|
								         * @param name The name of the logger to retrieve.
							 | 
						|
								         * @param factory The factory that will make the new logger instance.
							 | 
						|
								         */
							 | 
						|
								        virtual Logger getInstance(const log4cplus::tstring& name, spi::LoggerFactory& factory);
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Returns all the currently defined loggers in this hierarchy.
							 | 
						|
								         *
							 | 
						|
								         * The root logger is <em>not</em> included in the returned list. 
							 | 
						|
								         */
							 | 
						|
								        virtual LoggerList getCurrentLoggers();
							 | 
						|
								
							 | 
						|
								        /** 
							 | 
						|
								         * Is the LogLevel specified by <code>level</code> enabled? 
							 | 
						|
								         */
							 | 
						|
								        virtual bool isDisabled(LogLevel level);
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Get the root of this hierarchy.
							 | 
						|
								         */
							 | 
						|
								        virtual Logger getRoot() const;
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Reset all values contained in this hierarchy instance to their
							 | 
						|
								         * default.  This removes all appenders from all loggers, sets
							 | 
						|
								         * the LogLevel of all non-root loggers to <code>NOT_SET_LOG_LEVEL</code>,
							 | 
						|
								         * sets their additivity flag to <code>true</code> and sets the LogLevel
							 | 
						|
								         * of the root logger to DEBUG_LOG_LEVEL.  Moreover, message disabling
							 | 
						|
								         * is set its default "off" value.
							 | 
						|
								         *
							 | 
						|
								         * Existing loggers are not removed. They are just reset.
							 | 
						|
								         *
							 | 
						|
								         * This method should be used sparingly and with care as it will
							 | 
						|
								         * block all logging until it is completed.</p>
							 | 
						|
								         */
							 | 
						|
								        virtual void resetConfiguration(); 
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Set the default LoggerFactory instance.
							 | 
						|
								         */
							 | 
						|
								        virtual void setLoggerFactory(std::auto_ptr<spi::LoggerFactory> factory);
							 | 
						|
								        
							 | 
						|
								        /**
							 | 
						|
								         * Returns the default LoggerFactory instance.
							 | 
						|
								         */
							 | 
						|
								        virtual spi::LoggerFactory* getLoggerFactory();
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Shutting down a hierarchy will <em>safely</em> close and remove
							 | 
						|
								         * all appenders in all loggers including the root logger.
							 | 
						|
								         *                
							 | 
						|
								         * Some appenders such as SocketAppender need to be closed before the
							 | 
						|
								         * application exits. Otherwise, pending logging events might be
							 | 
						|
								         * lost.
							 | 
						|
								         *
							 | 
						|
								         * The <code>shutdown</code> method is careful to close nested
							 | 
						|
								         * appenders before closing regular appenders. This is allows
							 | 
						|
								         * configurations where a regular appender is attached to a logger
							 | 
						|
								         * and again to a nested appender.
							 | 
						|
								         */
							 | 
						|
								        virtual void shutdown();
							 | 
						|
								
							 | 
						|
								    private:
							 | 
						|
								      // Types
							 | 
						|
								        typedef std::vector<Logger> ProvisionNode;
							 | 
						|
								        typedef std::map<log4cplus::tstring, ProvisionNode> ProvisionNodeMap;
							 | 
						|
								        typedef std::map<log4cplus::tstring, Logger> LoggerMap;
							 | 
						|
								
							 | 
						|
								      // Methods
							 | 
						|
								        /**
							 | 
						|
								         * This is the implementation of the <code>getInstance()</code> method.
							 | 
						|
								         * NOTE: This method does not lock the <code>hashtable_mutex</code>.
							 | 
						|
								         */
							 | 
						|
								        LOG4CPLUS_PRIVATE
							 | 
						|
								        virtual Logger getInstanceImpl(const log4cplus::tstring& name, 
							 | 
						|
								            spi::LoggerFactory& factory);
							 | 
						|
								        
							 | 
						|
								        /**
							 | 
						|
								         * This is the implementation of the <code>getCurrentLoggers()</code>.
							 | 
						|
								         * NOTE: This method does not lock the <code>hashtable_mutex</code>.
							 | 
						|
								         */
							 | 
						|
								        LOG4CPLUS_PRIVATE
							 | 
						|
								        virtual void initializeLoggerList(LoggerList& list) const;
							 | 
						|
								        
							 | 
						|
								        /**
							 | 
						|
								         * This method loops through all the *potential* parents of
							 | 
						|
								         * logger'. There 3 possible cases:
							 | 
						|
								         *
							 | 
						|
								         * 1) No entry for the potential parent of 'logger' exists
							 | 
						|
								         *
							 | 
						|
								         *    We create a ProvisionNode for this potential parent and insert
							 | 
						|
								         *    'logger' in that provision node.
							 | 
						|
								         *
							 | 
						|
								         * 2) There is an entry of type Logger for the potential parent.
							 | 
						|
								         *
							 | 
						|
								         *    The entry is 'logger's nearest existing parent. We update logger's
							 | 
						|
								         *    parent field with this entry. We also break from the loop
							 | 
						|
								         *    because updating our parent's parent is our parent's
							 | 
						|
								         *    responsibility.
							 | 
						|
								         *
							 | 
						|
								         * 3) There entry is of type ProvisionNode for this potential parent.
							 | 
						|
								         *
							 | 
						|
								         *    We add 'logger' to the list of children for this potential parent.
							 | 
						|
								         */
							 | 
						|
								        LOG4CPLUS_PRIVATE void updateParents(Logger const & logger);
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * We update the links for all the children that placed themselves
							 | 
						|
								         * in the provision node 'pn'. The second argument 'logger' is a
							 | 
						|
								         * reference for the newly created Logger, parent of all the
							 | 
						|
								         * children in 'pn'
							 | 
						|
								         *
							 | 
						|
								         * We loop on all the children 'c' in 'pn':
							 | 
						|
								         *
							 | 
						|
								         *    If the child 'c' has been already linked to a child of
							 | 
						|
								         *    'logger' then there is no need to update 'c'.
							 | 
						|
								         *
							 | 
						|
								         *   Otherwise, we set logger's parent field to c's parent and set
							 | 
						|
								         *   c's parent field to logger.
							 | 
						|
								         */
							 | 
						|
								        LOG4CPLUS_PRIVATE void updateChildren(ProvisionNode& pn,
							 | 
						|
								            Logger const & logger);
							 | 
						|
								
							 | 
						|
								     // Data
							 | 
						|
								        thread::Mutex hashtable_mutex;
							 | 
						|
								        std::auto_ptr<spi::LoggerFactory> defaultFactory;
							 | 
						|
								        ProvisionNodeMap provisionNodes;
							 | 
						|
								        LoggerMap loggerPtrs;
							 | 
						|
								        Logger root;
							 | 
						|
								
							 | 
						|
								        int disableValue;
							 | 
						|
								
							 | 
						|
								        bool emittedNoAppenderWarning;
							 | 
						|
								
							 | 
						|
								        // Disallow copying of instances of this class
							 | 
						|
								        Hierarchy(const Hierarchy&);
							 | 
						|
								        Hierarchy& operator=(const Hierarchy&);
							 | 
						|
								
							 | 
						|
								     // Friends
							 | 
						|
								        friend class log4cplus::spi::LoggerImpl;
							 | 
						|
								        friend class log4cplus::HierarchyLocker;
							 | 
						|
								    };
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								    LOG4CPLUS_EXPORT Hierarchy & getDefaultHierarchy ();
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								} // end namespace log4cplus
							 | 
						|
								
							 | 
						|
								#endif // LOG4CPLUS_HIERARCHY_HEADER_
							 | 
						|
								
							 |