1 | /*
|
---|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
|
---|
3 | * contributor license agreements. See the NOTICE file distributed with
|
---|
4 | * this work for additional information regarding copyright ownership.
|
---|
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
|
---|
6 | * (the "License"); you may not use this file except in compliance with
|
---|
7 | * the License. You may obtain a copy of the License at
|
---|
8 | *
|
---|
9 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
10 | *
|
---|
11 | * Unless required by applicable law or agreed to in writing, software
|
---|
12 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
14 | * See the License for the specific language governing permissions and
|
---|
15 | * limitations under the License.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #ifndef _LOG4CXX_HIERARCHY_H
|
---|
19 | #define _LOG4CXX_HIERARCHY_H
|
---|
20 |
|
---|
21 | #if defined(_MSC_VER)
|
---|
22 | #pragma warning (push)
|
---|
23 | #pragma warning ( disable: 4231 4251 4275 4786 )
|
---|
24 | #endif
|
---|
25 |
|
---|
26 | #include <log4cxx/spi/loggerrepository.h>
|
---|
27 | #include <log4cxx/spi/loggerfactory.h>
|
---|
28 | #include <vector>
|
---|
29 | #include <map>
|
---|
30 | #include <log4cxx/provisionnode.h>
|
---|
31 | #include <log4cxx/helpers/objectimpl.h>
|
---|
32 | #include <log4cxx/spi/hierarchyeventlistener.h>
|
---|
33 | #include <log4cxx/helpers/pool.h>
|
---|
34 |
|
---|
35 | namespace log4cxx
|
---|
36 | {
|
---|
37 | /**
|
---|
38 | This class is specialized in retrieving loggers by name and also
|
---|
39 | maintaining the logger hierarchy.
|
---|
40 |
|
---|
41 | <p><em>The casual user does not have to deal with this class
|
---|
42 | directly.</em>
|
---|
43 |
|
---|
44 | <p>The structure of the logger hierarchy is maintained by the
|
---|
45 | #getLogger method. The hierarchy is such that children link
|
---|
46 | to their parent but parents do not have any pointers to their
|
---|
47 | children. Moreover, loggers can be instantiated in any order, in
|
---|
48 | particular descendant before ancestor.
|
---|
49 |
|
---|
50 | <p>In case a descendant is created before a particular ancestor,
|
---|
51 | then it creates a provision node for the ancestor and adds itself
|
---|
52 | to the provision node. Other descendants of the same ancestor add
|
---|
53 | themselves to the previously created provision node.
|
---|
54 | */
|
---|
55 | class LOG4CXX_EXPORT Hierarchy :
|
---|
56 | public virtual spi::LoggerRepository,
|
---|
57 | public virtual helpers::ObjectImpl
|
---|
58 | {
|
---|
59 | private:
|
---|
60 | log4cxx::helpers::Pool pool;
|
---|
61 | log4cxx::helpers::Mutex mutex;
|
---|
62 | bool configured;
|
---|
63 |
|
---|
64 | spi::LoggerFactoryPtr defaultFactory;
|
---|
65 | spi::HierarchyEventListenerList listeners;
|
---|
66 |
|
---|
67 | typedef std::map<LogString, LoggerPtr> LoggerMap;
|
---|
68 | LoggerMap* loggers;
|
---|
69 |
|
---|
70 | typedef std::map<LogString, ProvisionNode> ProvisionNodeMap;
|
---|
71 | ProvisionNodeMap* provisionNodes;
|
---|
72 |
|
---|
73 | LoggerPtr root;
|
---|
74 |
|
---|
75 | int thresholdInt;
|
---|
76 | LevelPtr threshold;
|
---|
77 |
|
---|
78 | bool emittedNoAppenderWarning;
|
---|
79 | bool emittedNoResourceBundleWarning;
|
---|
80 |
|
---|
81 | public:
|
---|
82 | DECLARE_ABSTRACT_LOG4CXX_OBJECT(Hierarchy)
|
---|
83 | BEGIN_LOG4CXX_CAST_MAP()
|
---|
84 | LOG4CXX_CAST_ENTRY(spi::LoggerRepository)
|
---|
85 | END_LOG4CXX_CAST_MAP()
|
---|
86 |
|
---|
87 | /**
|
---|
88 | Create a new logger hierarchy.
|
---|
89 | */
|
---|
90 | Hierarchy();
|
---|
91 |
|
---|
92 | ~Hierarchy();
|
---|
93 |
|
---|
94 | void addRef() const;
|
---|
95 | void releaseRef() const;
|
---|
96 |
|
---|
97 | void addHierarchyEventListener(const spi::HierarchyEventListenerPtr& listener);
|
---|
98 |
|
---|
99 | /**
|
---|
100 | This call will clear all logger definitions from the internal
|
---|
101 | hashtable. Invoking this method will irrevocably mess up the
|
---|
102 | logger hierarchy.
|
---|
103 |
|
---|
104 | <p>You should <em>really</em> know what you are doing before
|
---|
105 | invoking this method.
|
---|
106 | */
|
---|
107 | void clear();
|
---|
108 |
|
---|
109 | void emitNoAppenderWarning(const LoggerPtr& logger);
|
---|
110 |
|
---|
111 | /**
|
---|
112 | Check if the named logger exists in the hierarchy. If so return
|
---|
113 | its reference, otherwise returns <code>null</code>.
|
---|
114 |
|
---|
115 | @param name The name of the logger to search for.
|
---|
116 |
|
---|
117 | */
|
---|
118 | LoggerPtr exists(const LogString& name);
|
---|
119 |
|
---|
120 | /**
|
---|
121 | The string form of {@link #setThreshold(const LevelPtr&) setThreshold}.
|
---|
122 | */
|
---|
123 | void setThreshold(const LogString& levelStr);
|
---|
124 |
|
---|
125 | /**
|
---|
126 | Enable logging for logging requests with level <code>l</code> or
|
---|
127 | higher. By default all levels are enabled.
|
---|
128 |
|
---|
129 | @param l The minimum level for which logging requests are sent to
|
---|
130 | their appenders. */
|
---|
131 | void setThreshold(const LevelPtr& l);
|
---|
132 |
|
---|
133 | void fireAddAppenderEvent(const LoggerPtr& logger, const AppenderPtr& appender);
|
---|
134 |
|
---|
135 | void fireRemoveAppenderEvent(const LoggerPtr& logger,
|
---|
136 | const AppenderPtr& appender);
|
---|
137 |
|
---|
138 | /**
|
---|
139 | Returns a Level representation of the <code>enable</code>
|
---|
140 | state.
|
---|
141 | */
|
---|
142 | const LevelPtr& getThreshold() const;
|
---|
143 |
|
---|
144 | /**
|
---|
145 | Return a new logger instance named as the first parameter using
|
---|
146 | the default factory.
|
---|
147 |
|
---|
148 | <p>If a logger of that name already exists, then it will be
|
---|
149 | returned. Otherwise, a new logger will be instantiated and
|
---|
150 | then linked with its existing ancestors as well as children.
|
---|
151 |
|
---|
152 | @param name The name of the logger to retrieve.
|
---|
153 |
|
---|
154 | */
|
---|
155 | LoggerPtr getLogger(const LogString& name);
|
---|
156 |
|
---|
157 | /**
|
---|
158 | Return a new logger instance named as the first parameter using
|
---|
159 | <code>factory</code>.
|
---|
160 |
|
---|
161 | <p>If a logger of that name already exists, then it will be
|
---|
162 | returned. Otherwise, a new logger will be instantiated by the
|
---|
163 | <code>factory</code> parameter and linked with its existing
|
---|
164 | ancestors as well as children.
|
---|
165 |
|
---|
166 | @param name The name of the logger to retrieve.
|
---|
167 | @param factory The factory that will make the new logger instance.
|
---|
168 |
|
---|
169 | */
|
---|
170 | LoggerPtr getLogger(const LogString& name,
|
---|
171 | const spi::LoggerFactoryPtr& factory);
|
---|
172 |
|
---|
173 | /**
|
---|
174 | Returns all the currently defined loggers in this hierarchy as
|
---|
175 | a LoggerList.
|
---|
176 |
|
---|
177 | <p>The root logger is <em>not</em> included in the returned
|
---|
178 | LoggerList. */
|
---|
179 | LoggerList getCurrentLoggers() const;
|
---|
180 |
|
---|
181 | /**
|
---|
182 | Get the root of this hierarchy.
|
---|
183 | */
|
---|
184 | LoggerPtr getRootLogger() const;
|
---|
185 |
|
---|
186 | /**
|
---|
187 | This method will return <code>true</code> if this repository is
|
---|
188 | disabled for <code>level</code> object passed as parameter and
|
---|
189 | <code>false</code> otherwise. See also the
|
---|
190 | {@link #setThreshold(const LevelPtr&) setThreshold} method. */
|
---|
191 | bool isDisabled(int level) const;
|
---|
192 |
|
---|
193 | /**
|
---|
194 | Reset all values contained in this hierarchy instance to their
|
---|
195 | default. This removes all appenders from all categories, sets
|
---|
196 | the level of all non-root categories to <code>null</code>,
|
---|
197 | sets their additivity flag to <code>true</code> and sets the level
|
---|
198 | of the root logger to DEBUG. Moreover,
|
---|
199 | message disabling is set its default "off" value.
|
---|
200 |
|
---|
201 | <p>Existing categories are not removed. They are just reset.
|
---|
202 |
|
---|
203 | <p>This method should be used sparingly and with care as it will
|
---|
204 | block all logging until it is completed.</p>
|
---|
205 | */
|
---|
206 | void resetConfiguration();
|
---|
207 |
|
---|
208 | /**
|
---|
209 | Used by subclasses to add a renderer to the hierarchy passed as parameter.
|
---|
210 | */
|
---|
211 | /**
|
---|
212 | Shutting down a hierarchy will <em>safely</em> close and remove
|
---|
213 | all appenders in all categories including the root logger.
|
---|
214 |
|
---|
215 | <p>Some appenders such as {@link net::SocketAppender SocketAppender}
|
---|
216 | and AsyncAppender need to be closed before the
|
---|
217 | application exists. Otherwise, pending logging events might be
|
---|
218 | lost.
|
---|
219 |
|
---|
220 | <p>The <code>shutdown</code> method is careful to close nested
|
---|
221 | appenders before closing regular appenders. This is allows
|
---|
222 | configurations where a regular appender is attached to a logger
|
---|
223 | and again to a nested appender.
|
---|
224 | */
|
---|
225 | void shutdown();
|
---|
226 |
|
---|
227 |
|
---|
228 | virtual bool isConfigured();
|
---|
229 | virtual void setConfigured(bool configured);
|
---|
230 |
|
---|
231 |
|
---|
232 | private:
|
---|
233 |
|
---|
234 | /**
|
---|
235 | This method loops through all the *potential* parents of
|
---|
236 | 'cat'. There 3 possible cases:
|
---|
237 |
|
---|
238 | 1) No entry for the potential parent of 'cat' exists
|
---|
239 |
|
---|
240 | We create a ProvisionNode for this potential parent and insert
|
---|
241 | 'cat' in that provision node.
|
---|
242 |
|
---|
243 | 2) There entry is of type Logger for the potential parent.
|
---|
244 |
|
---|
245 | The entry is 'cat's nearest existing parent. We update cat's
|
---|
246 | parent field with this entry. We also break from the loop
|
---|
247 | because updating our parent's parent is our parent's
|
---|
248 | responsibility.
|
---|
249 |
|
---|
250 | 3) There entry is of type ProvisionNode for this potential parent.
|
---|
251 |
|
---|
252 | We add 'cat' to the list of children for this potential parent.
|
---|
253 | */
|
---|
254 | void updateParents(LoggerPtr logger);
|
---|
255 |
|
---|
256 | /**
|
---|
257 | We update the links for all the children that placed themselves
|
---|
258 | in the provision node 'pn'. The second argument 'cat' is a
|
---|
259 | reference for the newly created Logger, parent of all the
|
---|
260 | children in 'pn'
|
---|
261 |
|
---|
262 | We loop on all the children 'c' in 'pn':
|
---|
263 |
|
---|
264 | If the child 'c' has been already linked to a child of
|
---|
265 | 'cat' then there is no need to update 'c'.
|
---|
266 |
|
---|
267 | Otherwise, we set cat's parent field to c's parent and set
|
---|
268 | c's parent field to cat.
|
---|
269 | */
|
---|
270 | Hierarchy(const Hierarchy&);
|
---|
271 | Hierarchy& operator=(const Hierarchy&);
|
---|
272 |
|
---|
273 | void updateChildren(ProvisionNode& pn, LoggerPtr logger);
|
---|
274 | };
|
---|
275 |
|
---|
276 | } //namespace log4cxx
|
---|
277 |
|
---|
278 |
|
---|
279 | #if defined(_MSC_VER)
|
---|
280 | #pragma warning (pop)
|
---|
281 | #endif
|
---|
282 |
|
---|
283 | #endif //_LOG4CXX_HIERARCHY_H
|
---|