MonologFileLogger.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2015 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\core\impl;
12 
16 use Monolog\Logger;
21 
22 /**
23  * MonologFileLogger is a wrapper for the Monolog library that logs to files.
24  *
25  * Loggers may be configured by passing configuration file name to the first
26  * created logger instance. The file must have INI file format. The following
27  * sectiona are supported:
28  * - _Root_:
29  * - _level_: default log level
30  * - _target_: location of rotating log files relative to WCMF_BASE or stream resource e.g. php://stdout
31  * - _Logger_: Keys are the logger names, values the levels (_DEBUG_, _WARN_, ...)
32  *
33  * @author ingo herwig <ingo@wemove.com>
34  */
36 
37  const ROOT_SECTION_NAME = 'Root';
38  const LOGGER_SECTION_NAME = 'Logger';
39 
40  private $_monologLogger = null;
41  private $_level = Logger::ERROR;
42 
43  private static $_defaultLevel = Logger::ERROR;
44  private static $_logTarget = '';
45  private static $_levels = array();
46 
47  /**
48  * Constructor
49  * @param $name The logger name (channel in Monolog)
50  * @param $configFile A configuration file name
51  */
52  public function __construct($name, $configFile='') {
53  if (strlen($configFile) > 0) {
54  self::configure($configFile);
55  if (!$this->isStreamTarget(self::$_logTarget)) {
56  $fileUtil = new FileUtil();
57  self::$_logTarget = $fileUtil->realpath(WCMF_BASE.self::$_logTarget).'/';
58  $fileUtil->mkdirRec(self::$_logTarget);
59  }
60  }
61  $level = isset(self::$_levels[$name]) ? self::$_levels[$name] : self::$_defaultLevel;
62  $this->_level = $level;
63 
64  $output = "[%datetime%] %level_name%: %channel%:%extra.line%: %message%\n";
65  $formatter = new LineFormatter($output, null, true);
66  $processor = new IntrospectionProcessor($level, array(__CLASS__));
67  if ($this->isStreamTarget(self::$_logTarget)) {
68  $handler = new StreamHandler(self::$_logTarget, $level);
69  }
70  else {
71  $handler = new RotatingFileHandler(self::$_logTarget.'.log', 0, $level);
72  $handler->setFilenameFormat('{date}', 'Y-m-d');
73  }
74  $handler->setFormatter($formatter);
75  $handler->pushProcessor($processor);
76 
77  $this->_monologLogger = new Logger($name, array($handler));
78  }
79 
80  /**
81  * @see Logger::debug()
82  */
83  public function debug($message) {
84  $this->_monologLogger->addDebug($this->prepareMessage($message));
85  }
86 
87  /**
88  * @see Logger::info()
89  */
90  public function info($message) {
91  $this->_monologLogger->addInfo($this->prepareMessage($message));
92  }
93 
94  /**
95  * @see Logger::warn()
96  */
97  public function warn($message) {
98  $this->_monologLogger->addWarning($this->prepareMessage($message));
99  }
100 
101  /**
102  * @see Logger::error()
103  */
104  public function error($message) {
105  $this->_monologLogger->addError($this->prepareMessage($message));
106  }
107 
108  /**
109  * @see Logger::fatal()
110  */
111  public function fatal($message) {
112  $this->_monologLogger->addCritical($this->prepareMessage($message));
113  }
114 
115  /**
116  * @see Logger::isDebugEnabled()
117  */
118  public function isDebugEnabled() {
119  return $this->_level <= Logger::DEBUG;
120  }
121 
122  /**
123  * @see Logger::isInfoEnabled()
124  */
125  public function isInfoEnabled() {
126  return $this->_level <= Logger::INFO;
127  }
128 
129  /**
130  * @see Logger::isWarnEnabled()
131  */
132  public function isWarnEnabled() {
133  return $this->_level <= Logger::WARNING;
134  }
135 
136  /**
137  * @see Logger::isErrorEnabled()
138  */
139  public function isErrorEnabled() {
140  return $this->_level <= Logger::ERROR;
141  }
142 
143  /**
144  * @see Logger::isFatalEnabled()
145  */
146  public function isFatalEnabled() {
147  return $this->_level <= Logger::CRITICAL;
148  }
149 
150  /**
151  * @see Logger::getLogger()
152  */
153  public static function getLogger($name) {
154  return new MonologFileLogger($name);
155  }
156 
157  /**
158  * Configure logging
159  * @param $configFile
160  */
161  private function configure($configFile) {
162  if (!file_exists($configFile)) {
163  throw new ConfigurationException('Configuration file '.$configFile.' not found');
164  }
165  $config = parse_ini_file($configFile, true);
166 
167  // default settings
168  if (isset($config[self::ROOT_SECTION_NAME])) {
169  $rootConfig = $config[self::ROOT_SECTION_NAME];
170  self::$_defaultLevel = isset($rootConfig['level']) ?
171  constant('Monolog\Logger::'.strtoupper($rootConfig['level'])) :
172  self::$_defaultLevel;
173  self::$_logTarget = isset($rootConfig['target']) ?
174  $rootConfig['target'] : WCMF_BASE.self::$_logTarget;
175  }
176 
177  // log levels
178  self::$_levels = isset($config[self::LOGGER_SECTION_NAME]) ?
179  $config[self::LOGGER_SECTION_NAME] : array();
180  foreach (self::$_levels as $key => $val) {
181  self::$_levels[$key] = constant('Monolog\Logger::'.strtoupper($val));
182  }
183  }
184 
185  /**
186  * Prepare a message to be used with the internal logger
187  * @param $message
188  * @return String
189  */
190  private function prepareMessage($message) {
191  return is_string($message) ? $message : StringUtil::getDump($message);
192  }
193 
194  /**
195  * Check if the given target is a stream resource
196  * @param $target
197  * @return Boolean
198  */
199  private function isStreamTarget($target) {
200  return preg_match('/^.+?:\/\//', $target);
201  }
202 }
203 ?>
__construct($name, $configFile='')
Constructor.
Interface for logger implementations.
Definition: Logger.php:18
FileUtil provides basic support for file functionality like HTTP file upload.
Definition: FileUtil.php:22
MonologFileLogger is a wrapper for the Monolog library that logs to files.
ConfigurationException signals an exception in the configuration.
static getDump($var)
Get the dump of a variable as string.
Definition: StringUtil.php:25