diff --git a/library/log4php/configurators/LoggerConfigurationAdapterINI.php b/library/log4php/configurators/LoggerConfigurationAdapterINI.php new file mode 100644 --- /dev/null +++ b/library/log4php/configurators/LoggerConfigurationAdapterINI.php @@ -0,0 +1,291 @@ +load($path); + + // Parse threshold + if (isset($properties[self::THRESHOLD_PREFIX])) { + $this->config['threshold'] = $properties[self::THRESHOLD_PREFIX]; + } + + // Parse root logger + if (isset($properties[self::ROOT_LOGGER_PREFIX])) { + $this->parseLogger($properties[self::ROOT_LOGGER_PREFIX], self::ROOT_LOGGER_NAME); + } + + $appenders = array(); + + foreach ($properties as $key => $value) { + // Parse loggers + if ($this->beginsWith($key, self::LOGGER_PREFIX)) { + $name = substr($key, strlen(self::LOGGER_PREFIX)); + $this->parseLogger($value, $name); + } + + // Parse additivity + if ($this->beginsWith($key, self::ADDITIVITY_PREFIX)) { + $name = substr($key, strlen(self::ADDITIVITY_PREFIX)); + $this->config['loggers'][$name]['additivity'] = $value; + } // Parse appenders + else if ($this->beginsWith($key, self::APPENDER_PREFIX)) { + $this->parseAppender($key, $value); + } // Parse renderers + else if ($this->beginsWith($key, self::RENDERER_PREFIX)) { + $this->parseRenderer($key, $value); + } + } + + return $this->config; + } + + + /** + * Parses a logger definition. + * + * Loggers are defined in the following manner: + *
+     * log4php.logger. = [], [, , ...]
+     * 
+ * + * @param string $value The configuration value (level and appender-refs). + * @param string $name Logger name. + */ + private function parseLogger($value, $name) { + // Value is divided by commas + $parts = explode(',', $value); + if (empty($value) || empty($parts)) { + return; + } + + // The first value is the logger level + $level = array_shift($parts); + + // The remaining values are appender references + $appenders = array(); + while ($appender = array_shift($parts)) { + $appender = trim($appender); + if (!empty($appender)) { + $appenders[] = trim($appender); + } + } + + // Find the target configuration + if ($name == self::ROOT_LOGGER_NAME) { + $this->config['rootLogger']['level'] = trim($level); + $this->config['rootLogger']['appenders'] = $appenders; + } else { + $this->config['loggers'][$name]['level'] = trim($level); + $this->config['loggers'][$name]['appenders'] = $appenders; + } + } + + /** + * Parses an configuration line pertaining to an appender. + * + * Parses the following patterns: + * + * Appender class: + *
+     * log4php.appender. = 
+     * 
+ * + * Appender parameter: + *
+     * log4php.appender.. = 
+     * 
+ * + * Appender threshold: + *
+     * log4php.appender..threshold = 
+     * 
+ * + * Appender layout: + *
+     * log4php.appender..layout = 
+     * 
+ * + * Layout parameter: + *
+     * log4php.appender..layout. = 
+     * 
+ * + * For example, a full appender config might look like: + *
+     * log4php.appender.myAppender = LoggerAppenderConsole
+     * log4php.appender.myAppender.threshold = info
+     * log4php.appender.myAppender.target = stdout
+     * log4php.appender.myAppender.layout = LoggerLayoutPattern
+     * log4php.appender.myAppender.layout.conversionPattern = "%d %c: %m%n"
+     * 
+ * + * After parsing all these options, the following configuration can be + * found under $this->config['appenders']['myAppender']: + *
+     * array(
+     *    'class' => LoggerAppenderConsole,
+     *    'threshold' => info,
+     *    'params' => array(
+     *        'target' => 'stdout'
+     *    ),
+     *    'layout' => array(
+     *        'class' => 'LoggerAppenderConsole',
+     *        'params' => array(
+     *            'conversionPattern' => '%d %c: %m%n'
+     *        )
+     *    )
+     * )
+     * 
+ * + * @param string $key + * @param string $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]); + + // Only one part - this line defines the appender class + if ($count == 1) { + $this->config['appenders'][$name]['class'] = $value; + return; + } // Two parts - either a parameter, a threshold or layout class + else if ($count == 2) { + + if ($parts[1] == 'layout') { + $this->config['appenders'][$name]['layout']['class'] = $value; + return; + } else if ($parts[1] == 'threshold') { + $this->config['appenders'][$name]['threshold'] = $value; + return; + } else { + $this->config['appenders'][$name]['params'][$parts[1]] = $value; + return; + } + } // Three parts - this can only be a layout parameter + else if ($count == 3) { + if ($parts[1] == 'layout') { + $this->config['appenders'][$name]['layout']['params'][$parts[2]] = $value; + return; + } + } + + trigger_error("log4php: Don't know how to parse the following line: \"$key = $value\". Skipping."); + } + + /** + * Parses a renderer definition. + * + * Renderers are defined as: + *
+     * log4php.renderer. = 
+     * 
+ * + * @param string $key log4php.renderer. + * @param string $value + */ + private function parseRenderer($key, $value) { + // Remove the appender prefix from key + $renderedClass = substr($key, strlen(self::APPENDER_PREFIX)); + $renderingClass = $value; + + $this->config['renderers'][] = compact('renderedClass', 'renderingClass'); + } + + /** Helper method. Returns true if $str begins with $sub. */ + private function beginsWith($str, $sub) { + return (strncmp($str, $sub, strlen($sub)) == 0); + } + + +} +