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