PageRenderTime 66ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/log4php/Logger.php

https://github.com/ehutson/log4php
PHP | 619 lines | 252 code | 66 blank | 301 comment | 21 complexity | d5d83e19baca32609195fe4a5528dad4 MD5 | raw file
  1. <?php
  2. namespace log4php;
  3. /**
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership.
  7. * The ASF licenses this file to You under the Apache License, Version 2.0
  8. * (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @package log4php
  20. */
  21. /**
  22. * This is the central class in the log4php package. All logging operations
  23. * are done through this class.
  24. *
  25. * The main logging methods are:
  26. * <ul>
  27. * <li>{@link trace()}</li>
  28. * <li>{@link debug()}</li>
  29. * <li>{@link info()}</li>
  30. * <li>{@link warn()}</li>
  31. * <li>{@link error()}</li>
  32. * <li>{@link fatal()}</li>
  33. * </ul>
  34. *
  35. * @package log4php
  36. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  37. * @version SVN: $Id: Logger.php 1241439 2012-02-07 12:17:21Z ihabunek $
  38. * @link http://logging.apache.org/log4php
  39. */
  40. class Logger
  41. {
  42. /**
  43. * Logger additivity. If set to true then child loggers will inherit
  44. * the appenders of their ancestors by default.
  45. * @var boolean
  46. */
  47. private $additive = true;
  48. /**
  49. * The Logger's fully qualified class name.
  50. * TODO: Determine if this is useful.
  51. */
  52. private $fqcn = 'Logger';
  53. /** The assigned Logger level. */
  54. private $level;
  55. /** The name of this Logger instance. */
  56. private $name;
  57. /** The parent logger. Set to null if this is the root logger. */
  58. private $parent;
  59. /** A collection of appenders linked to this logger. */
  60. private $appenders = array();
  61. /**
  62. * Constructor.
  63. * @param string $name Name of the logger.
  64. */
  65. public function __construct($name)
  66. {
  67. $this->name = $name;
  68. }
  69. /**
  70. * Returns the logger name.
  71. * @return string
  72. */
  73. public function getName()
  74. {
  75. return $this->name;
  76. }
  77. /**
  78. * Returns the parent Logger. Can be null if this is the root logger.
  79. * @return Logger
  80. */
  81. public function getParent()
  82. {
  83. return $this->parent;
  84. }
  85. // ******************************************
  86. // *** Logging methods ***
  87. // ******************************************
  88. /**
  89. * Log a message object with the TRACE level.
  90. *
  91. * @param mixed $message message
  92. * @param Exception $throwable Optional throwable information to include
  93. * in the logging event.
  94. */
  95. public function trace($message, $throwable = null)
  96. {
  97. $this->log(LoggerLevel::getLevelTrace(), $message, $throwable);
  98. }
  99. /**
  100. * Log a message object with the DEBUG level.
  101. *
  102. * @param mixed $message message
  103. * @param Exception $throwable Optional throwable information to include
  104. * in the logging event.
  105. */
  106. public function debug($message, $throwable = null)
  107. {
  108. $this->log(LoggerLevel::getLevelDebug(), $message, $throwable);
  109. }
  110. /**
  111. * Log a message object with the INFO Level.
  112. *
  113. * @param mixed $message message
  114. * @param Exception $throwable Optional throwable information to include
  115. * in the logging event.
  116. */
  117. public function info($message, $throwable = null)
  118. {
  119. $this->log(LoggerLevel::getLevelInfo(), $message, $throwable);
  120. }
  121. /**
  122. * Log a message with the WARN level.
  123. *
  124. * @param mixed $message message
  125. * @param Exception $throwable Optional throwable information to include
  126. * in the logging event.
  127. */
  128. public function warn($message, $throwable = null)
  129. {
  130. $this->log(LoggerLevel::getLevelWarn(), $message, $throwable);
  131. }
  132. /**
  133. * Log a message object with the ERROR level.
  134. *
  135. * @param mixed $message message
  136. * @param Exception $throwable Optional throwable information to include
  137. * in the logging event.
  138. */
  139. public function error($message, $throwable = null)
  140. {
  141. $this->log(LoggerLevel::getLevelError(), $message, $throwable);
  142. }
  143. /**
  144. * Log a message object with the FATAL level.
  145. *
  146. * @param mixed $message message
  147. * @param Exception $throwable Optional throwable information to include
  148. * in the logging event.
  149. */
  150. public function fatal($message, $throwable = null)
  151. {
  152. $this->log(LoggerLevel::getLevelFatal(), $message, $throwable);
  153. }
  154. /**
  155. * Log a message using the provided logging level.
  156. *
  157. * @param LoggerLevel $level The logging level.
  158. * @param mixed $message Message to log.
  159. * @param Exception $throwable Optional throwable information to include
  160. * in the logging event.
  161. */
  162. public function log(LoggerLevel $level, $message, $throwable = null)
  163. {
  164. if ($this->isEnabledFor($level)) {
  165. $this->forcedLog($this->fqcn, $throwable, $level, $message);
  166. }
  167. }
  168. /**
  169. * If assertion parameter evaluates as false, then logs the message
  170. * using the ERROR level.
  171. *
  172. * @param bool $assertion
  173. * @param string $msg message to log
  174. */
  175. public function assertLog($assertion = true, $msg = '')
  176. {
  177. if ($assertion == false) {
  178. $this->error($msg);
  179. }
  180. }
  181. /**
  182. * This method creates a new logging event and logs the event without
  183. * further checks.
  184. *
  185. * It should not be called directly. Use {@link trace()}, {@link debug()},
  186. * {@link info()}, {@link warn()}, {@link error()} and {@link fatal()}
  187. * wrappers.
  188. *
  189. * @param string $fqcn Fully qualified class name of the Logger
  190. * @param Exception $throwable Optional throwable information to include
  191. * in the logging event.
  192. * @param LoggerLevel $level log level
  193. * @param mixed $message message to log
  194. */
  195. public function forcedLog($fqcn, $throwable, LoggerLevel $level, $message)
  196. {
  197. if (!($throwable instanceof \Exception)) {
  198. $throwable = null;
  199. }
  200. $this->callAppenders(new LoggerLoggingEvent($fqcn, $this, $level, $message, null, $throwable));
  201. }
  202. // ******************************************
  203. // *** Checker methods ***
  204. // ******************************************
  205. /**
  206. * Check whether this Logger is enabled for a given Level passed as parameter.
  207. *
  208. * @param LoggerLevel level
  209. * @return boolean
  210. */
  211. public function isEnabledFor(LoggerLevel $level)
  212. {
  213. return $level->isGreaterOrEqual($this->getEffectiveLevel());
  214. }
  215. /**
  216. * Check whether this Logger is enabled for the TRACE Level.
  217. * @return boolean
  218. */
  219. public function isTraceEnabled()
  220. {
  221. return $this->isEnabledFor(LoggerLevel::getLevelTrace());
  222. }
  223. /**
  224. * Check whether this Logger is enabled for the DEBUG Level.
  225. * @return boolean
  226. */
  227. public function isDebugEnabled()
  228. {
  229. return $this->isEnabledFor(LoggerLevel::getLevelDebug());
  230. }
  231. /**
  232. * Check whether this Logger is enabled for the INFO Level.
  233. * @return boolean
  234. */
  235. public function isInfoEnabled()
  236. {
  237. return $this->isEnabledFor(LoggerLevel::getLevelInfo());
  238. }
  239. /**
  240. * Check whether this Logger is enabled for the WARN Level.
  241. * @return boolean
  242. */
  243. public function isWarnEnabled()
  244. {
  245. return $this->isEnabledFor(LoggerLevel::getLevelWarn());
  246. }
  247. /**
  248. * Check whether this Logger is enabled for the ERROR Level.
  249. * @return boolean
  250. */
  251. public function isErrorEnabled()
  252. {
  253. return $this->isEnabledFor(LoggerLevel::getLevelError());
  254. }
  255. /**
  256. * Check whether this Logger is enabled for the FATAL Level.
  257. * @return boolean
  258. */
  259. public function isFatalEnabled()
  260. {
  261. return $this->isEnabledFor(LoggerLevel::getLevelFatal());
  262. }
  263. // ******************************************
  264. // *** Configuration methods ***
  265. // ******************************************
  266. /**
  267. * Adds a new appender to the Logger.
  268. * @param LoggerAppender $appender The appender to add.
  269. */
  270. public function addAppender($appender)
  271. {
  272. $appenderName = $appender->getName();
  273. $this->appenders[$appenderName] = $appender;
  274. }
  275. /** Removes all appenders from the Logger. */
  276. public function removeAllAppenders()
  277. {
  278. foreach ($this->appenders as $name => $appender) {
  279. $this->removeAppender($name);
  280. }
  281. }
  282. /**
  283. * Remove the appender passed as parameter form the Logger.
  284. * @param mixed $appender an appender name or a {@link LoggerAppender} instance.
  285. */
  286. public function removeAppender($appender)
  287. {
  288. if ($appender instanceof LoggerAppender) {
  289. $appender->close();
  290. unset($this->appenders[$appender->getName()]);
  291. } else if (is_string($appender) and isset($this->appenders[$appender])) {
  292. $this->appenders[$appender]->close();
  293. unset($this->appenders[$appender]);
  294. }
  295. }
  296. /**
  297. * Forwards the given logging event to all linked appenders.
  298. * @param LoggerLoggingEvent $event
  299. */
  300. public function callAppenders($event)
  301. {
  302. // Forward the event to each linked appender
  303. foreach ($this->appenders as $appender) {
  304. $appender->doAppend($event);
  305. }
  306. // Forward the event upstream if additivity is turned on
  307. if (isset($this->parent) && $this->getAdditivity()) {
  308. $this->parent->callAppenders($event);
  309. }
  310. }
  311. /**
  312. * Returns the appenders linked to this logger as an array.
  313. * @return array collection of appender names
  314. */
  315. public function getAllAppenders()
  316. {
  317. return $this->appenders;
  318. }
  319. /**
  320. * Returns a linked appender by name.
  321. * @return LoggerAppender
  322. */
  323. public function getAppender($name)
  324. {
  325. return $this->appenders[$name];
  326. }
  327. /**
  328. * Sets the additivity flag.
  329. * @param boolean $additive
  330. */
  331. public function setAdditivity($additive)
  332. {
  333. $this->additive = (bool) $additive;
  334. }
  335. /**
  336. * Returns the additivity flag.
  337. * @return boolean
  338. */
  339. public function getAdditivity()
  340. {
  341. return $this->additive;
  342. }
  343. /**
  344. * Starting from this Logger, search the Logger hierarchy for a non-null level and return it.
  345. * @see LoggerLevel
  346. * @return LoggerLevel or null
  347. */
  348. public function getEffectiveLevel()
  349. {
  350. for ($logger = $this; $logger !== null; $logger = $logger->getParent()) {
  351. if ($logger->getLevel() !== null) {
  352. return $logger->getLevel();
  353. }
  354. }
  355. }
  356. /**
  357. * Get the assigned Logger level.
  358. * @return LoggerLevel The assigned level or null if none is assigned.
  359. */
  360. public function getLevel()
  361. {
  362. return $this->level;
  363. }
  364. /**
  365. * Set the Logger level.
  366. *
  367. * @param LoggerLevel $level the level to set
  368. */
  369. public function setLevel($level)
  370. {
  371. $this->level = $level;
  372. }
  373. /**
  374. * Checks whether an appender is attached to this logger instance.
  375. *
  376. * @param LoggerAppender $appender
  377. * @return boolean
  378. */
  379. public function isAttached(LoggerAppender $appender)
  380. {
  381. return isset($this->appenders[$appender->getName()]);
  382. }
  383. /**
  384. * Sets the parent logger.
  385. * @param Logger $logger
  386. */
  387. public function setParent(Logger $logger)
  388. {
  389. $this->parent = $logger;
  390. }
  391. // ******************************************
  392. // *** Static methods and properties ***
  393. // ******************************************
  394. /** The logger hierarchy used by log4php. */
  395. private static $hierarchy;
  396. /** Inidicates if log4php has been initialized */
  397. private static $initialized = false;
  398. /**
  399. * Returns the hierarchy used by this Logger.
  400. *
  401. * Caution: do not use this hierarchy unless you have called initialize().
  402. * To get Loggers, use the Logger::getLogger and Logger::getRootLogger
  403. * methods instead of operating on on the hierarchy directly.
  404. *
  405. * @return LoggerHierarchy
  406. */
  407. public static function getHierarchy()
  408. {
  409. if (!isset(self::$hierarchy)) {
  410. self::$hierarchy = new LoggerHierarchy(new LoggerRoot());
  411. }
  412. return self::$hierarchy;
  413. }
  414. /**
  415. * Returns a Logger by name. If it does not exist, it will be created.
  416. *
  417. * @param string $name The logger name
  418. * @return Logger
  419. */
  420. public static function getLogger($name)
  421. {
  422. if (!self::isInitialized()) {
  423. self::configure();
  424. }
  425. return self::getHierarchy()->getLogger($name);
  426. }
  427. /**
  428. * Returns the Root Logger.
  429. * @return LoggerRoot
  430. */
  431. public static function getRootLogger()
  432. {
  433. if (!self::isInitialized()) {
  434. self::configure();
  435. }
  436. return self::getHierarchy()->getRootLogger();
  437. }
  438. /**
  439. * Clears all Logger definitions from the logger hierarchy.
  440. * @return boolean
  441. */
  442. public static function clear()
  443. {
  444. return self::getHierarchy()->clear();
  445. }
  446. /**
  447. * Destroy configurations for logger definitions
  448. */
  449. public static function resetConfiguration()
  450. {
  451. self::getHierarchy()->resetConfiguration();
  452. self::getHierarchy()->clear(); // TODO: clear or not?
  453. self::$initialized = false;
  454. }
  455. /**
  456. * Safely close all appenders.
  457. * @deprecated This is no longer necessary due the appenders shutdown via
  458. * destructors.
  459. */
  460. public static function shutdown()
  461. {
  462. return self::getHierarchy()->shutdown();
  463. }
  464. /**
  465. * check if a given logger exists.
  466. *
  467. * @param string $name logger name
  468. * @return boolean
  469. */
  470. public static function exists($name)
  471. {
  472. return self::getHierarchy()->exists($name);
  473. }
  474. /**
  475. * Returns an array this whole Logger instances.
  476. * @see Logger
  477. * @return array
  478. */
  479. public static function getCurrentLoggers()
  480. {
  481. return self::getHierarchy()->getCurrentLoggers();
  482. }
  483. /**
  484. * Configures log4php.
  485. *
  486. * This method needs to be called before the first logging event has
  487. * occured. If this method is not called before then the default
  488. * configuration will be used.
  489. *
  490. * @param string|array $configuration Either a path to the configuration
  491. * file, or a configuration array.
  492. *
  493. * @param string|LoggerConfigurator $configurator A custom
  494. * configurator class: either a class name (string), or an object which
  495. * implements the LoggerConfigurator interface. If left empty, the default
  496. * configurator implementation will be used.
  497. */
  498. public static function configure($configuration = null, $configurator = null)
  499. {
  500. self::resetConfiguration();
  501. $configurator = self::getConfigurator($configurator);
  502. $configurator->configure(self::getHierarchy(), $configuration);
  503. self::$initialized = true;
  504. }
  505. /**
  506. * Creates a logger configurator instance based on the provided
  507. * configurator class. If no class is given, returns an instance of
  508. * the default configurator.
  509. *
  510. * @param string|LoggerConfigurator $configurator The configurator class
  511. * or LoggerConfigurator instance.
  512. */
  513. private static function getConfigurator($configurator = null)
  514. {
  515. if ($configurator === null) {
  516. return new Configurator\DefaultAdapter();
  517. }
  518. if (is_object($configurator)) {
  519. if ($configurator instanceof LoggerConfigurator) {
  520. return $configurator;
  521. } else {
  522. trigger_error("log4php: Given configurator object [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.",
  523. E_USER_WARNING);
  524. return new Configurator\DefaultAdapter();
  525. }
  526. }
  527. if (is_string($configurator)) {
  528. if (!class_exists($configurator)) {
  529. trigger_error("log4php: Specified configurator class [$configurator] does not exist. Reverting to default configurator.",
  530. E_USER_WARNING);
  531. return new Configurator\DefaultAdapter();
  532. }
  533. $instance = new $configurator();
  534. if (!($instance instanceof LoggerConfigurator)) {
  535. trigger_error("log4php: Specified configurator class [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.",
  536. E_USER_WARNING);
  537. return new Configurator\DefaultAdapter();
  538. }
  539. return $instance;
  540. }
  541. trigger_error("log4php: Invalid configurator specified. Expected either a string or a LoggerConfigurator instance. Reverting to default configurator.",
  542. E_USER_WARNING);
  543. return new Configurator\DefaultAdapter();
  544. }
  545. /**
  546. * Returns true if the log4php framework has been initialized.
  547. * @return boolean
  548. */
  549. private static function isInitialized()
  550. {
  551. return self::$initialized;
  552. }
  553. }