You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ih...@apache.org on 2011/12/13 15:30:51 UTC
svn commit: r1213710 - in /logging/log4php/trunk/src: main/php/
main/php/configurators/ site/xdoc/docs/ test/php/ test/php/filters/
Author: ihabunek
Date: Tue Dec 13 14:30:50 2011
New Revision: 1213710
URL: http://svn.apache.org/viewvc?rev=1213710&view=rev
Log:
Reintroduced the possibility of using a custom configurator which was lost when rewriting the configurator (LOG4PHP-152). Also updated docs for configuration.
Added:
logging/log4php/trunk/src/main/php/configurators/LoggerConfiguratorDefault.php
Modified:
logging/log4php/trunk/src/main/php/Logger.php
logging/log4php/trunk/src/main/php/LoggerConfigurator.php
logging/log4php/trunk/src/site/xdoc/docs/configuration.xml
logging/log4php/trunk/src/test/php/LoggerConfiguratorTest.php
logging/log4php/trunk/src/test/php/filters/LoggerFilterDenyAllTest.php
Modified: logging/log4php/trunk/src/main/php/Logger.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/main/php/Logger.php?rev=1213710&r1=1213709&r2=1213710&view=diff
==============================================================================
--- logging/log4php/trunk/src/main/php/Logger.php (original)
+++ logging/log4php/trunk/src/main/php/Logger.php Tue Dec 13 14:30:50 2011
@@ -54,6 +54,7 @@ class Logger {
'LoggerReflectionUtils' => '/LoggerReflectionUtils.php',
'LoggerConfigurable' => '/LoggerConfigurable.php',
'LoggerConfigurator' => '/LoggerConfigurator.php',
+ 'LoggerConfiguratorDefault' => '/configurators/LoggerConfiguratorDefault.php',
'LoggerConfigurationAdapter' => '/configurators/LoggerConfigurationAdapter.php',
'LoggerConfigurationAdapterINI' => '/configurators/LoggerConfigurationAdapterINI.php',
'LoggerConfigurationAdapterXML' => '/configurators/LoggerConfigurationAdapterXML.php',
@@ -558,15 +559,46 @@ class Logger {
*
* @param string|array $configuration Either a path to the configuration
* file, or a configuration array.
+ *
+ * @param mixed $configuratorClass A custom configurator class: either a
+ * class name (string), or an object which implements LoggerConfigurator
+ * interface. If left empty, the default configurator will be used.
*/
- public static function configure($configuration = null) {
+ public static function configure($configuration = null, $configuratorClass = null) {
self::resetConfiguration();
- $configurator = new LoggerConfigurator();
+ $configurator = self::getConfigurator($configuratorClass);
$configurator->configure(self::getHierarchy(), $configuration);
self::$initialized = true;
}
/**
+ * Creates a logger configurator instance based on the provided
+ * configurator class. If no class is given, returns an instance of
+ * the default configurator.
+ *
+ * @param string $configuratorClass The configurator class.
+ */
+ private static function getConfigurator($configuratorClass = null) {
+ if (empty($configuratorClass)) {
+ return new LoggerConfiguratorDefault();
+ }
+
+ if (!class_exists($configuratorClass)) {
+ $this->warn("Specified configurator class [$configuratorClass] does not exist. Reverting to default configurator.");
+ return new LoggerConfiguratorDefault();
+ }
+
+ $configurator = new $configuratorClass();
+
+ if (!($configurator instanceof LoggerConfigurator)) {
+ $this->warn("Specified configurator class [$configuratorClass] does not implement the LoggerConfigurator interface. Reverting to default configurator.");
+ return new LoggerConfiguratorDefault();
+ }
+
+ return $configurator;
+ }
+
+ /**
* Returns true if the log4php framework has been initialized.
* @return boolean
*/
Modified: logging/log4php/trunk/src/main/php/LoggerConfigurator.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/main/php/LoggerConfigurator.php?rev=1213710&r1=1213709&r2=1213710&view=diff
==============================================================================
--- logging/log4php/trunk/src/main/php/LoggerConfigurator.php (original)
+++ logging/log4php/trunk/src/main/php/LoggerConfigurator.php Tue Dec 13 14:30:50 2011
@@ -19,465 +19,24 @@
*/
/**
- * Configures log4php based on a provided configuration file or array.
+ * Interface for logger configurators.
*
* @package log4php
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version $Revision$
* @since 2.2
*/
-class LoggerConfigurator
+interface LoggerConfigurator
{
- /** XML configuration file format. */
- const FORMAT_XML = 'xml';
-
- /** PHP configuration file format. */
- const FORMAT_PHP = 'php';
-
- /** INI (properties) configuration file format. */
- const FORMAT_INI = 'ini';
-
- /** Defines which adapter should be used for parsing which format. */
- private $adapters = array(
- self::FORMAT_XML => 'LoggerConfigurationAdapterXML',
- self::FORMAT_INI => 'LoggerConfigurationAdapterINI',
- self::FORMAT_PHP => 'LoggerConfigurationAdapterPHP',
- );
-
- /** Default configuration; used if no configuration file is provided. */
- private static $defaultConfiguration = array(
- 'threshold' => 'ALL',
- 'rootLogger' => array(
- 'level' => 'DEBUG',
- 'appenders' => array('default'),
- ),
- 'appenders' => array(
- 'default' => array(
- 'class' => 'LoggerAppenderEcho',
- 'layout' => array(
- 'class' => 'LoggerLayoutTTCC',
- ),
- ),
- ),
- );
-
- /** Holds the appenders before they are linked to loggers. */
- private $appenders = array();
-
/**
- * Configures log4php based on the given configuration. The input can
- * either be a path to the config file, or a PHP array holding the
- * configuration.
+ * Configures log4php based on the given configuration.
*
- * If no configuration is given, or if the given configuration cannot be
- * parsed for whatever reason, a warning will be issued, and log4php
- * will use the default configuration contained in
- * {@link $defaultConfiguration}.
+ * All configurators implementations must implement this interface.
*
* @param LoggerHierarchy $hierarchy The hierarchy on which to perform
* the configuration.
- * @param string|array $input Either path to the config file or the
- * configuration as an array. If not set, default configuration
- * will be used.
- */
- public function configure(LoggerHierarchy $hierarchy, $input = null) {
- $config = $this->parse($input);
- $this->doConfigure($hierarchy, $config);
- }
-
- /**
- * Parses the given configuration and returns the parsed configuration
- * as a PHP array. Does not perform any configuration.
- *
- * If no configuration is given, or if the given configuration cannot be
- * parsed for whatever reason, a warning will be issued, and the default
- * configuration will be returned ({@link $defaultConfiguration}).
- *
- * @param string|array $input Either path to the config file or the
- * configuration as an array. If not set, default configuration
- * will be used.
- * @return array The parsed configuration.
- */
- public function parse($input)
- {
- // No input - use default configuration
- if (!isset($input)) {
- $config = self::$defaultConfiguration;
- }
-
- // Array input - contains configuration within the array
- else if (is_array($input)) {
- $config = $input;
- }
-
- // String input - contains path to configuration file
- else if (is_string($input)) {
- try {
- $config = $this->parseFile($input);
- } catch (LoggerException $e) {
- $this->warn("Configuration failed. " . $e->getMessage() . " Using default configuration.");
- $config = self::$defaultConfiguration;
- }
- }
-
- // Anything else is an error
- else {
- $this->warn("Invalid configuration param given. Reverting to default configuration.");
- $config = self::$defaultConfiguration;
- }
-
- return $config;
- }
-
- /**
- * Returns the default log4php configuration.
- * @return array
- */
- public static function getDefaultConfiguration() {
- return self::$defaultConfiguration;
- }
-
- /**
- * Loads the configuration file from the given URL, determines which
- * adapter to use, converts the configuration to a PHP array and
- * returns it.
- *
- * @param string $url Path to the config file.
- * @return The configuration from the config file, as a PHP array.
- * @throws LoggerException If the configuration file cannot be loaded, or
- * if the parsing fails.
- */
- private function parseFile($url) {
-
- if (!file_exists($url)) {
- throw new LoggerException("File not found at [$url].");
- }
-
- $type = $this->getConfigType($url);
- $adapterClass = $this->adapters[$type];
-
- $adapter = new $adapterClass();
- return $adapter->convert($url);
- }
-
- /** Determines configuration file type based on the file extension. */
- private function getConfigType($url) {
- $info = pathinfo($url);
- $ext = strtolower($info['extension']);
-
- switch($ext) {
- case 'xml':
- return self::FORMAT_XML;
-
- case 'ini':
- case 'properties':
- return self::FORMAT_INI;
-
- case 'php':
- return self::FORMAT_PHP;
-
- default:
- throw new LoggerException("Unsupported configuration file extension: $ext");
- }
- }
-
- /**
- * Constructs the logger hierarchy based on configuration.
- *
- * @param LoggerHierarchy $hierarchy
- * @param array $config
- */
- private function doConfigure(LoggerHierarchy $hierarchy, $config) {
- if (isset($config['threshold'])) {
- $threshold = LoggerLevel::toLevel($config['threshold']);
- if (isset($threshold)) {
- $hierarchy->setThreshold($threshold);
- } else {
- $this->warn("Invalid threshold value [{$config['threshold']}] specified. Ignoring threshold definition.");
- }
- }
-
- // Configure appenders and add them to the appender pool
- if (isset($config['appenders']) && is_array($config['appenders'])) {
- foreach($config['appenders'] as $name => $appenderConfig) {
- $this->configureAppender($name, $appenderConfig);
- }
- }
-
- // Configure root logger
- if (isset($config['rootLogger'])) {
- $this->configureRootLogger($hierarchy, $config['rootLogger']);
- }
-
- // Configure loggers
- if (isset($config['loggers']) && is_array($config['loggers'])) {
- foreach($config['loggers'] as $loggerName => $loggerConfig) {
- $this->configureOtherLogger($hierarchy, $loggerName, $loggerConfig);
- }
- }
-
- // Configure renderers
- if (isset($config['renderers']) && is_array($config['renderers'])) {
- foreach($config['renderers'] as $rendererConfig) {
- $this->configureRenderer($hierarchy, $rendererConfig);
- }
- }
- }
-
- private function configureRenderer(LoggerHierarchy $hierarchy, $config) {
- if (!isset($config['renderingClass'])) {
- $this->warn("Rendering class not specified. Skipping renderers definition.");
- return;
- }
-
- $renderingClass = $config['renderingClass'];
- if (!class_exists($renderingClass)) {
- $this->warn("Nonexistant rendering class [$renderingClass] specified. Skipping renderers definition.");
- return;
- }
-
- $renderingClassInstance = new $renderingClass();
- if (!$renderingClassInstance instanceof LoggerRendererObject) {
- $this->warn("Invalid class [$renderingClass] given. Not a valid LoggerRenderer class. Skipping renderers definition.");
- return;
- }
-
- if (!isset($config['renderedClass'])) {
- $this->warn("Rendered class not specified for rendering Class [$renderingClass]. Skipping renderers definition.");
- return;
- }
-
- $renderedClass = $config['renderedClass'];
- if (!class_exists($renderedClass)) {
- $this->warn("Nonexistant rendered class [$renderedClass] specified for renderer [$renderingClass]. Skipping renderers definition.");
- return;
- }
-
- $hierarchy->getRendererMap()->addRenderer($renderedClass, $renderingClassInstance);
- }
-
- /**
- * Configures an appender based on given config and saves it to
- * {@link $appenders} array so it can be later linked to loggers.
- * @param string $name Appender name.
- * @param array $config Appender configuration options.
- */
- private function configureAppender($name, $config) {
-
- // TODO: add this check to other places where it might be useful
- if (!is_array($config)) {
- $type = gettype($config);
- $this->warn("Invalid configuration provided for appender [$name]. Expected an array, found <$type>. Skipping appender definition.");
- return;
- }
-
- // Parse appender class
- $class = $config['class'];
- if (empty($class)) {
- $this->warn("No class given for appender [$name]. Skipping appender definition.");
- return;
- }
- if (!class_exists($class)) {
- $this->warn("Invalid class [$class] given for appender [$name]. Class does not exist. Skipping appender definition.");
- return;
- }
-
- // Instantiate the appender
- $appender = new $class($name);
- if (!($appender instanceof LoggerAppender)) {
- $this->warn("Invalid class [$class] given for appender [$name]. Not a valid LoggerAppender class. Skipping appender definition.");
- return;
- }
-
- // Parse the appender threshold
- if (isset($config['threshold'])) {
- $threshold = LoggerLevel::toLevel($config['threshold']);
- if ($threshold instanceof LoggerLevel) {
- $appender->setThreshold($threshold);
- } else {
- $this->warn("Invalid threshold value [{$config['threshold']}] specified for appender [$name]. Ignoring threshold definition.");
- }
- }
-
- // Parse the appender layout
- if ($appender->requiresLayout() && isset($config['layout'])) {
- $this->createAppenderLayout($appender, $config['layout']);
- }
-
- // Parse filters
- if (isset($config['filters']) && is_array($config['filters'])) {
- foreach($config['filters'] as $filterConfig) {
- $this->createAppenderFilter($appender, $filterConfig);
- }
- }
-
- // Set options if any
- if (isset($config['params'])) {
- $this->setOptions($appender, $config['params']);
- }
-
- // Activate and save for later linking to loggers
- $appender->activateOptions();
- $this->appenders[$name] = $appender;
- }
-
- /**
- * Parses layout config, creates the layout and links it to the appender.
- * @param LoggerAppender $appender
- * @param array $config Layout configuration.
- */
- private function createAppenderLayout(LoggerAppender $appender, $config) {
- $name = $appender->getName();
- $class = $config['class'];
- if (empty($class)) {
- $this->warn("Layout class not specified for appender [$name]. Reverting to default layout.");
- return;
- }
- if (!class_exists($class)) {
- $this->warn("Nonexistant layout class [$class] specified for appender [$name]. Reverting to default layout.");
- return;
- }
-
- $layout = new $class();
- if (!($layout instanceof LoggerLayout)) {
- $this->warn("Invalid layout class [$class] sepcified for appender [$name]. Reverting to default layout.");
- return;
- }
-
- if (isset($config['params'])) {
- $this->setOptions($layout, $config['params']);
- }
-
- $layout->activateOptions();
- $appender->setLayout($layout);
- }
-
- /**
- * Parses filter config, creates the filter and adds it to the appender's
- * filter chain.
- * @param LoggerAppender $appender
- * @param array $config Filter configuration.
- */
- private function createAppenderFilter(LoggerAppender $appender, $config) {
- $name = $appender->getName();
- $class = $config['class'];
- if (!class_exists($class)) {
- $this->warn("Nonexistant filter class [$class] specified on appender [$name]. Skipping filter definition.");
- return;
- }
-
- $filter = new $class();
- if (!($filter instanceof LoggerFilter)) {
- $this->warn("Invalid filter class [$class] sepcified on appender [$name]. Skipping filter definition.");
- return;
- }
-
- if (isset($config['params'])) {
- $this->setOptions($filter, $config['params']);
- }
-
- $filter->activateOptions();
- $appender->addFilter($filter);
- }
-
- /**
- * Configures the root logger
- * @see configureLogger()
- */
- private function configureRootLogger(LoggerHierarchy $hierarchy, $config) {
- $logger = $hierarchy->getRootLogger();
- $this->configureLogger($logger, $config);
- }
-
- /**
- * Configures a logger which is not root.
- * @see configureLogger()
- */
- private function configureOtherLogger(LoggerHierarchy $hierarchy, $name, $config) {
- // Get logger from hierarchy (this creates it if it doesn't already exist)
- $logger = $hierarchy->getLogger($name);
- $this->configureLogger($logger, $config);
- }
-
- /**
- * Configures a logger.
- *
- * @param Logger $logger The logger to configure
- * @param array $config Logger configuration options.
- */
- private function configureLogger(Logger $logger, $config) {
- $loggerName = $logger->getName();
-
- // Set logger level
- if (isset($config['level'])) {
- $level = LoggerLevel::toLevel($config['level']);
- if (isset($level)) {
- $logger->setLevel($level);
- } else {
- $default = $logger->getLevel();
- $this->warn("Invalid level value [{$config['level']}] specified for logger [$loggerName]. Ignoring level definition.");
- }
- }
-
- // Link appenders to logger
- if (isset($config['appenders'])) {
- foreach($config['appenders'] as $appenderName) {
- if (isset($this->appenders[$appenderName])) {
- $logger->addAppender($this->appenders[$appenderName]);
- } else {
- $this->warn("Nonexistnant appender [$appenderName] linked to logger [$loggerName].");
- }
- }
- }
-
- // Set logger additivity
- if (isset($config['additivity'])) {
- $additivity = LoggerOptionConverter::toBoolean($config['additivity'], null);
- if (is_bool($additivity)) {
- $logger->setAdditivity($additivity);
- } else {
- $this->warn("Invalid additivity value [{$config['additivity']}] specified for logger [$loggerName]. Ignoring additivity setting.");
- }
- }
- }
-
- /**
- * Helper method which applies given options to an object which has setters
- * for these options (such as appenders, layouts, etc.).
- *
- * For example, if options are:
- * <code>
- * array(
- * 'file' => '/tmp/myfile.log',
- * 'append' => true
- * )
- * </code>
- *
- * This method will call:
- * <code>
- * $object->setFile('/tmp/myfile.log')
- * $object->setAppend(true)
- * </code>
- *
- * If required setters do not exist, it will produce a warning.
- *
- * @param mixed $object The object to configure.
- * @param unknown_type $options
+ * @param mixed $input Either path to the config file or the
+ * configuration as an array.
*/
- private function setOptions($object, $options) {
- foreach($options as $name => $value) {
- $setter = "set$name";
- if (method_exists($object, $setter)) {
- $object->$setter($value);
- } else {
- $class = get_class($object);
- $this->warn("Nonexistant option [$name] specified on [$class]. Skipping.");
- }
- }
- }
-
- /** Helper method to simplify error reporting. */
- private function warn($message) {
- trigger_error("log4php: $message", E_USER_WARNING);
- }
+ public function configure(LoggerHierarchy $hierarchy, $input = null);
}
\ No newline at end of file
Added: logging/log4php/trunk/src/main/php/configurators/LoggerConfiguratorDefault.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/main/php/configurators/LoggerConfiguratorDefault.php?rev=1213710&view=auto
==============================================================================
--- logging/log4php/trunk/src/main/php/configurators/LoggerConfiguratorDefault.php (added)
+++ logging/log4php/trunk/src/main/php/configurators/LoggerConfiguratorDefault.php Tue Dec 13 14:30:50 2011
@@ -0,0 +1,485 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Default implementation of the logger configurator.
+ *
+ * Configures log4php based on a provided configuration file or array.
+ *
+ * @package log4php
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1212319 $
+ * @since 2.2
+ */
+class LoggerConfiguratorDefault implements LoggerConfigurator
+{
+ /** XML configuration file format. */
+ const FORMAT_XML = 'xml';
+
+ /** PHP configuration file format. */
+ const FORMAT_PHP = 'php';
+
+ /** INI (properties) configuration file format. */
+ const FORMAT_INI = 'ini';
+
+ /** Defines which adapter should be used for parsing which format. */
+ private $adapters = array(
+ self::FORMAT_XML => 'LoggerConfigurationAdapterXML',
+ self::FORMAT_INI => 'LoggerConfigurationAdapterINI',
+ self::FORMAT_PHP => 'LoggerConfigurationAdapterPHP',
+ );
+
+ /** Default configuration; used if no configuration file is provided. */
+ private static $defaultConfiguration = array(
+ 'threshold' => 'ALL',
+ 'rootLogger' => array(
+ 'level' => 'DEBUG',
+ 'appenders' => array('default'),
+ ),
+ 'appenders' => array(
+ 'default' => array(
+ 'class' => 'LoggerAppenderEcho',
+ 'layout' => array(
+ 'class' => 'LoggerLayoutTTCC',
+ ),
+ ),
+ ),
+ );
+
+ /** Holds the appenders before they are linked to loggers. */
+ private $appenders = array();
+
+ /**
+ * Configures log4php based on the given configuration. The input can
+ * either be a path to the config file, or a PHP array holding the
+ * configuration.
+ *
+ * If no configuration is given, or if the given configuration cannot be
+ * parsed for whatever reason, a warning will be issued, and log4php
+ * will use the default configuration contained in
+ * {@link $defaultConfiguration}.
+ *
+ * @param LoggerHierarchy $hierarchy The hierarchy on which to perform
+ * the configuration.
+ * @param string|array $input Either path to the config file or the
+ * configuration as an array. If not set, default configuration
+ * will be used.
+ */
+ public function configure(LoggerHierarchy $hierarchy, $input = null) {
+ $config = $this->parse($input);
+ $this->doConfigure($hierarchy, $config);
+ }
+
+ /**
+ * Parses the given configuration and returns the parsed configuration
+ * as a PHP array. Does not perform any configuration.
+ *
+ * If no configuration is given, or if the given configuration cannot be
+ * parsed for whatever reason, a warning will be issued, and the default
+ * configuration will be returned ({@link $defaultConfiguration}).
+ *
+ * @param string|array $input Either path to the config file or the
+ * configuration as an array. If not set, default configuration
+ * will be used.
+ * @return array The parsed configuration.
+ */
+ public function parse($input)
+ {
+ // No input - use default configuration
+ if (!isset($input)) {
+ $config = self::$defaultConfiguration;
+ }
+
+ // Array input - contains configuration within the array
+ else if (is_array($input)) {
+ $config = $input;
+ }
+
+ // String input - contains path to configuration file
+ else if (is_string($input)) {
+ try {
+ $config = $this->parseFile($input);
+ } catch (LoggerException $e) {
+ $this->warn("Configuration failed. " . $e->getMessage() . " Using default configuration.");
+ $config = self::$defaultConfiguration;
+ }
+ }
+
+ // Anything else is an error
+ else {
+ $this->warn("Invalid configuration param given. Reverting to default configuration.");
+ $config = self::$defaultConfiguration;
+ }
+
+ return $config;
+ }
+
+ /**
+ * Returns the default log4php configuration.
+ * @return array
+ */
+ public static function getDefaultConfiguration() {
+ return self::$defaultConfiguration;
+ }
+
+ /**
+ * Loads the configuration file from the given URL, determines which
+ * adapter to use, converts the configuration to a PHP array and
+ * returns it.
+ *
+ * @param string $url Path to the config file.
+ * @return The configuration from the config file, as a PHP array.
+ * @throws LoggerException If the configuration file cannot be loaded, or
+ * if the parsing fails.
+ */
+ private function parseFile($url) {
+
+ if (!file_exists($url)) {
+ throw new LoggerException("File not found at [$url].");
+ }
+
+ $type = $this->getConfigType($url);
+ $adapterClass = $this->adapters[$type];
+
+ $adapter = new $adapterClass();
+ return $adapter->convert($url);
+ }
+
+ /** Determines configuration file type based on the file extension. */
+ private function getConfigType($url) {
+ $info = pathinfo($url);
+ $ext = strtolower($info['extension']);
+
+ switch($ext) {
+ case 'xml':
+ return self::FORMAT_XML;
+
+ case 'ini':
+ case 'properties':
+ return self::FORMAT_INI;
+
+ case 'php':
+ return self::FORMAT_PHP;
+
+ default:
+ throw new LoggerException("Unsupported configuration file extension: $ext");
+ }
+ }
+
+ /**
+ * Constructs the logger hierarchy based on configuration.
+ *
+ * @param LoggerHierarchy $hierarchy
+ * @param array $config
+ */
+ private function doConfigure(LoggerHierarchy $hierarchy, $config) {
+ if (isset($config['threshold'])) {
+ $threshold = LoggerLevel::toLevel($config['threshold']);
+ if (isset($threshold)) {
+ $hierarchy->setThreshold($threshold);
+ } else {
+ $this->warn("Invalid threshold value [{$config['threshold']}] specified. Ignoring threshold definition.");
+ }
+ }
+
+ // Configure appenders and add them to the appender pool
+ if (isset($config['appenders']) && is_array($config['appenders'])) {
+ foreach($config['appenders'] as $name => $appenderConfig) {
+ $this->configureAppender($name, $appenderConfig);
+ }
+ }
+
+ // Configure root logger
+ if (isset($config['rootLogger'])) {
+ $this->configureRootLogger($hierarchy, $config['rootLogger']);
+ }
+
+ // Configure loggers
+ if (isset($config['loggers']) && is_array($config['loggers'])) {
+ foreach($config['loggers'] as $loggerName => $loggerConfig) {
+ $this->configureOtherLogger($hierarchy, $loggerName, $loggerConfig);
+ }
+ }
+
+ // Configure renderers
+ if (isset($config['renderers']) && is_array($config['renderers'])) {
+ foreach($config['renderers'] as $rendererConfig) {
+ $this->configureRenderer($hierarchy, $rendererConfig);
+ }
+ }
+ }
+
+ private function configureRenderer(LoggerHierarchy $hierarchy, $config) {
+ if (!isset($config['renderingClass'])) {
+ $this->warn("Rendering class not specified. Skipping renderers definition.");
+ return;
+ }
+
+ $renderingClass = $config['renderingClass'];
+ if (!class_exists($renderingClass)) {
+ $this->warn("Nonexistant rendering class [$renderingClass] specified. Skipping renderers definition.");
+ return;
+ }
+
+ $renderingClassInstance = new $renderingClass();
+ if (!$renderingClassInstance instanceof LoggerRendererObject) {
+ $this->warn("Invalid class [$renderingClass] given. Not a valid LoggerRenderer class. Skipping renderers definition.");
+ return;
+ }
+
+ if (!isset($config['renderedClass'])) {
+ $this->warn("Rendered class not specified for rendering Class [$renderingClass]. Skipping renderers definition.");
+ return;
+ }
+
+ $renderedClass = $config['renderedClass'];
+ if (!class_exists($renderedClass)) {
+ $this->warn("Nonexistant rendered class [$renderedClass] specified for renderer [$renderingClass]. Skipping renderers definition.");
+ return;
+ }
+
+ $hierarchy->getRendererMap()->addRenderer($renderedClass, $renderingClassInstance);
+ }
+
+ /**
+ * Configures an appender based on given config and saves it to
+ * {@link $appenders} array so it can be later linked to loggers.
+ * @param string $name Appender name.
+ * @param array $config Appender configuration options.
+ */
+ private function configureAppender($name, $config) {
+
+ // TODO: add this check to other places where it might be useful
+ if (!is_array($config)) {
+ $type = gettype($config);
+ $this->warn("Invalid configuration provided for appender [$name]. Expected an array, found <$type>. Skipping appender definition.");
+ return;
+ }
+
+ // Parse appender class
+ $class = $config['class'];
+ if (empty($class)) {
+ $this->warn("No class given for appender [$name]. Skipping appender definition.");
+ return;
+ }
+ if (!class_exists($class)) {
+ $this->warn("Invalid class [$class] given for appender [$name]. Class does not exist. Skipping appender definition.");
+ return;
+ }
+
+ // Instantiate the appender
+ $appender = new $class($name);
+ if (!($appender instanceof LoggerAppender)) {
+ $this->warn("Invalid class [$class] given for appender [$name]. Not a valid LoggerAppender class. Skipping appender definition.");
+ return;
+ }
+
+ // Parse the appender threshold
+ if (isset($config['threshold'])) {
+ $threshold = LoggerLevel::toLevel($config['threshold']);
+ if ($threshold instanceof LoggerLevel) {
+ $appender->setThreshold($threshold);
+ } else {
+ $this->warn("Invalid threshold value [{$config['threshold']}] specified for appender [$name]. Ignoring threshold definition.");
+ }
+ }
+
+ // Parse the appender layout
+ if ($appender->requiresLayout() && isset($config['layout'])) {
+ $this->createAppenderLayout($appender, $config['layout']);
+ }
+
+ // Parse filters
+ if (isset($config['filters']) && is_array($config['filters'])) {
+ foreach($config['filters'] as $filterConfig) {
+ $this->createAppenderFilter($appender, $filterConfig);
+ }
+ }
+
+ // Set options if any
+ if (isset($config['params'])) {
+ $this->setOptions($appender, $config['params']);
+ }
+
+ // Activate and save for later linking to loggers
+ $appender->activateOptions();
+ $this->appenders[$name] = $appender;
+ }
+
+ /**
+ * Parses layout config, creates the layout and links it to the appender.
+ * @param LoggerAppender $appender
+ * @param array $config Layout configuration.
+ */
+ private function createAppenderLayout(LoggerAppender $appender, $config) {
+ $name = $appender->getName();
+ $class = $config['class'];
+ if (empty($class)) {
+ $this->warn("Layout class not specified for appender [$name]. Reverting to default layout.");
+ return;
+ }
+ if (!class_exists($class)) {
+ $this->warn("Nonexistant layout class [$class] specified for appender [$name]. Reverting to default layout.");
+ return;
+ }
+
+ $layout = new $class();
+ if (!($layout instanceof LoggerLayout)) {
+ $this->warn("Invalid layout class [$class] sepcified for appender [$name]. Reverting to default layout.");
+ return;
+ }
+
+ if (isset($config['params'])) {
+ $this->setOptions($layout, $config['params']);
+ }
+
+ $layout->activateOptions();
+ $appender->setLayout($layout);
+ }
+
+ /**
+ * Parses filter config, creates the filter and adds it to the appender's
+ * filter chain.
+ * @param LoggerAppender $appender
+ * @param array $config Filter configuration.
+ */
+ private function createAppenderFilter(LoggerAppender $appender, $config) {
+ $name = $appender->getName();
+ $class = $config['class'];
+ if (!class_exists($class)) {
+ $this->warn("Nonexistant filter class [$class] specified on appender [$name]. Skipping filter definition.");
+ return;
+ }
+
+ $filter = new $class();
+ if (!($filter instanceof LoggerFilter)) {
+ $this->warn("Invalid filter class [$class] sepcified on appender [$name]. Skipping filter definition.");
+ return;
+ }
+
+ if (isset($config['params'])) {
+ $this->setOptions($filter, $config['params']);
+ }
+
+ $filter->activateOptions();
+ $appender->addFilter($filter);
+ }
+
+ /**
+ * Configures the root logger
+ * @see configureLogger()
+ */
+ private function configureRootLogger(LoggerHierarchy $hierarchy, $config) {
+ $logger = $hierarchy->getRootLogger();
+ $this->configureLogger($logger, $config);
+ }
+
+ /**
+ * Configures a logger which is not root.
+ * @see configureLogger()
+ */
+ private function configureOtherLogger(LoggerHierarchy $hierarchy, $name, $config) {
+ // Get logger from hierarchy (this creates it if it doesn't already exist)
+ $logger = $hierarchy->getLogger($name);
+ $this->configureLogger($logger, $config);
+ }
+
+ /**
+ * Configures a logger.
+ *
+ * @param Logger $logger The logger to configure
+ * @param array $config Logger configuration options.
+ */
+ private function configureLogger(Logger $logger, $config) {
+ $loggerName = $logger->getName();
+
+ // Set logger level
+ if (isset($config['level'])) {
+ $level = LoggerLevel::toLevel($config['level']);
+ if (isset($level)) {
+ $logger->setLevel($level);
+ } else {
+ $default = $logger->getLevel();
+ $this->warn("Invalid level value [{$config['level']}] specified for logger [$loggerName]. Ignoring level definition.");
+ }
+ }
+
+ // Link appenders to logger
+ if (isset($config['appenders'])) {
+ foreach($config['appenders'] as $appenderName) {
+ if (isset($this->appenders[$appenderName])) {
+ $logger->addAppender($this->appenders[$appenderName]);
+ } else {
+ $this->warn("Nonexistnant appender [$appenderName] linked to logger [$loggerName].");
+ }
+ }
+ }
+
+ // Set logger additivity
+ if (isset($config['additivity'])) {
+ $additivity = LoggerOptionConverter::toBoolean($config['additivity'], null);
+ if (is_bool($additivity)) {
+ $logger->setAdditivity($additivity);
+ } else {
+ $this->warn("Invalid additivity value [{$config['additivity']}] specified for logger [$loggerName]. Ignoring additivity setting.");
+ }
+ }
+ }
+
+ /**
+ * Helper method which applies given options to an object which has setters
+ * for these options (such as appenders, layouts, etc.).
+ *
+ * For example, if options are:
+ * <code>
+ * array(
+ * 'file' => '/tmp/myfile.log',
+ * 'append' => true
+ * )
+ * </code>
+ *
+ * This method will call:
+ * <code>
+ * $object->setFile('/tmp/myfile.log')
+ * $object->setAppend(true)
+ * </code>
+ *
+ * If required setters do not exist, it will produce a warning.
+ *
+ * @param mixed $object The object to configure.
+ * @param unknown_type $options
+ */
+ private function setOptions($object, $options) {
+ foreach($options as $name => $value) {
+ $setter = "set$name";
+ if (method_exists($object, $setter)) {
+ $object->$setter($value);
+ } else {
+ $class = get_class($object);
+ $this->warn("Nonexistant option [$name] specified on [$class]. Skipping.");
+ }
+ }
+ }
+
+ /** Helper method to simplify error reporting. */
+ private function warn($message) {
+ trigger_error("log4php: $message", E_USER_WARNING);
+ }
+}
\ No newline at end of file
Modified: logging/log4php/trunk/src/site/xdoc/docs/configuration.xml
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/site/xdoc/docs/configuration.xml?rev=1213710&r1=1213709&r2=1213710&view=diff
==============================================================================
--- logging/log4php/trunk/src/site/xdoc/docs/configuration.xml (original)
+++ logging/log4php/trunk/src/site/xdoc/docs/configuration.xml Tue Dec 13 14:30:50 2011
@@ -203,26 +203,70 @@ array(
<div class="alert-message block-message info">
<p><strong>Hint:</strong> You can fetch the default configuration as a PHP array by running:</p>
- <pre class="prettyprint">LoggerConfigurator::getDefaultConfiguration();</pre>
+ <pre class="prettyprint">LoggerConfiguratorDefault::getDefaultConfiguration();</pre>
</div>
</subsection>
<subsection name="Programmatic configuration">
- <p>It is possible to configure log4php fully programmatically. Here is an example:</p>
+ <p>It is possible to configure log4php fully programmatically. This requires the user to implement
+ their own configurator object. Configurators must implement the <code>LoggerConfigurator</code>
+ interface.</p>
+
+ <p>Here is an example:</p>
<pre class="prettyprint">
+class MyConfigurator implements LoggerConfigurator {
+
+ public function configure(LoggerHierarchy $hierarchy, $input = null) {
+
+ // Create an appender which logs to file
+ $appFile = new LoggerAppenderFile('foo');
+ $appFile->setFile('D:/Temp/log.txt');
+ $appFile->setAppend(true);
+ $appFile->setThreshold('all');
+ $appFile->activateOptions();
+
+ // Use a different layout for the next appender
+ $layout = new LoggerLayoutTTCC();
+ $layout->setContextPrinting(false);
+ $layout->setDateFormat('%Y-%m-%d %H:%M:%S');
+ $layout->activateOptions();
+
+ // Create an appender which echoes log events, using a custom layout
+ // and with the threshold set to INFO
+ $appEcho = new LoggerAppenderEcho('bar');
+ $appEcho->setLayout($layout);
+ $appEcho->setThreshold('info');
+ $appEcho->activateOptions();
+
+ // Add both appenders to the root logger
+ $root = $hierarchy->getRootLogger();
+ $root->addAppender($appFile);
+ $root->addAppender($appEcho);
+ }
+}
+</pre>
+
+ <p>To use the configurator, pass it as a second parameter to <code>Logger::configure()</code>
+ (either the name of the class as a string or an instance).</p>
+<pre class="prettyprint">
+Logger::configure(null, 'MyConfigurator');
+$log = Logger::getRootLogger();
+$log->trace('one');
+$log->debug('two');
+$log->info('three');
+$log->warn('four');
+$log->error('five');
</pre>
<div class="alert-message block-message warn">
- <p>Note that named loggers should always be created by calling Logger::getLogger('name'). This
- will create the logger if it doesn't already exist and place it in the logger hierarchy.</p>
+ <p><strong>Note: </strong>Always call <code>activateOptions()</code> on all appenders, filters and layouts after setting
+ their configuration parameters. Otherwise, the configuration may not be properly activated.</p>
</div>
</subsection>
-
-
</section>
</body>
</document>
Modified: logging/log4php/trunk/src/test/php/LoggerConfiguratorTest.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/test/php/LoggerConfiguratorTest.php?rev=1213710&r1=1213709&r2=1213710&view=diff
==============================================================================
--- logging/log4php/trunk/src/test/php/LoggerConfiguratorTest.php (original)
+++ logging/log4php/trunk/src/test/php/LoggerConfiguratorTest.php Tue Dec 13 14:30:50 2011
@@ -98,7 +98,7 @@
),
);
- $configurator = new LoggerConfigurator();
+ $configurator = new LoggerConfiguratorDefault();
$configurator->configure($hierachyMock, $config);
}
Modified: logging/log4php/trunk/src/test/php/filters/LoggerFilterDenyAllTest.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/test/php/filters/LoggerFilterDenyAllTest.php?rev=1213710&r1=1213709&r2=1213710&view=diff
==============================================================================
--- logging/log4php/trunk/src/test/php/filters/LoggerFilterDenyAllTest.php (original)
+++ logging/log4php/trunk/src/test/php/filters/LoggerFilterDenyAllTest.php Tue Dec 13 14:30:50 2011
@@ -47,7 +47,7 @@ class LoggerFilterDenyAllTest extends PH
}
public function testConfiguration() {
- $config = LoggerConfigurator::getDefaultConfiguration();
+ $config = LoggerConfiguratorDefault::getDefaultConfiguration();
$config['appenders']['default']['filters'] = array(
array(
'class' => 'LoggerFilterDenyAll'