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 | require_once(LOG4PHP_DIR . '/spi/LoggerConfigurator.php');
|
---|
25 | require_once(LOG4PHP_DIR . '/config/LoggerPropertySetter.php');
|
---|
26 | require_once(LOG4PHP_DIR . '/LoggerLevel.php');
|
---|
27 | require_once(LOG4PHP_DIR . '/helpers/LoggerOptionConverter.php');
|
---|
28 | require_once(LOG4PHP_DIR . '/LoggerLayout.php');
|
---|
29 | require_once(LOG4PHP_DIR . '/LoggerAppender.php');
|
---|
30 | require_once(LOG4PHP_DIR . '/spi/LoggerFilter.php');
|
---|
31 | require_once(LOG4PHP_DIR . '/or/LoggerObjectRenderer.php');
|
---|
32 | require_once(LOG4PHP_DIR . '/LoggerManager.php');
|
---|
33 |
|
---|
34 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_CATEGORY_PREFIX', "log4php.category.");
|
---|
35 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_PREFIX', "log4php.logger.");
|
---|
36 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_FACTORY_PREFIX', "log4php.factory");
|
---|
37 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ADDITIVITY_PREFIX', "log4php.additivity.");
|
---|
38 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ROOT_CATEGORY_PREFIX', "log4php.rootCategory");
|
---|
39 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ROOT_LOGGER_PREFIX', "log4php.rootLogger");
|
---|
40 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_APPENDER_PREFIX', "log4php.appender.");
|
---|
41 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_RENDERER_PREFIX', "log4php.renderer.");
|
---|
42 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_THRESHOLD_PREFIX', "log4php.threshold");
|
---|
43 |
|
---|
44 | /**
|
---|
45 | * Key for specifying the {@link LoggerFactory}.
|
---|
46 | */
|
---|
47 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_FACTORY_KEY', "log4php.loggerFactory");
|
---|
48 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_DEBUG_KEY', "log4php.debug");
|
---|
49 | define('LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_INTERNAL_ROOT_NAME', "root");
|
---|
50 |
|
---|
51 |
|
---|
52 |
|
---|
53 | /**
|
---|
54 | * Allows the configuration of log4php from an external file.
|
---|
55 | *
|
---|
56 | * See {@link doConfigure()} for the expected format.
|
---|
57 | *
|
---|
58 | * <p>It is sometimes useful to see how log4php is reading configuration
|
---|
59 | * files. You can enable log4php internal logging by defining the
|
---|
60 | * <b>log4php.debug</b> variable.</p>
|
---|
61 | *
|
---|
62 | * <p>The <i>LoggerPropertyConfigurator</i> does not handle the
|
---|
63 | * advanced configuration features supported by the {@link LoggerDOMConfigurator}
|
---|
64 | * such as support for {@link LoggerFilter},
|
---|
65 | custom {@link LoggerErrorHandlers}, nested appenders such as the
|
---|
66 | {@link Logger AsyncAppender},
|
---|
67 | * etc.
|
---|
68 | *
|
---|
69 | * <p>All option <i>values</i> admit variable substitution. The
|
---|
70 | * syntax of variable substitution is similar to that of Unix
|
---|
71 | * shells. The string between an opening <b>"${"</b> and
|
---|
72 | * closing <b>"}"</b> is interpreted as a key. The value of
|
---|
73 | * the substituted variable can be defined as a system property or in
|
---|
74 | * the configuration file itself. The value of the key is first
|
---|
75 | * searched in the defined constants, in the enviroments variables
|
---|
76 | * and if not found there, it is
|
---|
77 | * then searched in the configuration file being parsed. The
|
---|
78 | * corresponding value replaces the ${variableName} sequence.</p>
|
---|
79 | * <p>For example, if <b>$_ENV['home']</b> env var is set to
|
---|
80 | * <b>/home/xyz</b>, then every occurrence of the sequence
|
---|
81 | * <b>${home}</b> will be interpreted as
|
---|
82 | * <b>/home/xyz</b>. See {@link LoggerOptionConverter::getSystemProperty()}
|
---|
83 | * for details.</p>
|
---|
84 | *
|
---|
85 | * @author VxR <vxr@vxr.it>
|
---|
86 | * @version $Revision: 1.5 $
|
---|
87 | * @package log4php
|
---|
88 | * @since 0.5
|
---|
89 | */
|
---|
90 | class LoggerPropertyConfigurator extends LoggerConfigurator {
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * @var LoggerFactory
|
---|
94 | */
|
---|
95 | var $loggerFactory = null;
|
---|
96 |
|
---|
97 | /**
|
---|
98 | * Constructor
|
---|
99 | */
|
---|
100 | function LoggerPropertyConfigurator()
|
---|
101 | {
|
---|
102 | $this->loggerFactory = new LoggerDefaultCategoryFactory();
|
---|
103 | }
|
---|
104 |
|
---|
105 | /**
|
---|
106 | * Configure the default repository using the resource pointed by <b>url</b>.
|
---|
107 | * <b>Url</b> is any valid resurce as defined in {@link PHP_MANUAL#file} function.
|
---|
108 | * Note that the resource will be search with <i>use_include_path</i> parameter
|
---|
109 | * set to "1".
|
---|
110 | *
|
---|
111 | * @param string $url
|
---|
112 | * @return boolean configuration result
|
---|
113 | * @static
|
---|
114 | */
|
---|
115 | function configure($url = '')
|
---|
116 | {
|
---|
117 | $configurator = new LoggerPropertyConfigurator();
|
---|
118 | $repository =& LoggerManager::getLoggerRepository();
|
---|
119 | return $configurator->doConfigure($url, $repository);
|
---|
120 | }
|
---|
121 |
|
---|
122 | /**
|
---|
123 | * Read configuration from a file.
|
---|
124 | *
|
---|
125 | * <p>The function {@link PHP_MANUAL#parse_ini_file} is used to read the
|
---|
126 | * file.</p>
|
---|
127 | *
|
---|
128 | * <b>The existing configuration is not cleared nor reset.</b>
|
---|
129 | * If you require a different behavior, then call
|
---|
130 | * {@link LoggerManager::resetConfiguration()}
|
---|
131 | * method before calling {@link doConfigure()}.
|
---|
132 | *
|
---|
133 | * <p>The configuration file consists of statements in the format
|
---|
134 | * <b>key=value</b>. The syntax of different configuration
|
---|
135 | * elements are discussed below.
|
---|
136 | *
|
---|
137 | * <p><b>Repository-wide threshold</b></p>
|
---|
138 | *
|
---|
139 | * <p>The repository-wide threshold filters logging requests by level
|
---|
140 | * regardless of logger. The syntax is:
|
---|
141 | *
|
---|
142 | * <pre>
|
---|
143 | * log4php.threshold=[level]
|
---|
144 | * </pre>
|
---|
145 | *
|
---|
146 | * <p>The level value can consist of the string values OFF, FATAL,
|
---|
147 | * ERROR, WARN, INFO, DEBUG, ALL or a <i>custom level</i> value. A
|
---|
148 | * custom level value can be specified in the form
|
---|
149 | * <samp>level#classname</samp>. By default the repository-wide threshold is set
|
---|
150 | * to the lowest possible value, namely the level <b>ALL</b>.
|
---|
151 | * </p>
|
---|
152 | *
|
---|
153 | *
|
---|
154 | * <p><b>Appender configuration</b></p>
|
---|
155 | *
|
---|
156 | * <p>Appender configuration syntax is:</p>
|
---|
157 | * <pre>
|
---|
158 | * ; For appender named <i>appenderName</i>, set its class.
|
---|
159 | * ; Note: The appender name can contain dots.
|
---|
160 | * log4php.appender.appenderName=name_of_appender_class
|
---|
161 | *
|
---|
162 | * ; Set appender specific options.
|
---|
163 | *
|
---|
164 | * log4php.appender.appenderName.option1=value1
|
---|
165 | * log4php.appender.appenderName.optionN=valueN
|
---|
166 | * </pre>
|
---|
167 | *
|
---|
168 | * For each named appender you can configure its {@link LoggerLayout}. The
|
---|
169 | * syntax for configuring an appender's layout is:
|
---|
170 | * <pre>
|
---|
171 | * log4php.appender.appenderName.layout=name_of_layout_class
|
---|
172 | * log4php.appender.appenderName.layout.option1=value1
|
---|
173 | * ....
|
---|
174 | * log4php.appender.appenderName.layout.optionN=valueN
|
---|
175 | * </pre>
|
---|
176 | *
|
---|
177 | * <p><b>Configuring loggers</b></p>
|
---|
178 | *
|
---|
179 | * <p>The syntax for configuring the root logger is:
|
---|
180 | * <pre>
|
---|
181 | * log4php.rootLogger=[level], appenderName, appenderName, ...
|
---|
182 | * </pre>
|
---|
183 | *
|
---|
184 | * <p>This syntax means that an optional <i>level</i> can be
|
---|
185 | * supplied followed by appender names separated by commas.
|
---|
186 | *
|
---|
187 | * <p>The level value can consist of the string values OFF, FATAL,
|
---|
188 | * ERROR, WARN, INFO, DEBUG, ALL or a <i>custom level</i> value. A
|
---|
189 | * custom level value can be specified in the form</p>
|
---|
190 | *
|
---|
191 | * <pre>level#classname</pre>
|
---|
192 | *
|
---|
193 | * <p>If a level value is specified, then the root level is set
|
---|
194 | * to the corresponding level. If no level value is specified,
|
---|
195 | * then the root level remains untouched.
|
---|
196 | *
|
---|
197 | * <p>The root logger can be assigned multiple appenders.
|
---|
198 | *
|
---|
199 | * <p>Each <i>appenderName</i> (separated by commas) will be added to
|
---|
200 | * the root logger. The named appender is defined using the
|
---|
201 | * appender syntax defined above.
|
---|
202 | *
|
---|
203 | * <p>For non-root categories the syntax is almost the same:
|
---|
204 | * <pre>
|
---|
205 | * log4php.logger.logger_name=[level|INHERITED|NULL], appenderName, appenderName, ...
|
---|
206 | * </pre>
|
---|
207 | *
|
---|
208 | * <p>The meaning of the optional level value is discussed above
|
---|
209 | * in relation to the root logger. In addition however, the value
|
---|
210 | * INHERITED can be specified meaning that the named logger should
|
---|
211 | * inherit its level from the logger hierarchy.</p>
|
---|
212 | *
|
---|
213 | * <p>If no level value is supplied, then the level of the
|
---|
214 | * named logger remains untouched.</p>
|
---|
215 | *
|
---|
216 | * <p>By default categories inherit their level from the
|
---|
217 | * hierarchy. However, if you set the level of a logger and later
|
---|
218 | * decide that that logger should inherit its level, then you should
|
---|
219 | * specify INHERITED as the value for the level value. NULL is a
|
---|
220 | * synonym for INHERITED.</p>
|
---|
221 | *
|
---|
222 | * <p>Similar to the root logger syntax, each <i>appenderName</i>
|
---|
223 | * (separated by commas) will be attached to the named logger.</p>
|
---|
224 | *
|
---|
225 | * <p>See the <i>appender additivity rule</i> in the user manual for
|
---|
226 | * the meaning of the <b>additivity</b> flag.
|
---|
227 | *
|
---|
228 | * <p><b>ObjectRenderers</b></p>
|
---|
229 | *
|
---|
230 | * <p>You can customize the way message objects of a given type are
|
---|
231 | * converted to String before being logged. This is done by
|
---|
232 | * specifying a {@link LoggerObjectRenderer}
|
---|
233 | * for the object type would like to customize.</p>
|
---|
234 | *
|
---|
235 | * <p>The syntax is:
|
---|
236 | *
|
---|
237 | * <pre>
|
---|
238 | * log4php.renderer.name_of_rendered_class=name_of_rendering.class
|
---|
239 | * </pre>
|
---|
240 | *
|
---|
241 | * As in,
|
---|
242 | * <pre>
|
---|
243 | * log4php.renderer.myFruit=myFruitRenderer
|
---|
244 | * </pre>
|
---|
245 | *
|
---|
246 | * <p><b>Logger Factories</b></p>
|
---|
247 | *
|
---|
248 | * The usage of custom logger factories is discouraged and no longer
|
---|
249 | * documented.
|
---|
250 | *
|
---|
251 | * <p><b>Example</b></p>
|
---|
252 | *
|
---|
253 | * <p>An example configuration is given below. Other configuration
|
---|
254 | * file examples are given in the <b>tests</b> folder.
|
---|
255 | *
|
---|
256 | * <pre>
|
---|
257 | * ; Set options for appender named "A1".
|
---|
258 | * ; Appender "A1" will be a SyslogAppender
|
---|
259 | * log4php.appender.A1=SyslogAppender
|
---|
260 | *
|
---|
261 | * ; The syslog daemon resides on www.abc.net
|
---|
262 | * log4php.appender.A1.SyslogHost=www.abc.net
|
---|
263 | *
|
---|
264 | * ; A1's layout is a LoggerPatternLayout, using the conversion pattern
|
---|
265 | * ; <b>%r %-5p %c{2} %M.%L %x - %m%n</b>. Thus, the log output will
|
---|
266 | * ; include the relative time since the start of the application in
|
---|
267 | * ; milliseconds, followed by the level of the log request,
|
---|
268 | * ; followed by the two rightmost components of the logger name,
|
---|
269 | * ; followed by the callers method name, followed by the line number,
|
---|
270 | * ; the nested disgnostic context and finally the message itself.
|
---|
271 | * ; Refer to the documentation of LoggerPatternLayout} for further information
|
---|
272 | * ; on the syntax of the ConversionPattern key.
|
---|
273 | * log4php.appender.A1.layout=LoggerPatternLayout
|
---|
274 | * log4php.appender.A1.layout.ConversionPattern="%-4r %-5p %c{2} %M.%L %x - %m%n"
|
---|
275 | *
|
---|
276 | * ; Set options for appender named "A2"
|
---|
277 | * ; A2 should be a LoggerAppenderRollingFile, with maximum file size of 10 MB
|
---|
278 | * ; using at most one backup file. A2's layout is TTCC, using the
|
---|
279 | * ; ISO8061 date format with context printing enabled.
|
---|
280 | * log4php.appender.A2=LoggerAppenderRollingFile
|
---|
281 | * log4php.appender.A2.MaxFileSize=10MB
|
---|
282 | * log4php.appender.A2.MaxBackupIndex=1
|
---|
283 | * log4php.appender.A2.layout=LoggerLayoutTTCC
|
---|
284 | * log4php.appender.A2.layout.ContextPrinting="true"
|
---|
285 | * log4php.appender.A2.layout.DateFormat="%c"
|
---|
286 | *
|
---|
287 | * ; Root logger set to DEBUG using the A2 appender defined above.
|
---|
288 | * log4php.rootLogger=DEBUG, A2
|
---|
289 | *
|
---|
290 | * ; Logger definitions:
|
---|
291 | * ; The SECURITY logger inherits is level from root. However, it's output
|
---|
292 | * ; will go to A1 appender defined above. It's additivity is non-cumulative.
|
---|
293 | * log4php.logger.SECURITY=INHERIT, A1
|
---|
294 | * log4php.additivity.SECURITY=false
|
---|
295 | *
|
---|
296 | * ; Only warnings or above will be logged for the logger "SECURITY.access".
|
---|
297 | * ; Output will go to A1.
|
---|
298 | * log4php.logger.SECURITY.access=WARN
|
---|
299 | *
|
---|
300 | *
|
---|
301 | * ; The logger "class.of.the.day" inherits its level from the
|
---|
302 | * ; logger hierarchy. Output will go to the appender's of the root
|
---|
303 | * ; logger, A2 in this case.
|
---|
304 | * log4php.logger.class.of.the.day=INHERIT
|
---|
305 | * </pre>
|
---|
306 | *
|
---|
307 | * <p>Refer to the <b>setOption</b> method in each Appender and
|
---|
308 | * Layout for class specific options.</p>
|
---|
309 | *
|
---|
310 | * <p>Use the <b>";"</b> character at the
|
---|
311 | * beginning of a line for comments.</p>
|
---|
312 | *
|
---|
313 | * @param string $url The name of the configuration file where the
|
---|
314 | * configuration information is stored.
|
---|
315 | * @param LoggerHierarchy &$repository the repository to apply the configuration
|
---|
316 | */
|
---|
317 | function doConfigure($url, &$repository)
|
---|
318 | {
|
---|
319 | $properties = @parse_ini_file($url);
|
---|
320 | if ($properties === false) {
|
---|
321 | LoggerLog::warn("LoggerPropertyConfigurator::doConfigure() cannot load '$url' configuration.");
|
---|
322 | return false;
|
---|
323 | }
|
---|
324 | return $this->doConfigureProperties($properties, $repository);
|
---|
325 | }
|
---|
326 |
|
---|
327 |
|
---|
328 | /**
|
---|
329 | * Read configuration options from <b>properties</b>.
|
---|
330 | *
|
---|
331 | * @see doConfigure().
|
---|
332 | * @param array $properties
|
---|
333 | * @param LoggerHierarchy &$hierarchy
|
---|
334 | */
|
---|
335 | function doConfigureProperties($properties, &$hierarchy)
|
---|
336 | {
|
---|
337 | $value = @$properties[LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_DEBUG_KEY];
|
---|
338 |
|
---|
339 | if (!empty($value)) {
|
---|
340 | LoggerLog::internalDebugging(LoggerOptionConverter::toBoolean($value, LoggerLog::internalDebugging()));
|
---|
341 | }
|
---|
342 |
|
---|
343 | $thresholdStr = @$properties[LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_THRESHOLD_PREFIX];
|
---|
344 | $hierarchy->setThreshold(LoggerOptionConverter::toLevel($thresholdStr, LoggerLevel::getLevelAll()));
|
---|
345 |
|
---|
346 | $this->configureRootCategory($properties, $hierarchy);
|
---|
347 | $this->configureLoggerFactory($properties);
|
---|
348 | $this->parseCatsAndRenderers($properties, $hierarchy);
|
---|
349 |
|
---|
350 | LoggerLog::debug("LoggerPropertyConfigurator::doConfigureProperties() Finished configuring.");
|
---|
351 |
|
---|
352 | return true;
|
---|
353 | }
|
---|
354 |
|
---|
355 | // --------------------------------------------------------------------------
|
---|
356 | // Internal stuff
|
---|
357 | // --------------------------------------------------------------------------
|
---|
358 |
|
---|
359 | /**
|
---|
360 | * Check the provided <b>Properties</b> object for a
|
---|
361 | * {@link LoggerFactory} entry specified by
|
---|
362 | * {@link LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_FACTORY_KEY}.
|
---|
363 | *
|
---|
364 | * If such an entry exists, an attempt is made to create an instance using
|
---|
365 | * the default constructor.
|
---|
366 | * This instance is used for subsequent Category creations
|
---|
367 | * within this configurator.
|
---|
368 | *
|
---|
369 | * @see parseCatsAndRenderers()
|
---|
370 | * @param array $props array of properties
|
---|
371 | */
|
---|
372 | function configureLoggerFactory($props)
|
---|
373 | {
|
---|
374 | $factoryFqcn = @$props[LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_FACTORY_KEY];
|
---|
375 | if(!empty($factoryFqcn)) {
|
---|
376 | $factoryClassName = basename($factoryFqcn);
|
---|
377 | LoggerLog::debug(
|
---|
378 | "LoggerPropertyConfigurator::configureLoggerFactory() Trying to load factory [" .
|
---|
379 | $factoryClassName .
|
---|
380 | "]."
|
---|
381 | );
|
---|
382 |
|
---|
383 | if (!class_exists($factoryClassName))
|
---|
384 | @include_once("{$factoryFqcn}.php");
|
---|
385 | if (class_exists($factoryClassName)) {
|
---|
386 | $loggerFactory = new $factoryClassName();
|
---|
387 | } else {
|
---|
388 | LoggerLog::debug(
|
---|
389 | "LoggerPropertyConfigurator::configureLoggerFactory() Unable to load factory [" .
|
---|
390 | $factoryClassName .
|
---|
391 | "]. Using default."
|
---|
392 | );
|
---|
393 | $loggerFactory = $this->loggerFactory;
|
---|
394 | }
|
---|
395 |
|
---|
396 | LoggerLog::debug(
|
---|
397 | "LoggerPropertyConfigurator::configureLoggerFactory() ".
|
---|
398 | "Setting properties for category factory [" . get_class($loggerFactory) . "]."
|
---|
399 | );
|
---|
400 |
|
---|
401 | LoggerPropertySetter::setPropertiesByObject($loggerFactory, $props, LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_FACTORY_PREFIX . ".");
|
---|
402 | }
|
---|
403 | }
|
---|
404 |
|
---|
405 | /**
|
---|
406 | * @param array $props array of properties
|
---|
407 | * @param LoggerHierarchy &$hierarchy
|
---|
408 | */
|
---|
409 | function configureRootCategory($props, &$hierarchy)
|
---|
410 | {
|
---|
411 | $effectivePrefix = LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ROOT_LOGGER_PREFIX;
|
---|
412 | $value = @$props[LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ROOT_LOGGER_PREFIX];
|
---|
413 |
|
---|
414 | if(empty($value)) {
|
---|
415 | $value = @$props[LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ROOT_CATEGORY_PREFIX];
|
---|
416 | $effectivePrefix = LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ROOT_CATEGORY_PREFIX;
|
---|
417 | }
|
---|
418 |
|
---|
419 | if (empty($value)) {
|
---|
420 | LoggerLog::debug(
|
---|
421 | "LoggerPropertyConfigurator::configureRootCategory() ".
|
---|
422 | "Could not find root logger information. Is this OK?"
|
---|
423 | );
|
---|
424 | } else {
|
---|
425 | $root =& $hierarchy->getRootLogger();
|
---|
426 | // synchronized(root) {
|
---|
427 | $this->parseCategory(
|
---|
428 | $props,
|
---|
429 | $root,
|
---|
430 | $effectivePrefix,
|
---|
431 | LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_INTERNAL_ROOT_NAME,
|
---|
432 | $value
|
---|
433 | );
|
---|
434 | // }
|
---|
435 | }
|
---|
436 | }
|
---|
437 |
|
---|
438 | /**
|
---|
439 | * Parse non-root elements, such non-root categories and renderers.
|
---|
440 | *
|
---|
441 | * @param array $props array of properties
|
---|
442 | * @param LoggerHierarchy &$hierarchy
|
---|
443 | */
|
---|
444 | function parseCatsAndRenderers($props, &$hierarchy)
|
---|
445 | {
|
---|
446 | while(list($key,$value) = each($props)) {
|
---|
447 | if( strpos($key, LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_CATEGORY_PREFIX) === 0 or
|
---|
448 | strpos($key, LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_PREFIX) === 0) {
|
---|
449 | if(strpos($key, LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_CATEGORY_PREFIX) === 0) {
|
---|
450 | $loggerName = substr($key, strlen(LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_CATEGORY_PREFIX));
|
---|
451 | } elseif (strpos($key, LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_PREFIX) === 0) {
|
---|
452 | $loggerName = substr($key, strlen(LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_LOGGER_PREFIX));
|
---|
453 | }
|
---|
454 | $logger =& $hierarchy->getLogger($loggerName, $this->loggerFactory);
|
---|
455 | // synchronized(logger) {
|
---|
456 | $this->parseCategory($props, $logger, $key, $loggerName, $value);
|
---|
457 | $this->parseAdditivityForLogger($props, $logger, $loggerName);
|
---|
458 | // }
|
---|
459 | } elseif (strpos($key, LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_RENDERER_PREFIX) === 0) {
|
---|
460 | $renderedClass = substr($key, strlen(LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_RENDERER_PREFIX));
|
---|
461 | $renderingClass = $value;
|
---|
462 | if (method_exists($hierarchy, 'addrenderer')) {
|
---|
463 | LoggerRendererMap::addRenderer($hierarchy, $renderedClass, $renderingClass);
|
---|
464 | }
|
---|
465 | }
|
---|
466 | }
|
---|
467 | }
|
---|
468 |
|
---|
469 | /**
|
---|
470 | * Parse the additivity option for a non-root category.
|
---|
471 | *
|
---|
472 | * @param array $props array of properties
|
---|
473 | * @param Logger &$cat
|
---|
474 | * @param string $loggerName
|
---|
475 | */
|
---|
476 | function parseAdditivityForLogger($props, &$cat, $loggerName)
|
---|
477 | {
|
---|
478 | $value = LoggerOptionConverter::findAndSubst(
|
---|
479 | LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ADDITIVITY_PREFIX . $loggerName,
|
---|
480 | $props
|
---|
481 | );
|
---|
482 | LoggerLog::debug(
|
---|
483 | "LoggerPropertyConfigurator::parseAdditivityForLogger() ".
|
---|
484 | "Handling " . LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_ADDITIVITY_PREFIX . $loggerName . "=[{$value}]"
|
---|
485 | );
|
---|
486 | // touch additivity only if necessary
|
---|
487 | if(!empty($value)) {
|
---|
488 | $additivity = LoggerOptionConverter::toBoolean($value, true);
|
---|
489 | LoggerLog::debug(
|
---|
490 | "LoggerPropertyConfigurator::parseAdditivityForLogger() ".
|
---|
491 | "Setting additivity for [{$loggerName}] to [{$additivity}]"
|
---|
492 | );
|
---|
493 | $cat->setAdditivity($additivity);
|
---|
494 | }
|
---|
495 | }
|
---|
496 |
|
---|
497 | /**
|
---|
498 | * This method must work for the root category as well.
|
---|
499 | *
|
---|
500 | * @param array $props array of properties
|
---|
501 | * @param Logger &$logger
|
---|
502 | * @param string $optionKey
|
---|
503 | * @param string $loggerName
|
---|
504 | * @param string $value
|
---|
505 | * @return Logger
|
---|
506 | */
|
---|
507 | function &parseCategory($props, &$logger, $optionKey, $loggerName, $value)
|
---|
508 | {
|
---|
509 | LoggerLog::debug(
|
---|
510 | "LoggerPropertyConfigurator::parseCategory() ".
|
---|
511 | "Parsing for [{$loggerName}] with value=[{$value}]."
|
---|
512 | );
|
---|
513 |
|
---|
514 | // We must skip over ',' but not white space
|
---|
515 | $st = explode(',', $value);
|
---|
516 |
|
---|
517 | // If value is not in the form ", appender.." or "", then we should set
|
---|
518 | // the level of the loggeregory.
|
---|
519 |
|
---|
520 | if(!(@$value{0} == ',' || empty($value))) {
|
---|
521 | // just to be on the safe side...
|
---|
522 | if(sizeof($st) == 0)
|
---|
523 | return;
|
---|
524 |
|
---|
525 | $levelStr = current($st);
|
---|
526 | LoggerLog::debug(
|
---|
527 | "LoggerPropertyConfigurator::parseCategory() ".
|
---|
528 | "Level token is [$levelStr]."
|
---|
529 | );
|
---|
530 |
|
---|
531 | // If the level value is inherited, set category level value to
|
---|
532 | // null. We also check that the user has not specified inherited for the
|
---|
533 | // root category.
|
---|
534 | if('INHERITED' == strtoupper($levelStr) || 'NULL' == strtoupper($levelStr)) {
|
---|
535 | if ($loggerName == LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_INTERNAL_ROOT_NAME) {
|
---|
536 | LoggerLog::warn(
|
---|
537 | "LoggerPropertyConfigurator::parseCategory() ".
|
---|
538 | "The root logger cannot be set to null."
|
---|
539 | );
|
---|
540 | } else {
|
---|
541 | $logger->setLevel(null);
|
---|
542 | }
|
---|
543 | } else {
|
---|
544 | $logger->setLevel(LoggerOptionConverter::toLevel($levelStr, LoggerLevel::getLevelDebug()));
|
---|
545 | }
|
---|
546 | }
|
---|
547 |
|
---|
548 | // Begin by removing all existing appenders.
|
---|
549 | $logger->removeAllAppenders();
|
---|
550 | while($appenderName = next($st)) {
|
---|
551 | $appenderName = trim($appenderName);
|
---|
552 | if(empty($appenderName))
|
---|
553 | continue;
|
---|
554 | LoggerLog::debug(
|
---|
555 | "LoggerPropertyConfigurator::parseCategory() ".
|
---|
556 | "Parsing appender named [{$appenderName}]."
|
---|
557 | );
|
---|
558 | $appender =& $this->parseAppender($props, $appenderName);
|
---|
559 | if($appender !== null) {
|
---|
560 | $logger->addAppender($appender);
|
---|
561 | }
|
---|
562 | }
|
---|
563 | }
|
---|
564 |
|
---|
565 | /**
|
---|
566 | * @param array $props array of properties
|
---|
567 | * @param string $appenderName
|
---|
568 | * @return LoggerAppender
|
---|
569 | */
|
---|
570 | function &parseAppender($props, $appenderName)
|
---|
571 | {
|
---|
572 | $appender =& LoggerAppender::singleton($appenderName);
|
---|
573 | if($appender !== null) {
|
---|
574 | LoggerLog::debug(
|
---|
575 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
576 | "Appender [{$appenderName}] was already parsed."
|
---|
577 | );
|
---|
578 | return $appender;
|
---|
579 | }
|
---|
580 | // Appender was not previously initialized.
|
---|
581 | $prefix = LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_APPENDER_PREFIX . $appenderName;
|
---|
582 | $layoutPrefix = $prefix . ".layout";
|
---|
583 | $appenderClass = @$props[$prefix];
|
---|
584 | if (!empty($appenderClass)) {
|
---|
585 | $appender =& LoggerAppender::singleton($appenderName, $appenderClass);
|
---|
586 | if($appender === null) {
|
---|
587 | LoggerLog::warn(
|
---|
588 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
589 | "Could not instantiate appender named [$appenderName]."
|
---|
590 | );
|
---|
591 | return null;
|
---|
592 | }
|
---|
593 | } else {
|
---|
594 | LoggerLog::warn(
|
---|
595 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
596 | "Could not instantiate appender named [$appenderName] with null className."
|
---|
597 | );
|
---|
598 | return null;
|
---|
599 | }
|
---|
600 |
|
---|
601 | $appender->setName($appenderName);
|
---|
602 | if( $appender->requiresLayout() ) {
|
---|
603 | LoggerLog::debug(
|
---|
604 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
605 | "Parsing layout section for [$appenderName]."
|
---|
606 | );
|
---|
607 | $layoutClass = @$props[$layoutPrefix];
|
---|
608 | $layoutClass = LoggerOptionConverter::substVars($layoutClass, $props);
|
---|
609 | if (empty($layoutClass)) {
|
---|
610 | LoggerLog::warn(
|
---|
611 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
612 | "layout class is empty in '$layoutPrefix'. Using Simple layout"
|
---|
613 | );
|
---|
614 | $layout = LoggerLayout::factory('LoggerLayoutSimple');
|
---|
615 | } else {
|
---|
616 | $layout = LoggerLayout::factory($layoutClass);
|
---|
617 |
|
---|
618 | if($layout === null) {
|
---|
619 | LoggerLog::warn(
|
---|
620 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
621 | "cannot create layout '$layoutClass'. Using Simple layout"
|
---|
622 | );
|
---|
623 | $layout = LoggerLayout::factory('LoggerLayoutSimple');
|
---|
624 | }
|
---|
625 | }
|
---|
626 |
|
---|
627 | LoggerLog::debug(
|
---|
628 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
629 | "Parsing layout options for [$appenderName]."
|
---|
630 | );
|
---|
631 | LoggerPropertySetter::setPropertiesByObject($layout, $props, $layoutPrefix . ".");
|
---|
632 | LoggerLog::debug(
|
---|
633 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
634 | "End Parsing layout options for [$appenderName]."
|
---|
635 | );
|
---|
636 | $appender->setLayout($layout);
|
---|
637 |
|
---|
638 | }
|
---|
639 | LoggerPropertySetter::setPropertiesByObject($appender, $props, $prefix . ".");
|
---|
640 | LoggerLog::debug(
|
---|
641 | "LoggerPropertyConfigurator::parseAppender() ".
|
---|
642 | "Parsed [{$appenderName}] options."
|
---|
643 | );
|
---|
644 | return $appender;
|
---|
645 | }
|
---|
646 |
|
---|
647 | }
|
---|
648 | ?> |
---|