1 // Module:  Log4CPLUS
  2 // File:    hierarchy.h
  3 // Created: 6/2001
  4 // Author:  Tad E. Smith
  5 //
  6 //
  7 // Copyright (C) Tad E. Smith  All rights reserved.
  8 //
  9 // This software is published under the terms of the Apache Software
 10 // License version 1.1, a copy of which has been included with this
 11 // distribution in the LICENSE.APL file.
 12 //
 13 
 14 /** @file */
 15 
 16 #ifndef _LOG4CPLUS_HIERARCHY_HEADER_
 17 #define _LOG4CPLUS_HIERARCHY_HEADER_
 18 
 19 #include <log4cplus/config.h>
 20 #include <log4cplus/logger.h>
 21 #include <log4cplus/helpers/logloguser.h>
 22 #include <log4cplus/helpers/pointer.h>
 23 #include <log4cplus/helpers/threads.h>
 24 #include <map>
 25 #include <memory>
 26 #include <vector>
 27 
 28 
 29 namespace log4cplus {
 30     // Forward Declarations
 31     class HierarchyLocker;
 32 
 33     /**
 34      * This class is specialized in retrieving loggers by name and
 35      * also maintaining the logger hierarchy.
 36      *
 37      * <p><em>The casual user should not have to deal with this class
 38      * directly.</em>  However, if you are in an environment where
 39      * multiple applications run in the same process, then read on.
 40      *
 41      * <p>The structure of the logger hierarchy is maintained by the
 42      * {@link #getInstance} method. The hierarchy is such that children
 43      * link to their parent but parents do not have any pointers to their
 44      * children. Moreover, loggers can be instantiated in any order, in
 45      * particular descendant before ancestor.
 46      *
 47      * <p>In case a descendant is created before a particular ancestor,
 48      * then it creates a provision node for the ancestor and adds itself
 49      * to the provision node. Other descendants of the same ancestor add
 50      * themselves to the previously created provision node.
 51      */
 52     class LOG4CPLUS_EXPORT Hierarchy : protected log4cplus::helpers::LogLogUser {
 53     public:
 54         // DISABLE_OFF should be set to a value lower than all possible
 55         // priorities.
 56         static const LogLevel DISABLE_OFF;
 57         static const LogLevel DISABLE_OVERRIDE;
 58 
 59       // Ctors
 60         /**
 61          * Create a new Logger hierarchy.
 62          *
 63          * @param root The root of the new hierarchy.
 64          */
 65         Hierarchy();
 66 
 67       // Dtor
 68         virtual ~Hierarchy();
 69 
 70       // Methods
 71         /**
 72          * This call will clear all logger definitions from the internal
 73          * hashtable. Invoking this method will irrevocably mess up the
 74          * logger hierarchy.
 75          *                     
 76          * <p>You should <em>really</em> know what you are doing before
 77          * invoking this method.
 78          */
 79         virtual void clear();
 80 
 81         /**
 82          * Returns <code>true </code>if the named logger exists 
 83          * (in the default hierarchy).
 84          *                
 85          * @param name The name of the logger to search for.
 86          */
 87         virtual bool exists(const log4cplus::tstring& name);
 88 
 89         /**
 90          * Similar to {@link #disable(LogLevel)} except that the LogLevel
 91          * argument is given as a log4cplus::tstring.  
 92          */
 93         virtual void disable(const log4cplus::tstring& loglevelStr);
 94 
 95         /**
 96          * Disable all logging requests of LogLevel <em>equal to or
 97          * below</em> the ll parameter <code>p</code>, for
 98          * <em>all</em> loggers in this hierarchy. Logging requests of
 99          * higher LogLevel then <code>p</code> remain unaffected.
100          *
101          * <p>Nevertheless, if the {@link
102          * BasicConfigurator#DISABLE_OVERRIDE_KEY} system property is set to
103          * "true" or any value other than "false", then logging requests are
104          * evaluated as usual, i.e. according to the <a
105          * href="../../../../manual.html#selectionRule">Basic Selection Rule</a>.
106          *
107          * <p>The "disable" family of methods are there for speed. They
108          * allow printing methods such as debug, info, etc. to return
109          * immediately after an integer comparison without walking the
110          * logger hierarchy. In most modern computers an integer
111          * comparison is measured in nanoseconds where as a logger walk is
112          * measured in units of microseconds.
113          */
114         virtual void disable(LogLevel ll);
115 
116         /**
117          * Disable all logging requests regardless of logger and LogLevel.
118          * This method is equivalent to calling {@link #disable} with the
119          * argument FATAL_LOG_LEVEL, the highest possible LogLevel.
120          */
121         virtual void disableAll();
122 
123         /**
124          * Disable all Debug logging requests regardless of logger.
125          * This method is equivalent to calling {@link #disable} with the
126          * argument DEBUG_LOG_LEVEL.
127          */
128         virtual void disableDebug();
129 
130         /**
131          * Disable all Info logging requests regardless of logger.
132          * This method is equivalent to calling {@link #disable} with the
133          * argument INFO_LOG_LEVEL.
134          */
135         virtual void disableInfo();
136 
137         /**
138          * Undoes the effect of calling any of {@link #disable}, {@link
139          * #disableAll}, {@link #disableDebug} and {@link #disableInfo}
140          * methods. More precisely, invoking this method sets the Logger
141          * class internal variable called <code>disable</code> to its
142          * default "off" value.
143          */
144         virtual void enableAll();
145 
146         /**
147          * Return a new logger instance named as the first parameter using
148          * the default factory. 
149          *                
150          * <p>If a logger of that name already exists, then it will be
151          * returned.  Otherwise, a new logger will be instantiated and
152          * then linked with its existing ancestors as well as children.
153          *                                    
154          * @param name The name of the logger to retrieve.
155          */
156         virtual Logger getInstance(const log4cplus::tstring& name);
157 
158         /**
159          * Return a new logger instance named as the first parameter using
160          * <code>factory</code>.
161          *                
162          * <p>If a logger of that name already exists, then it will be
163          * returned.  Otherwise, a new logger will be instantiated by the
164          * <code>factory</code> parameter and linked with its existing
165          * ancestors as well as children.
166          *                                         
167          * @param name The name of the logger to retrieve.
168          * @param factory The factory that will make the new logger instance.
169          */
170         virtual Logger getInstance(const log4cplus::tstring& name, spi::LoggerFactory& factory);
171 
172         /**
173          * Returns all the currently defined loggers in this hierarchy.
174          *
175          * <p>The root logger is <em>not</em> included in the returned list. 
176          */
177         virtual LoggerList getCurrentLoggers();
178 
179         /** 
180          * Is the LogLevel specified by <code>level</code> enabled? 
181          */
182         virtual bool isDisabled(int level);
183 
184         /**
185          * Get the root of this hierarchy.
186          */
187         virtual Logger getRoot() const;
188 
189         /**
190          * Reset all values contained in this hierarchy instance to their
191          * default.  This removes all appenders from all loggers, sets
192          * the LogLevel of all non-root loggers to <code>NOT_SET_LOG_LEVEL</code>,
193          * sets their additivity flag to <code>true</code> and sets the LogLevel
194          * of the root logger to DEBUG_LOG_LEVEL.  Moreover, message disabling
195          * is set its default "off" value.
196          *
197          * <p>Existing loggers are not removed. They are just reset.
198          *
199          * <p>This method should be used sparingly and with care as it will
200          * block all logging until it is completed.</p>
201          */
202         virtual void resetConfiguration(); 
203 
204         /**
205          * Set the default LoggerFactory instance.
206          */
207         virtual void setLoggerFactory(std::auto_ptr<spi::LoggerFactory> factory);
208         
209         /**
210          * Returns the default LoggerFactory instance.
211          */
212         virtual spi::LoggerFactory* getLoggerFactory() { return defaultFactory.get(); }
213 
214         /**
215          * Shutting down a hierarchy will <em>safely</em> close and remove
216          * all appenders in all loggers including the root logger.
217          *                
218          * <p>Some appenders such as SocketAppender need to be closed before the
219          * application exits. Otherwise, pending logging events might be
220          * lost.
221          *
222          * <p>The <code>shutdown</code> method is careful to close nested
223          * appenders before closing regular appenders. This is allows
224          * configurations where a regular appender is attached to a logger
225          * and again to a nested appender.
226          */
227         virtual void shutdown();
228 
229     private:
230       // Types
231         typedef std::vector<Logger> ProvisionNode;
232         typedef std::map<log4cplus::tstring, ProvisionNode> ProvisionNodeMap;
233         typedef std::map<log4cplus::tstring, Logger> LoggerMap;
234 
235       // Methods
236         /**
237          * This is the implementation of the <code>getInstance()</code> method.
238          * NOTE: This method does not lock the <code>hashtable_mutex</code>.
239          */
240         virtual Logger getInstanceImpl(const log4cplus::tstring& name, 
241                                        spi::LoggerFactory& factory);
242         
243         /**
244          * This is the implementation of the <code>getCurrentLoggers()</code>.
245          * NOTE: This method does not lock the <code>hashtable_mutex</code>.
246          */
247         virtual void initializeLoggerList(LoggerList& list) const;
248         
249         /**
250          * This method loops through all the *potential* parents of
251          * logger'. There 3 possible cases:
252          *
253          * 1) No entry for the potential parent of 'logger' exists
254          *
255          *    We create a ProvisionNode for this potential parent and insert
256          *    'logger' in that provision node.
257          *
258          * 2) There is an entry of type Logger for the potential parent.
259          *
260          *    The entry is 'logger's nearest existing parent. We update logger's
261          *    parent field with this entry. We also break from the loop
262          *    because updating our parent's parent is our parent's
263          *    responsibility.
264          *
265          * 3) There entry is of type ProvisionNode for this potential parent.
266          *
267          *    We add 'logger' to the list of children for this potential parent.
268          */
269         void updateParents(Logger logger);
270 
271         /**
272          * We update the links for all the children that placed themselves
273          * in the provision node 'pn'. The second argument 'logger' is a
274          * reference for the newly created Logger, parent of all the
275          * children in 'pn'
276          *
277          * We loop on all the children 'c' in 'pn':
278          *
279          *    If the child 'c' has been already linked to a child of
280          *    'logger' then there is no need to update 'c'.
281          *
282          *   Otherwise, we set logger's parent field to c's parent and set
283          *   c's parent field to logger.
284          */
285         void updateChildren(ProvisionNode& pn, Logger logger);
286 
287     // Data
288        LOG4CPLUS_MUTEX_PTR_DECLARE hashtable_mutex;
289        std::auto_ptr<spi::LoggerFactory> defaultFactory;
290        ProvisionNodeMap provisionNodes;
291        LoggerMap loggerPtrs;
292        Logger root;
293 
294        int disableValue;
295 
296        bool emittedNoAppenderWarning;
297        bool emittedNoResourceBundleWarning;
298 
299      // Disallow copying of instances of this class
300        Hierarchy(const Hierarchy&);
301        Hierarchy& operator=(const Hierarchy&);
302 
303     // Friends
304        friend class log4cplus::spi::LoggerImpl;
305        friend class log4cplus::HierarchyLocker;
306     };
307 
308 } // end namespace log4cplus
309 
310 #endif // _LOG4CPLUS_HIERARCHY_HEADER_


syntax highlighted by Code2HTML, v. 0.9.1