source: branches/comu-ver2/data/module/log4php/php5/log4php/LoggerPropertyConfigurator.php @ 18220

Revision 18220, 26.3 KB checked in by yokkuns, 15 years ago (diff)

#149 ロガークラス作成

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