1 | <?php
|
---|
2 | /**
|
---|
3 | * log4php is a PHP port of the log4j java logging package.
|
---|
4 | *
|
---|
5 | * <p>This framework is based on log4j (see {@link http://jakarta.apache.org/log4j log4j} for details).</p>
|
---|
6 | * <p>Design, strategies and part of the methods documentation are developed by log4j team
|
---|
7 | * (Ceki Gülcü as log4j project founder and
|
---|
8 | * {@link http://jakarta.apache.org/log4j/docs/contributors.html contributors}).</p>
|
---|
9 | *
|
---|
10 | * <p>PHP port, extensions and modifications by VxR. All rights reserved.<br>
|
---|
11 | * For more information, please see {@link http://www.vxr.it/log4php/}.</p>
|
---|
12 | *
|
---|
13 | * <p>This software is published under the terms of the LGPL License
|
---|
14 | * a copy of which has been included with this distribution in the LICENSE file.</p>
|
---|
15 | *
|
---|
16 | * @package log4php
|
---|
17 | */
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * @ignore
|
---|
21 | */
|
---|
22 | if (!defined('LOG4PHP_DIR')) define('LOG4PHP_DIR', dirname(__FILE__));
|
---|
23 |
|
---|
24 | /**
|
---|
25 | */
|
---|
26 | require_once(LOG4PHP_DIR . '/LoggerLog.php');
|
---|
27 | require_once(LOG4PHP_DIR . '/LoggerLevel.php');
|
---|
28 | require_once(LOG4PHP_DIR . '/Logger.php');
|
---|
29 | require_once(LOG4PHP_DIR . '/LoggerRoot.php');
|
---|
30 | require_once(LOG4PHP_DIR . '/or/LoggerRendererMap.php');
|
---|
31 | require_once(LOG4PHP_DIR . '/LoggerDefaultCategoryFactory.php');
|
---|
32 |
|
---|
33 | /**
|
---|
34 | * This class is specialized in retrieving loggers by name and also maintaining
|
---|
35 | * the logger hierarchy.
|
---|
36 | *
|
---|
37 | * <p>The casual user does not have to deal with this class directly.</p>
|
---|
38 | *
|
---|
39 | * <p>The structure of the logger hierarchy is maintained by the
|
---|
40 | * getLogger method. The hierarchy is such that children link
|
---|
41 | * to their parent but parents do not have any pointers to their
|
---|
42 | * children. Moreover, loggers can be instantiated in any order, in
|
---|
43 | * particular descendant before ancestor.</p>
|
---|
44 | *
|
---|
45 | * <p>In case a descendant is created before a particular ancestor,
|
---|
46 | * then it creates a provision node for the ancestor and adds itself
|
---|
47 | * to the provision node. Other descendants of the same ancestor add
|
---|
48 | * themselves to the previously created provision node.</p>
|
---|
49 | *
|
---|
50 | * @author VxR <vxr@vxr.it>
|
---|
51 | * @version $Revision: 1.19 $
|
---|
52 | * @package log4php
|
---|
53 | */
|
---|
54 | class LoggerHierarchy {
|
---|
55 |
|
---|
56 | /**
|
---|
57 | * @var object currently unused
|
---|
58 | */
|
---|
59 | var $defaultFactory;
|
---|
60 |
|
---|
61 | /**
|
---|
62 | * @var boolean activate internal logging
|
---|
63 | * @see LoggerLog
|
---|
64 | */
|
---|
65 | var $debug = false;
|
---|
66 |
|
---|
67 | /**
|
---|
68 | * @var array hierarchy tree. saves here all loggers
|
---|
69 | */
|
---|
70 | var $ht = array();
|
---|
71 |
|
---|
72 | /**
|
---|
73 | * @var LoggerRoot
|
---|
74 | */
|
---|
75 | var $root = null;
|
---|
76 |
|
---|
77 | /**
|
---|
78 | * @var LoggerRendererMap
|
---|
79 | */
|
---|
80 | var $rendererMap;
|
---|
81 |
|
---|
82 | /**
|
---|
83 | * @var LoggerLevel main level threshold
|
---|
84 | */
|
---|
85 | var $threshold;
|
---|
86 |
|
---|
87 | /**
|
---|
88 | * @var boolean currently unused
|
---|
89 | */
|
---|
90 | var $emittedNoAppenderWarning = false;
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * @var boolean currently unused
|
---|
94 | */
|
---|
95 | var $emittedNoResourceBundleWarning = false;
|
---|
96 |
|
---|
97 |
|
---|
98 | /* --------------------------------------------------------------------------*/
|
---|
99 | /* --------------------------------------------------------------------------*/
|
---|
100 | /* --------------------------------------------------------------------------*/
|
---|
101 |
|
---|
102 | function &singleton()
|
---|
103 | {
|
---|
104 | static $instance;
|
---|
105 |
|
---|
106 | if (!isset($instance))
|
---|
107 | $instance = new LoggerHierarchy(new LoggerRoot());
|
---|
108 | return $instance;
|
---|
109 | }
|
---|
110 |
|
---|
111 | /**
|
---|
112 | * Create a new logger hierarchy.
|
---|
113 | * @param object $root the root logger
|
---|
114 | */
|
---|
115 | function LoggerHierarchy($root)
|
---|
116 | {
|
---|
117 | $this->root =& $root;
|
---|
118 | // Enable all level levels by default.
|
---|
119 | $this->setThreshold(LoggerLevel::getLevelAll());
|
---|
120 | $this->root->setHierarchy($this);
|
---|
121 | $this->rendererMap = new LoggerRendererMap();
|
---|
122 | $this->defaultFactory = new LoggerDefaultCategoryFactory();
|
---|
123 | }
|
---|
124 |
|
---|
125 | /**
|
---|
126 | * Add a HierarchyEventListener event to the repository.
|
---|
127 | * Not Yet Impl.
|
---|
128 | */
|
---|
129 | function addHierarchyEventListener($listener)
|
---|
130 | {
|
---|
131 | return;
|
---|
132 | }
|
---|
133 |
|
---|
134 | /**
|
---|
135 | * Add an object renderer for a specific class.
|
---|
136 | * Not Yet Impl.
|
---|
137 | */
|
---|
138 | function addRenderer($classToRender, $or)
|
---|
139 | {
|
---|
140 | $this->rendererMap->put($classToRender, $or);
|
---|
141 | }
|
---|
142 |
|
---|
143 | /**
|
---|
144 | * This call will clear all logger definitions from the internal hashtable.
|
---|
145 | */
|
---|
146 | function clear()
|
---|
147 | {
|
---|
148 | $this->ht = array();
|
---|
149 | }
|
---|
150 |
|
---|
151 | function emitNoAppenderWarning($cat)
|
---|
152 | {
|
---|
153 | return;
|
---|
154 | }
|
---|
155 |
|
---|
156 | /**
|
---|
157 | * Check if the named logger exists in the hierarchy.
|
---|
158 | * @param string $name
|
---|
159 | * @return boolean
|
---|
160 | */
|
---|
161 | function exists($name)
|
---|
162 | {
|
---|
163 | return in_array($name, array_keys($this->ht));
|
---|
164 | }
|
---|
165 |
|
---|
166 | function fireAddAppenderEvent($logger, $appender)
|
---|
167 | {
|
---|
168 | return;
|
---|
169 | }
|
---|
170 |
|
---|
171 | /**
|
---|
172 | * @deprecated Please use {@link getCurrentLoggers()} instead.
|
---|
173 | */
|
---|
174 | function &getCurrentCategories()
|
---|
175 | {
|
---|
176 | return $this->getCurrentLoggers();
|
---|
177 | }
|
---|
178 |
|
---|
179 | /**
|
---|
180 | * Returns all the currently defined categories in this hierarchy as an array.
|
---|
181 | * @return array
|
---|
182 | */
|
---|
183 | function &getCurrentLoggers()
|
---|
184 | {
|
---|
185 | $loggers = array();
|
---|
186 | $loggerNames = array_keys($this->ht);
|
---|
187 | $enumLoggers = sizeof($loggerNames);
|
---|
188 | for ($i = 0; $i < $enumLoggers; $i++) {
|
---|
189 | $loggerName = $loggerNames[$i];
|
---|
190 | $loggers[] =& $this->ht[$loggerName];
|
---|
191 | }
|
---|
192 | return $loggers;
|
---|
193 | }
|
---|
194 |
|
---|
195 | /**
|
---|
196 | * Return a new logger instance named as the first parameter using the default factory.
|
---|
197 | *
|
---|
198 | * @param string $name logger name
|
---|
199 | * @param LoggerFactory $factory a {@link LoggerFactory} instance or null
|
---|
200 | * @return Logger
|
---|
201 | */
|
---|
202 | function &getLogger($name, $factory = null)
|
---|
203 | {
|
---|
204 | if ($factory === null) {
|
---|
205 | return $this->getLoggerByFactory($name, $this->defaultFactory);
|
---|
206 | } else {
|
---|
207 | return $this->getLoggerByFactory($name, $factory);
|
---|
208 | }
|
---|
209 | }
|
---|
210 |
|
---|
211 | /**
|
---|
212 | * Return a new logger instance named as the first parameter using the default factory.
|
---|
213 | *
|
---|
214 | * @param string $name logger name
|
---|
215 | * @return Logger
|
---|
216 | * @todo merge with {@link getLogger()}
|
---|
217 | */
|
---|
218 | function &getLoggerByFactory($name, $factory)
|
---|
219 | {
|
---|
220 | if (!isset($this->ht[$name])) {
|
---|
221 | LoggerLog::debug("LoggerHierarchy::getLoggerByFactory():name=[$name]:factory=[".get_class($factory)."] creating a new logger...");
|
---|
222 | $this->ht[$name] = $factory->makeNewLoggerInstance($name);
|
---|
223 | $this->ht[$name]->setHierarchy($this);
|
---|
224 | $nodes = explode('.', $name);
|
---|
225 | $firstNode = array_shift($nodes);
|
---|
226 | if ( $firstNode != $name and isset($this->ht[$firstNode])) {
|
---|
227 | LoggerLog::debug("LoggerHierarchy::getLogger($name) parent is now [$firstNode]");
|
---|
228 | $this->ht[$name]->parent =& $this->ht[$firstNode];
|
---|
229 | } else {
|
---|
230 | LoggerLog::debug("LoggerHierarchy::getLogger($name) parent is now [root]");
|
---|
231 | $this->ht[$name]->parent =& $this->root;
|
---|
232 | }
|
---|
233 | if (sizeof($nodes) > 0) {
|
---|
234 | // find parent node
|
---|
235 | foreach ($nodes as $node) {
|
---|
236 | $parentNode = "$firstNode.$node";
|
---|
237 | if (isset($this->ht[$parentNode]) and $parentNode != $name) {
|
---|
238 | LoggerLog::debug("LoggerHierarchy::getLogger($name) parent is now [$parentNode]");
|
---|
239 | $this->ht[$name]->parent =& $this->ht[$parentNode];
|
---|
240 | }
|
---|
241 | $firstNode .= ".$node";
|
---|
242 | }
|
---|
243 | }
|
---|
244 | // update children
|
---|
245 | /*
|
---|
246 | $children = array();
|
---|
247 | foreach (array_keys($this->ht) as $nodeName) {
|
---|
248 | if ($nodeName != $name and substr($nodeName, 0, strlen($name)) == $name) {
|
---|
249 | $children[] = $nodeName;
|
---|
250 | }
|
---|
251 | }
|
---|
252 | */
|
---|
253 | }
|
---|
254 | return $this->ht[$name];
|
---|
255 | }
|
---|
256 |
|
---|
257 | /**
|
---|
258 | * @return LoggerRendererMap Get the renderer map for this hierarchy.
|
---|
259 | */
|
---|
260 | function &getRendererMap()
|
---|
261 | {
|
---|
262 | return $this->rendererMap;
|
---|
263 | }
|
---|
264 |
|
---|
265 | /**
|
---|
266 | * @return LoggerRoot Get the root of this hierarchy.
|
---|
267 | */
|
---|
268 | function &getRootLogger()
|
---|
269 | {
|
---|
270 | if (!isset($this->root) or $this->root == null)
|
---|
271 | $this->root = new LoggerRoot();
|
---|
272 | return $this->root;
|
---|
273 | }
|
---|
274 |
|
---|
275 | /**
|
---|
276 | * @return LoggerLevel Returns the threshold Level.
|
---|
277 | */
|
---|
278 | function getThreshold()
|
---|
279 | {
|
---|
280 | return $this->threshold;
|
---|
281 | }
|
---|
282 |
|
---|
283 | /**
|
---|
284 | * This method will return true if this repository is disabled
|
---|
285 | * for level object passed as parameter and false otherwise.
|
---|
286 | * @return boolean
|
---|
287 | */
|
---|
288 | function isDisabled($level)
|
---|
289 | {
|
---|
290 | return ($this->threshold->level > $level->level);
|
---|
291 | }
|
---|
292 |
|
---|
293 | /**
|
---|
294 | * @deprecated Deprecated with no replacement.
|
---|
295 | */
|
---|
296 | function overrideAsNeeded($override)
|
---|
297 | {
|
---|
298 | return;
|
---|
299 | }
|
---|
300 |
|
---|
301 | /**
|
---|
302 | * Reset all values contained in this hierarchy instance to their
|
---|
303 | * default.
|
---|
304 | *
|
---|
305 | * This removes all appenders from all categories, sets
|
---|
306 | * the level of all non-root categories to <i>null</i>,
|
---|
307 | * sets their additivity flag to <i>true</i> and sets the level
|
---|
308 | * of the root logger to {@link LOGGER_LEVEL_DEBUG}. Moreover,
|
---|
309 | * message disabling is set its default "off" value.
|
---|
310 | *
|
---|
311 | * <p>Existing categories are not removed. They are just reset.
|
---|
312 | *
|
---|
313 | * <p>This method should be used sparingly and with care as it will
|
---|
314 | * block all logging until it is completed.</p>
|
---|
315 | */
|
---|
316 | function resetConfiguration()
|
---|
317 | {
|
---|
318 | $root =& $this->getRootLogger();
|
---|
319 |
|
---|
320 | $root->setLevel(LoggerLevel::getLevelDebug());
|
---|
321 | $this->setThreshold(LoggerLevel::getLevelAll());
|
---|
322 | $this->shutDown();
|
---|
323 | $loggers =& $this->getCurrentLoggers();
|
---|
324 | $enumLoggers = sizeof($loggers);
|
---|
325 | for ($i = 0; $i < $enumLoggers; $i++) {
|
---|
326 | $loggers[$i]->setLevel(null);
|
---|
327 | $loggers[$i]->setAdditivity(true);
|
---|
328 | $loggers[$i]->setResourceBundle(null);
|
---|
329 | }
|
---|
330 | $this->rendererMap->clear();
|
---|
331 | }
|
---|
332 |
|
---|
333 | /**
|
---|
334 | * @deprecated Deprecated with no replacement.
|
---|
335 | */
|
---|
336 | function setDisableOverride($override)
|
---|
337 | {
|
---|
338 | return;
|
---|
339 | }
|
---|
340 |
|
---|
341 | /**
|
---|
342 | * Used by subclasses to add a renderer to the hierarchy passed as parameter.
|
---|
343 | * @param string $renderedClass a LoggerRenderer class name
|
---|
344 | * @param LoggerRenderer $renderer
|
---|
345 | *
|
---|
346 | */
|
---|
347 | function setRenderer($renderedClass, $renderer)
|
---|
348 | {
|
---|
349 | $this->rendererMap->put($renderedClass, $renderer);
|
---|
350 | }
|
---|
351 |
|
---|
352 | /**
|
---|
353 | * set a new threshold level
|
---|
354 | *
|
---|
355 | * @param LoggerLevel $l
|
---|
356 | */
|
---|
357 | function setThreshold($l)
|
---|
358 | {
|
---|
359 | if ($l !== null)
|
---|
360 | $this->threshold = $l;
|
---|
361 | }
|
---|
362 |
|
---|
363 | /**
|
---|
364 | * Shutting down a hierarchy will <i>safely</i> close and remove
|
---|
365 | * all appenders in all categories including the root logger.
|
---|
366 | *
|
---|
367 | * <p>Some appenders such as {@link LoggerSocketAppender}
|
---|
368 | * need to be closed before the
|
---|
369 | * application exists. Otherwise, pending logging events might be
|
---|
370 | * lost.
|
---|
371 | *
|
---|
372 | * <p>The shutdown method is careful to close nested
|
---|
373 | * appenders before closing regular appenders. This is allows
|
---|
374 | * configurations where a regular appender is attached to a logger
|
---|
375 | * and again to a nested appender.
|
---|
376 | */
|
---|
377 | function shutdown()
|
---|
378 | {
|
---|
379 | $this->root->removeAllAppenders();
|
---|
380 | $cats =& $this->getCurrentLoggers();
|
---|
381 | $enumCats = sizeof($cats);
|
---|
382 | if ($enumCats > 0) {
|
---|
383 | for ($i = 0; $i < $enumCats; $i++) {
|
---|
384 | $cats[$i]->removeAllAppenders();
|
---|
385 | }
|
---|
386 | }
|
---|
387 | }
|
---|
388 | }
|
---|
389 | ?> |
---|