[18220] | 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 | * |
---|
| 19 | * @package log4php |
---|
| 20 | */ |
---|
| 21 | |
---|
| 22 | /** |
---|
| 23 | * @ignore |
---|
| 24 | */ |
---|
| 25 | if (!defined('LOG4PHP_DIR')) define('LOG4PHP_DIR', dirname(__FILE__)); |
---|
| 26 | |
---|
| 27 | /** |
---|
| 28 | */ |
---|
| 29 | require_once(LOG4PHP_DIR . '/LoggerAppender.php'); |
---|
| 30 | require_once(LOG4PHP_DIR . '/LoggerLog.php'); |
---|
| 31 | require_once(LOG4PHP_DIR . '/helpers/LoggerOptionConverter.php'); |
---|
| 32 | |
---|
| 33 | /** |
---|
| 34 | * Abstract superclass of the other appenders in the package. |
---|
| 35 | * |
---|
| 36 | * This class provides the code for common functionality, such as |
---|
| 37 | * support for threshold filtering and support for general filters. |
---|
| 38 | * |
---|
| 39 | * @author Marco Vassura |
---|
| 40 | * @author Sergio Strampelli |
---|
| 41 | * @version $Revision: 635069 $ |
---|
| 42 | * @package log4php |
---|
| 43 | * @abstract |
---|
| 44 | */ |
---|
| 45 | abstract class LoggerAppenderSkeleton extends LoggerAppender { |
---|
| 46 | |
---|
| 47 | /** |
---|
| 48 | * @var boolean closed appender flag |
---|
| 49 | */ |
---|
| 50 | protected $closed = false; |
---|
| 51 | |
---|
| 52 | /** |
---|
| 53 | * @var object unused |
---|
| 54 | */ |
---|
| 55 | protected $errorHandler; |
---|
| 56 | |
---|
| 57 | /** |
---|
| 58 | * The first filter in the filter chain |
---|
| 59 | * @var LoggerFilter |
---|
| 60 | */ |
---|
| 61 | protected $headFilter = null; |
---|
| 62 | |
---|
| 63 | /** |
---|
| 64 | * LoggerLayout for this appender. It can be null if appender has its own layout |
---|
| 65 | * @var LoggerLayout |
---|
| 66 | */ |
---|
| 67 | protected $layout = null; |
---|
| 68 | |
---|
| 69 | /** |
---|
| 70 | * @var string Appender name |
---|
| 71 | */ |
---|
| 72 | protected $name; |
---|
| 73 | |
---|
| 74 | /** |
---|
| 75 | * The last filter in the filter chain |
---|
| 76 | * @var LoggerFilter |
---|
| 77 | */ |
---|
| 78 | protected $tailFilter = null; |
---|
| 79 | |
---|
| 80 | /** |
---|
| 81 | * @var LoggerLevel There is no level threshold filtering by default. |
---|
| 82 | */ |
---|
| 83 | protected $threshold = null; |
---|
| 84 | |
---|
| 85 | /** |
---|
| 86 | * @var boolean needs a layout formatting ? |
---|
| 87 | */ |
---|
| 88 | protected $requiresLayout = false; |
---|
| 89 | |
---|
| 90 | /** |
---|
| 91 | * Constructor |
---|
| 92 | * |
---|
| 93 | * @param string $name appender name |
---|
| 94 | */ |
---|
| 95 | public function __construct($name) { |
---|
| 96 | $this->name = $name; |
---|
| 97 | $this->clearFilters(); |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | /** |
---|
| 101 | * @param LoggerFilter $newFilter add a new LoggerFilter |
---|
| 102 | * @see LoggerAppender::addFilter() |
---|
| 103 | */ |
---|
| 104 | public function addFilter($newFilter) { |
---|
| 105 | if($this->headFilter === null) { |
---|
| 106 | $this->headFilter = $newFilter; |
---|
| 107 | $this->tailFilter = $this->headFilter; |
---|
| 108 | } else { |
---|
| 109 | $this->tailFilter->next = $newFilter; |
---|
| 110 | $this->tailFilter = $this->tailFilter->next; |
---|
| 111 | } |
---|
| 112 | } |
---|
| 113 | |
---|
| 114 | /** |
---|
| 115 | * Derived appenders should override this method if option structure |
---|
| 116 | * requires it. |
---|
| 117 | */ |
---|
| 118 | abstract public function activateOptions(); |
---|
| 119 | |
---|
| 120 | /** |
---|
| 121 | * Subclasses of {@link LoggerAppenderSkeleton} should implement |
---|
| 122 | * this method to perform actual logging. |
---|
| 123 | * |
---|
| 124 | * @param LoggerLoggingEvent $event |
---|
| 125 | * @see doAppend() |
---|
| 126 | * @abstract |
---|
| 127 | */ |
---|
| 128 | abstract protected function append($event); |
---|
| 129 | |
---|
| 130 | /** |
---|
| 131 | * @see LoggerAppender::clearFilters() |
---|
| 132 | */ |
---|
| 133 | public function clearFilters() |
---|
| 134 | { |
---|
| 135 | unset($this->headFilter); |
---|
| 136 | unset($this->tailFilter); |
---|
| 137 | $this->headFilter = null; |
---|
| 138 | $this->tailFilter = null; |
---|
| 139 | } |
---|
| 140 | |
---|
| 141 | /** |
---|
| 142 | * Finalize this appender by calling the derived class' <i>close()</i> method. |
---|
| 143 | */ |
---|
| 144 | public function finalize() |
---|
| 145 | { |
---|
| 146 | // An appender might be closed then garbage collected. There is no |
---|
| 147 | // point in closing twice. |
---|
| 148 | if ($this->closed) return; |
---|
| 149 | |
---|
| 150 | LoggerLog::debug("LoggerAppenderSkeleton::finalize():name=[{$this->name}]."); |
---|
| 151 | |
---|
| 152 | $this->close(); |
---|
| 153 | } |
---|
| 154 | |
---|
| 155 | /** |
---|
| 156 | * Do not use this method. |
---|
| 157 | * @see LoggerAppender::getErrorHandler() |
---|
| 158 | * @return object |
---|
| 159 | */ |
---|
| 160 | public function getErrorHandler() |
---|
| 161 | { |
---|
| 162 | return $this->errorHandler; |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | /** |
---|
| 166 | * @see LoggerAppender::getFilter() |
---|
| 167 | * @return LoggerFilter |
---|
| 168 | */ |
---|
| 169 | public function getFilter() |
---|
| 170 | { |
---|
| 171 | return $this->headFilter; |
---|
| 172 | } |
---|
| 173 | |
---|
| 174 | /** |
---|
| 175 | * Return the first filter in the filter chain for this Appender. |
---|
| 176 | * The return value may be <i>null</i> if no is filter is set. |
---|
| 177 | * @return LoggerFilter |
---|
| 178 | */ |
---|
| 179 | public function getFirstFilter() |
---|
| 180 | { |
---|
| 181 | return $this->headFilter; |
---|
| 182 | } |
---|
| 183 | |
---|
| 184 | /** |
---|
| 185 | * @see LoggerAppender::getLayout() |
---|
| 186 | * @return LoggerLayout |
---|
| 187 | */ |
---|
| 188 | public function getLayout() |
---|
| 189 | { |
---|
| 190 | return $this->layout; |
---|
| 191 | } |
---|
| 192 | |
---|
| 193 | /** |
---|
| 194 | * @see LoggerAppender::getName() |
---|
| 195 | * @return string |
---|
| 196 | */ |
---|
| 197 | public function getName() |
---|
| 198 | { |
---|
| 199 | return $this->name; |
---|
| 200 | } |
---|
| 201 | |
---|
| 202 | /** |
---|
| 203 | * Returns this appenders threshold level. |
---|
| 204 | * See the {@link setThreshold()} method for the meaning of this option. |
---|
| 205 | * @return LoggerLevel |
---|
| 206 | */ |
---|
| 207 | public function getThreshold() |
---|
| 208 | { |
---|
| 209 | return $this->threshold; |
---|
| 210 | } |
---|
| 211 | |
---|
| 212 | /** |
---|
| 213 | * Check whether the message level is below the appender's threshold. |
---|
| 214 | * |
---|
| 215 | * |
---|
| 216 | * If there is no threshold set, then the return value is always <i>true</i>. |
---|
| 217 | * @param LoggerLevel $priority |
---|
| 218 | * @return boolean true if priority is greater or equal than threshold |
---|
| 219 | */ |
---|
| 220 | public function isAsSevereAsThreshold($priority) |
---|
| 221 | { |
---|
| 222 | if ($this->threshold === null) |
---|
| 223 | return true; |
---|
| 224 | |
---|
| 225 | return $priority->isGreaterOrEqual($this->getThreshold()); |
---|
| 226 | } |
---|
| 227 | |
---|
| 228 | /** |
---|
| 229 | * @see LoggerAppender::doAppend() |
---|
| 230 | * @param LoggerLoggingEvent $event |
---|
| 231 | */ |
---|
| 232 | public function doAppend($event) |
---|
| 233 | { |
---|
| 234 | LoggerLog::debug("LoggerAppenderSkeleton::doAppend()"); |
---|
| 235 | |
---|
| 236 | if ($this->closed) { |
---|
| 237 | LoggerLog::debug("LoggerAppenderSkeleton::doAppend() Attempted to append to closed appender named [{$this->name}]."); |
---|
| 238 | return; |
---|
| 239 | } |
---|
| 240 | if(!$this->isAsSevereAsThreshold($event->getLevel())) { |
---|
| 241 | LoggerLog::debug("LoggerAppenderSkeleton::doAppend() event level is less severe than threshold."); |
---|
| 242 | return; |
---|
| 243 | } |
---|
| 244 | |
---|
| 245 | $f = $this->getFirstFilter(); |
---|
| 246 | |
---|
| 247 | while($f !== null) { |
---|
| 248 | switch ($f->decide($event)) { |
---|
| 249 | case LOG4PHP_LOGGER_FILTER_DENY: return; |
---|
| 250 | case LOG4PHP_LOGGER_FILTER_ACCEPT: return $this->append($event); |
---|
| 251 | case LOG4PHP_LOGGER_FILTER_NEUTRAL: $f = $f->getNext(); |
---|
| 252 | } |
---|
| 253 | } |
---|
| 254 | $this->append($event); |
---|
| 255 | } |
---|
| 256 | |
---|
| 257 | |
---|
| 258 | /** |
---|
| 259 | * @see LoggerAppender::requiresLayout() |
---|
| 260 | * @return boolean |
---|
| 261 | */ |
---|
| 262 | public function requiresLayout() |
---|
| 263 | { |
---|
| 264 | return $this->requiresLayout; |
---|
| 265 | } |
---|
| 266 | |
---|
| 267 | /** |
---|
| 268 | * @see LoggerAppender::setErrorHandler() |
---|
| 269 | * @param object |
---|
| 270 | */ |
---|
| 271 | public function setErrorHandler($errorHandler) |
---|
| 272 | { |
---|
| 273 | if($errorHandler == null) { |
---|
| 274 | // We do not throw exception here since the cause is probably a |
---|
| 275 | // bad config file. |
---|
| 276 | LoggerLog::warn("You have tried to set a null error-handler."); |
---|
| 277 | } else { |
---|
| 278 | $this->errorHandler = $errorHandler; |
---|
| 279 | } |
---|
| 280 | } |
---|
| 281 | |
---|
| 282 | /** |
---|
| 283 | * @see LoggerAppender::setLayout() |
---|
| 284 | * @param LoggerLayout $layout |
---|
| 285 | */ |
---|
| 286 | public function setLayout($layout) |
---|
| 287 | { |
---|
| 288 | if ($this->requiresLayout()) |
---|
| 289 | $this->layout = $layout; |
---|
| 290 | } |
---|
| 291 | |
---|
| 292 | /** |
---|
| 293 | * @see LoggerAppender::setName() |
---|
| 294 | * @param string $name |
---|
| 295 | */ |
---|
| 296 | public function setName($name) |
---|
| 297 | { |
---|
| 298 | $this->name = $name; |
---|
| 299 | } |
---|
| 300 | |
---|
| 301 | /** |
---|
| 302 | * Set the threshold level of this appender. |
---|
| 303 | * |
---|
| 304 | * @param mixed $threshold can be a {@link LoggerLevel} object or a string. |
---|
| 305 | * @see LoggerOptionConverter::toLevel() |
---|
| 306 | */ |
---|
| 307 | public function setThreshold($threshold) |
---|
| 308 | { |
---|
| 309 | if (is_string($threshold)) { |
---|
| 310 | $this->threshold = LoggerOptionConverter::toLevel($threshold, null); |
---|
| 311 | }elseif ($threshold instanceof LoggerLevel) { |
---|
| 312 | $this->threshold = $threshold; |
---|
| 313 | } |
---|
| 314 | } |
---|
| 315 | |
---|
| 316 | /** |
---|
| 317 | * Perform actions before object serialization. |
---|
| 318 | * |
---|
| 319 | * Call {@link finalize()} to properly close the appender. |
---|
| 320 | */ |
---|
| 321 | function __sleep() |
---|
| 322 | { |
---|
| 323 | $this->finalize(); |
---|
| 324 | return array_keys(get_object_vars($this)); |
---|
| 325 | } |
---|
| 326 | |
---|
| 327 | /** |
---|
| 328 | * Perform actions after object de-serialization. |
---|
| 329 | * |
---|
| 330 | * Call {@link activateOptions()} to properly setup the appender. |
---|
| 331 | */ |
---|
| 332 | function __wakeup() |
---|
| 333 | { |
---|
| 334 | $this->activateOptions(); |
---|
| 335 | } |
---|
| 336 | |
---|
| 337 | } |
---|