Overview

Packages

  • log4php
    • appenders
    • configurators
    • filters
    • helpers
    • layouts
    • pattern
    • renderers

Classes

  • LoggerConfigurationAdapterINI
  • LoggerConfigurationAdapterPHP
  • LoggerConfigurationAdapterXML

Interfaces

  • LoggerConfigurationAdapter
  • Overview
  • Package
  • Class
  • Tree
  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:  * @package log4php
 19:  */
 20: 
 21: /**
 22:  * Converts ini configuration files to a PHP array.
 23:  * 
 24:  * These used to be called "properties" files (inherited from log4j), and that 
 25:  * file extension is still supported. 
 26:  *
 27:  * @package log4php
 28:  * @subpackage configurators
 29:  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 30:  * @version $Revision: 1343601 $
 31:  * @since 2.2
 32:  */
 33: class LoggerConfigurationAdapterINI implements LoggerConfigurationAdapter {
 34:     
 35:     /** Name to assign to the root logger. */
 36:     const ROOT_LOGGER_NAME = "root";
 37: 
 38:     /** Prefix used for defining logger additivity. */
 39:     const ADDITIVITY_PREFIX = "log4php.additivity.";
 40:     
 41:     /** Prefix used for defining logger threshold. */
 42:     const THRESHOLD_PREFIX = "log4php.threshold";
 43:     
 44:     /** Prefix used for defining the root logger. */
 45:     const ROOT_LOGGER_PREFIX = "log4php.rootLogger";
 46:     
 47:     /** Prefix used for defining a logger. */
 48:     const LOGGER_PREFIX = "log4php.logger.";
 49:     
 50:     /** Prefix used for defining an appender. */
 51:     const APPENDER_PREFIX = "log4php.appender.";
 52:     
 53:     /** Prefix used for defining a renderer. */
 54:     const RENDERER_PREFIX = "log4php.renderer.";
 55:     
 56:     /** Holds the configuration. */
 57:     private $config = array();
 58:     
 59:     /**
 60:      * Loads and parses the INI configuration file.
 61:      * 
 62:      * @param string $url Path to the config file.
 63:      * @throws LoggerException
 64:      */
 65:     private function load($url) {
 66:         if (!file_exists($url)) {
 67:             throw new LoggerException("File [$url] does not exist.");
 68:         }
 69:         
 70:         $properties = @parse_ini_file($url, true);
 71:         if ($properties === false) {
 72:             $error = error_get_last();
 73:             throw new LoggerException("Error parsing configuration file: {$error['message']}");
 74:         }
 75:         
 76:         return $properties;
 77:     }
 78:     
 79:     /**
 80:     * Converts the provided INI configuration file to a PHP array config.
 81:     *
 82:     * @param string $path Path to the config file.
 83:     * @throws LoggerException If the file cannot be loaded or parsed.
 84:     */
 85:     public function convert($path) {
 86:         // Load the configuration
 87:         $properties = $this->load($path);
 88:         
 89:         // Parse threshold
 90:         if (isset($properties[self::THRESHOLD_PREFIX])) {
 91:             $this->config['threshold'] = $properties[self::THRESHOLD_PREFIX]; 
 92:         }
 93:         
 94:         // Parse root logger
 95:         if (isset($properties[self::ROOT_LOGGER_PREFIX])) {
 96:             $this->parseLogger($properties[self::ROOT_LOGGER_PREFIX], self::ROOT_LOGGER_NAME);
 97:         }
 98:         
 99:         $appenders = array();
100:         
101:         foreach($properties as $key => $value) {
102:             // Parse loggers
103:             if ($this->beginsWith($key, self::LOGGER_PREFIX)) {
104:                 $name = substr($key, strlen(self::LOGGER_PREFIX));
105:                 $this->parseLogger($value, $name);
106:             }
107:             
108:             // Parse additivity
109:             if ($this->beginsWith($key, self::ADDITIVITY_PREFIX)) {
110:                 $name = substr($key, strlen(self::ADDITIVITY_PREFIX));
111:                 $this->config['loggers'][$name]['additivity'] = $value;
112:             }
113:             
114:             // Parse appenders
115:             else if ($this->beginsWith($key, self::APPENDER_PREFIX)) {
116:                 $this->parseAppender($key, $value);
117:             }
118:             
119:             // Parse renderers
120:             else if ($this->beginsWith($key, self::RENDERER_PREFIX)) {
121:                 $this->parseRenderer($key, $value);
122:             }
123:         }
124:         
125:         return $this->config;
126:     }
127:     
128:     
129:     /**
130:      * Parses a logger definition.
131:      * 
132:      * Loggers are defined in the following manner:
133:      * <pre>
134:      * log4php.logger.<name> = [<level>], [<appender-ref>, <appender-ref>, ...] 
135:      * </pre>
136:      * 
137:      * @param string $value The configuration value (level and appender-refs).
138:      * @param string $name Logger name. 
139:      */
140:     private function parseLogger($value, $name) {
141:         // Value is divided by commas
142:         $parts = explode(',', $value);
143:         if (empty($value) || empty($parts)) {
144:             return;
145:         }
146: 
147:         // The first value is the logger level 
148:         $level = array_shift($parts);
149:         
150:         // The remaining values are appender references 
151:         $appenders = array();
152:         while($appender = array_shift($parts)) {
153:             $appender = trim($appender);
154:             if (!empty($appender)) {
155:                 $appenders[] = trim($appender);
156:             }
157:         }
158: 
159:         // Find the target configuration 
160:         if ($name == self::ROOT_LOGGER_NAME) {
161:             $this->config['rootLogger']['level'] = trim($level);
162:             $this->config['rootLogger']['appenders'] = $appenders;
163:         } else {
164:             $this->config['loggers'][$name]['level'] = trim($level);
165:             $this->config['loggers'][$name]['appenders'] = $appenders;
166:         }
167:     }
168:     
169:     /**
170:      * Parses an configuration line pertaining to an appender.
171:      * 
172:      * Parses the following patterns:
173:      * 
174:      * Appender class:
175:      * <pre>
176:      * log4php.appender.<name> = <class>
177:      * </pre>
178:      * 
179:      * Appender parameter:
180:      * <pre>
181:      * log4php.appender.<name>.<param> = <value>
182:      * </pre>
183:      * 
184:      * Appender threshold:
185:      * <pre>
186:      * log4php.appender.<name>.threshold = <level>
187:      * </pre>
188:      * 
189:      * Appender layout:
190:      * <pre>
191:      * log4php.appender.<name>.layout = <layoutClass>
192:      * </pre>
193:      * 
194:      * Layout parameter:
195:      * <pre>
196:      * log4php.appender.<name>.layout.<param> = <value>
197:      * </pre> 
198:      * 
199:      * For example, a full appender config might look like:
200:      * <pre>
201:      * log4php.appender.myAppender = LoggerAppenderConsole
202:      * log4php.appender.myAppender.threshold = info
203:      * log4php.appender.myAppender.target = stdout
204:      * log4php.appender.myAppender.layout = LoggerLayoutPattern
205:      * log4php.appender.myAppender.layout.conversionPattern = "%d %c: %m%n"
206:      * </pre>
207:      * 
208:      * After parsing all these options, the following configuration can be 
209:      * found under $this->config['appenders']['myAppender']:
210:      * <pre>
211:      * array(
212:      *  'class' => LoggerAppenderConsole,
213:      *  'threshold' => info,
214:      *  'params' => array(
215:      *      'target' => 'stdout'
216:      *  ),
217:      *  'layout' => array(
218:      *      'class' => 'LoggerAppenderConsole',
219:      *      'params' => array(
220:      *          'conversionPattern' => '%d %c: %m%n'
221:      *      )
222:      *  )
223:      * )
224:      * </pre>
225:      * 
226:      * @param string $key
227:      * @param string $value
228:      */
229:     private function parseAppender($key, $value) {
230: 
231:         // Remove the appender prefix from key
232:         $subKey = substr($key, strlen(self::APPENDER_PREFIX));
233:         
234:         // Divide the string by dots
235:         $parts = explode('.', $subKey);
236:         $count = count($parts);
237:         
238:         // The first part is always the appender name
239:         $name = trim($parts[0]);
240:         
241:         // Only one part - this line defines the appender class 
242:         if ($count == 1) {
243:             $this->config['appenders'][$name]['class'] = $value;
244:             return;
245:         }
246:         
247:         // Two parts - either a parameter, a threshold or layout class
248:         else if ($count == 2) {
249:             
250:             if ($parts[1] == 'layout') {
251:                 $this->config['appenders'][$name]['layout']['class'] = $value;
252:                 return;
253:             } else if ($parts[1] == 'threshold') {
254:                 $this->config['appenders'][$name]['threshold'] = $value;
255:                 return;
256:             } else {
257:                 $this->config['appenders'][$name]['params'][$parts[1]] = $value;
258:                 return;
259:             }
260:         }
261:         
262:         // Three parts - this can only be a layout parameter
263:         else if ($count == 3) {
264:             if ($parts[1] == 'layout') {
265:                 $this->config['appenders'][$name]['layout']['params'][$parts[2]] = $value;
266:                 return;
267:             }
268:         }
269:         
270:         trigger_error("log4php: Don't know how to parse the following line: \"$key = $value\". Skipping.");
271:     }
272: 
273:     /**
274:      * Parses a renderer definition.
275:      * 
276:      * Renderers are defined as:
277:      * <pre>
278:      * log4php.renderer.<renderedClass> = <renderingClass> 
279:      * </pre>
280:      * 
281:      * @param string $key log4php.renderer.<renderedClass>
282:      * @param string $value <renderingClass>
283:      */
284:     private function parseRenderer($key, $value) {
285:         // Remove the appender prefix from key
286:         $renderedClass = substr($key, strlen(self::APPENDER_PREFIX));
287:         $renderingClass = $value;
288:         
289:         $this->config['renderers'][] = compact('renderedClass', 'renderingClass');
290:     }
291:     
292:     /** Helper method. Returns true if $str begins with $sub. */
293:     private function beginsWith($str, $sub) {
294:         return (strncmp($str, $sub, strlen($sub)) == 0);
295:     }
296:     
297:     
298: }
299: 
300: 
Apache log4php API documentation generated by ApiGen 2.8.0