Return-Path: X-Original-To: apmail-logging-log4php-dev-archive@www.apache.org Delivered-To: apmail-logging-log4php-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 015DC7914 for ; Thu, 25 Aug 2011 06:46:41 +0000 (UTC) Received: (qmail 47413 invoked by uid 500); 25 Aug 2011 06:46:36 -0000 Delivered-To: apmail-logging-log4php-dev-archive@logging.apache.org Received: (qmail 47346 invoked by uid 500); 25 Aug 2011 06:46:24 -0000 Mailing-List: contact log4php-dev-help@logging.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Log4PHP Dev" List-Id: Delivered-To: mailing list log4php-dev@logging.apache.org Received: (qmail 47339 invoked by uid 500); 25 Aug 2011 06:46:21 -0000 Delivered-To: apmail-logging-log4php-cvs@logging.apache.org Received: (qmail 47333 invoked by uid 99); 25 Aug 2011 06:46:19 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 25 Aug 2011 06:46:19 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 25 Aug 2011 06:46:15 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id AF29423889B3; Thu, 25 Aug 2011 06:45:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1161411 - in /logging/log4php/branches/experimental/config-adapters/src/main/php: ./ configurators/ xml/ Date: Thu, 25 Aug 2011 06:45:55 -0000 To: log4php-cvs@logging.apache.org From: ihabunek@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110825064555.AF29423889B3@eris.apache.org> Author: ihabunek Date: Thu Aug 25 06:45:54 2011 New Revision: 1161411 URL: http://svn.apache.org/viewvc?rev=1161411&view=rev Log: Initial work on config adapters. Added: logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd Removed: logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorBasic.php logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorIni.php logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorPhp.php logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorXml.php Modified: logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd Modified: logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php URL: http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php?rev=1161411&r1=1161410&r2=1161411&view=diff ============================================================================== --- logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php (original) +++ logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php Thu Aug 25 06:45:54 2011 @@ -53,11 +53,10 @@ class Logger { 'LoggerMDC' => '/LoggerMDC.php', 'LoggerNDC' => '/LoggerNDC.php', 'LoggerReflectionUtils' => '/LoggerReflectionUtils.php', - 'LoggerConfigurator' => '/LoggerConfigurator.php', - 'LoggerConfiguratorBasic' => '/configurators/LoggerConfiguratorBasic.php', - 'LoggerConfiguratorIni' => '/configurators/LoggerConfiguratorIni.php', - 'LoggerConfiguratorPhp' => '/configurators/LoggerConfiguratorPhp.php', - 'LoggerConfiguratorXml' => '/configurators/LoggerConfiguratorXml.php', + 'LoggerConfigurator' => '/configurators/LoggerConfigurator.php', + 'LoggerConfigurationAdapter' => '/configurators/LoggerConfigurationAdapter.php', + 'LoggerConfigurationAdapterINI' => '/configurators/LoggerConfigurationAdapterINI.php', + 'LoggerConfigurationAdapterXML' => '/configurators/LoggerConfigurationAdapterXML.php', 'LoggerRoot' => '/LoggerRoot.php', 'LoggerAppender' => '/LoggerAppender.php', 'LoggerAppenderPool' => '/LoggerAppenderPool.php', @@ -154,17 +153,7 @@ class Logger { /** The logger hierarchy used by log4php. */ private static $hierarchy; - /** - * Name of the configurator class used to configure log4php. - * Populated by {@link configure()} and used in {@link initialize()}. - */ - private static $configurationClass = 'LoggerConfiguratorBasic'; - - /** - * Path to the configuration file which may be used by the configurator. - * Populated by {@link configure()} and used in {@link initialize()}. - */ - private static $configurationFile; + private static $configurator; /** Inidicates if log4php has been initialized */ private static $initialized = false; @@ -564,7 +553,7 @@ class Logger { } /** - * Configures log4php by defining a configuration file and/or class. + * Configures log4php. * * This method needs to be called before the first logging event has * occured. If this method is not called before then, the standard @@ -581,25 +570,12 @@ class Logger { * @param string $configurationFile path to the configuration file * @param string $configurationClass name of the custom configurator class */ - public static function configure($configurationFile = null, $configurationClass = null ) { - if($configurationClass === null && $configurationFile === null) { - self::$configurationClass = 'LoggerConfiguratorBasic'; - return; - } - - if($configurationClass !== null) { - self::$configurationFile = $configurationFile; - self::$configurationClass = $configurationClass; - return; + public static function configure($configuration) { + if (!isset(self::$configurator)) { + self::$configurator = new LoggerConfigurator(); } - if (strtolower(substr( $configurationFile, -4 )) == '.xml') { - self::$configurationFile = $configurationFile; - self::$configurationClass = 'LoggerConfiguratorXml'; - } else { - self::$configurationFile = $configurationFile; - self::$configurationClass = 'LoggerConfiguratorIni'; - } + self::$configurator->configure(self::getHierarchy(), $configuration); } /** Added: logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php URL: http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php?rev=1161411&view=auto ============================================================================== --- logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php (added) +++ logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php Thu Aug 25 06:45:54 2011 @@ -0,0 +1,10 @@ + \ No newline at end of file Added: logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php URL: http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php?rev=1161411&view=auto ============================================================================== --- logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php (added) +++ logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php Thu Aug 25 06:45:54 2011 @@ -0,0 +1,247 @@ +properties = $properties; + } + + /** + * Converts the provided INI configuration file to a PHP array config. + * + * @param string $path Path to the config file. + * @throws LoggerException If the file cannot be loaded or parsed. + */ + public function convert($path) { + // Load the configuration + $this->load($path); + + // Parse threshold + if (isset($this->properties[self::THRESHOLD_PREFIX])) { + $this->config['threshold'] = $this->properties[self::THRESHOLD_PREFIX]; + } + + // Parse root logger + if (isset($this->properties[self::ROOT_LOGGER_PREFIX])) { + $this->parseLogger($this->properties[self::ROOT_LOGGER_PREFIX], self::ROOT_LOGGER_NAME); + } + + $appenders = array(); + + foreach($this->properties as $key => $value) { + // Parse loggers + if ($this->beginsWith($key, self::LOGGER_PREFIX)) { + $name = substr($key, strlen(self::LOGGER_PREFIX)); + $this->parseLogger($property, $name); + } + + // Parse appenders + else if ($this->beginsWith($key, self::APPENDER_PREFIX)) { + $this->parseAppender($key, $value); + } + } + + } + + + /** + * Parses a logger property. + * + * Loggers are defined in the following manner: + *
+	 * log4php.logger. = [], [, , ...] 
+	 * 
+ * + * Where: + * - level - level to assign to the logger (optional) + * - appender-ref - name of the appenders to attach to the logger (optional) + * + * @param string $property + * @param string $loggerName + */ + private function parseLogger($property, $loggerName) { + // Values are divided by commas + $values = explode(',', $property); + + if (empty($property) || empty($values)) { + return; + } + + // The first value is the logger level + $level = array_shift($values); + + // The remaining values are appender references + $appenders = array(); + while($appender = array_shift($values)) { + $appender = trim($appender); + if (!empty($appender)) { + $appenders[] = trim($appender); + } + } + + $config = array( + 'level' => trim($level), + 'appenders' => $appenders + ); + + if ($loggerName == self::ROOT_LOGGER_NAME) { + $this->config['rootLogger'] = $config; + } else { + $this->config['loggers'][$loggerName] = $config; + } + } + + + /** + * Parses an appender. + * + * Appenders are defined: + *
+	 * log4php.appender. = 
+	 * log4php.appender.. = 
+	 * 
+ * + * Appender layout is defined: + *
+	 * log4php.appender..layout = 
+	 * log4php.appender..layout. = 
+	 * 
+ * + * Legend: + * - appender - name of the appender + * - class - the appender class to use + * - param - name of a configurable parameter + * - value - value of the configurable parameter + * + * For example, a full appender config might look like: + *
+	 * log4php.appender.myAppender = LoggerAppenderConsole
+	 * log4php.appender.myAppender.target = STDOUT
+	 * log4php.appender.myAppender.layout = LoggerLayoutSimple
+	 * 
+ * + * @param unknown_type $key + * @param unknown_type $value + */ + private function parseAppender($key, $value) { + + // Remove the appender prefix from key + $subKey = substr($key, strlen(self::APPENDER_PREFIX)); + + // Divide the string by dots + $parts = explode('.', $subKey); + $count = count($parts); + + // The first part is always the appender name + $name = trim($parts[0]); + + // No dots in key - this line defines the appender class + if ($count == 1) { + $name = trim($parts[0]); + $this->config['appenders'][$name]['class'] = $value; + } + + // Dot(s) in key - this line defines an appender property. + else { + + // Layouts may have their own properties + if ($parts[0] == 'layout') { + + + } + + + + } + + // No dot in key - this is the appender class + if (!strpos($appenderKey, '.')) { + + } + + // Dot in key - this is an appender property. + else { + + } + + + + + // Remove the appender prefix from key to get name + $appenderName = substr($key, strlen(self::APPENDER_PREFIX)); + + if (strpos($appenderName, '.')) { + return; + } + + $appender = array( + 'class' => $value + ); + + // Iterate over params and search for params linked to this appender + foreach($this->properties as $pKey => $pValue) { + + // Detect layout + if($pKey == $appenderName . '.layout') { + $layout = $this->parseLayout($pKey, $pValue); + } + + // Detect other parameters + else if ($this->beginsWith($pKey, $key) && $pKey != $key) { + $paramName = substr($pKey, strlen($key) + 1); + $appender[$paramName] = $pValue; + } + } + + $this->config['appenders'][$appenderName] = $appender; + + + } + + private function beginsWith($str, $sub) { + return (strncmp($str, $sub, strlen($sub)) == 0); + } + + +} + +?> \ No newline at end of file Added: logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php URL: http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php?rev=1161411&view=auto ============================================================================== --- logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php (added) +++ logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php Thu Aug 25 06:45:54 2011 @@ -0,0 +1,34 @@ + \ No newline at end of file Added: logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php URL: http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php?rev=1161411&view=auto ============================================================================== --- logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php (added) +++ logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php Thu Aug 25 06:45:54 2011 @@ -0,0 +1,247 @@ + array(), + 'loggers' => array(), + 'renderers' => array(), + ); + + public function convert($url) + { + $xml = $this->loadXML($url); + + $this->parseConfiguration($xml); + + // Parse the node + if (isset($xml->root)) { + $this->parseRootLogger($xml->root); + } + + // Process nodes + foreach($xml->logger as $logger) { + $this->parseLogger($logger); + } + + // Process nodes + foreach($xml->appender as $appender) { + $this->parseAppender($appender); + } + + // Process nodes + foreach($xml->renderer as $rendererNode) { + $this->parseRenderer($rendererNode); + } + + return $this->config; + } + + /** + * Loads and validates the XML. + * @param string $url Input XML. + */ + private function loadXML($url) { + + // Load the config file + $config = @file_get_contents($url); + if ($config === false) { + $error = error_get_last(); + throw new LoggerException("Cannot load config file: {$error['message']}"); + } + + // Validate XML against schema + $internal = libxml_use_internal_errors(true); + + $this->validateXML($config); + + libxml_clear_errors(); + libxml_use_internal_errors($internal); + + // Load XML + $xml = simplexml_load_string($config); + if ($xml === false) { + throw new LoggerException("Failed parsing XML configuration file."); + } + return $xml; + } + + /** + * DOMDocument is used here for validation because SimpleXML doesn't + * implement this feature. + * @param string $input The configuration XML. + */ + private function validateXML($url) { + $schema = dirname(__FILE__) . self::SCHEMA_PATH; + try { + $dom = new DOMDocument(); + $dom->loadXML($url); + } catch(Exception $e) { + throw new LoggerException("Failed parsing XML configuration file."); + } + + $success = $dom->schemaValidate($schema); + if ($success === false) { + $errors = libxml_get_errors(); + foreach($errors as $error) { + $message = trim($error->message) . " On line {$error->line} of the configuration file."; + $this->warn($message); + } + throw new LoggerException("The XML configuration file failed validation."); + } + } + + /** + * Parses the node. + */ + private function parseConfiguration(SimpleXMLElement $xml) { + $attributes = $xml->attributes(); + if (isset($attributes['threshold'])) { + $this->config['threshold'] = (string) $attributes['threshold']; + } + } + + /** Parses an node. */ + private function parseAppender(SimpleXMLElement $node) { + $name = $this->getAttributeValue($node, 'name'); + + $appender = array(); + $appender['class'] = $this->getAttributeValue($node, 'class'); + + $attrs = $node->attributes(); + if (isset($attrs['threshold'])) { + $appender['threshold'] = (string) $attrs['threshold']; + } + + if (isset($node->layout)) { + $appender['layout']= $this->parseLayout($node->layout, $name); + } + + if (count($node->param) > 0) { + $appender['params'] = $this->parseParameters($node); + } + + foreach($node->filter as $filterNode) { + $appender['filters'][] = $this->parseFilter($filterNode); + } + + $this->config['appenders'][$name] = $appender; + } + + /** Parses a node. */ + private function parseLayout(SimpleXMLElement $node, $appenderName) { + $layout = array(); + $layout['class'] = $this->getAttributeValue($node, 'class'); + + if (count($node->param) > 0) { + $layout['params'] = $this->parseParameters($node); + } + + return $layout; + } + /** Parses any child nodes returning them in an array. */ + private function parseParameters($node) { + $params = array(); + + foreach($node->param as $paramNode) { + $attrs = $paramNode->attributes(); + $name = (string) $attrs['name']; + $value = (string) $attrs['value']; + + $params[$name] = $value; + } + + return $params; + } + + /** Parses a node. */ + private function parseRootLogger(SimpleXMLElement $node) { + $logger = array(); + + var_dump($node->level['value']); + + if (isset($node->level)) { + $logger['level'] = $this->getAttributeValue($node->level, 'value'); + } + + $logger['appenders'] = array(); + foreach($node->appender_ref as $appender) { + $logger['appenders'][] = $this->getAttributeValue($appender, 'ref'); + } + + $this->config['rootLogger'] = $logger; + } + + /** Parses a node. */ + private function parseLogger(SimpleXMLElement $node) { + $logger = array(); + $attributes = $node->attributes(); + + $name = (string) $attributes['name']; + + if (isset($node->level)) { + $logger['level'] = $this->getAttributeValue($node->level, 'value'); + } + + $logger['appenders'] = $this->parseAppenderReferences($node, $name); + + if (isset($this->config['loggers'][$name])) { + $this->warn("Duplicate logger definition for $name. Overwriting."); + } + + $this->config['loggers'][$name] = $logger; + } + + /** + * Parses a node for appender references and returns them in an array. + */ + private function parseAppenderReferences(SimpleXMLElement $node, $name) { + $refs = array(); + foreach($node->appender_ref as $ref) { + $refs[] = $this->getAttributeValue($ref, 'ref'); + } + + return $refs; + } + + private function parseFilter($filterNode) { + $filter = array(); + $filter['class'] = $this->getAttributeValue($filterNode, 'class'); + + if (count($filterNode->param) > 0) { + $filter['params'] = $this->parseParameters($filterNode); + } + + return $filter; + } + + /** Parses a node. */ + private function parseRenderer(SimpleXMLElement $node) { + $renderedClass = $this->getAttributeValue($node, 'renderedClass'); + $renderingClass = $this->getAttributeValue($node, 'renderingClass'); + + $this->config['renderers'][] = compact('renderedClass', 'renderingClass'); + } + + // ****************************************** + // ** Helper methods ** + // ****************************************** + + private function getAttributeValue(SimpleXMLElement $node, $name) { + $attrs = $node->attributes(); + return isset($attrs[$name]) ? (string) $attrs[$name] : null; + } + + private function warn($message) { + trigger_error("log4php: " . $message, E_USER_WARNING); + } + +} + +?> \ No newline at end of file Modified: logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd URL: http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd?rev=1161411&r1=1161410&r2=1161411&view=diff ============================================================================== --- logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd (original) +++ logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd Thu Aug 25 06:45:54 2011 @@ -46,7 +46,7 @@ element. --> @@ -64,7 +64,7 @@ element. --> - + - + - - + - + @@ -121,7 +121,7 @@ element. --> Added: logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd URL: http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd?rev=1161411&view=auto ============================================================================== --- logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd (added) +++ logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd Thu Aug 25 06:45:54 2011 @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +