PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/apache-log4php/trunk/src/main/php/Logger.php

http://owasp-esapi-php.googlecode.com/
PHP | 624 lines | 269 code | 61 blank | 294 comment | 25 complexity | b3caf7f61c5fe02524cc1e80ce88960f MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  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. /**
  20. * LOG4PHP_DIR points to the log4php root directory.
  21. *
  22. * If not defined it will be set automatically when the first package classfile
  23. * is included
  24. *
  25. * @var string
  26. */
  27. if (!defined('LOG4PHP_DIR')) define('LOG4PHP_DIR', dirname(__FILE__));
  28. spl_autoload_register(array('Logger', 'autoload'));
  29. /**
  30. * This is the central class in the log4j package. Most logging operations,
  31. * except configuration, are done through this class.
  32. *
  33. * In log4j this class replaces the Category class. There is no need to
  34. * port deprecated classes; log4php Logger class doesn't extend Category.
  35. *
  36. * @category log4php
  37. * @package log4php
  38. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  39. * @version SVN: $Id: Logger.php 806678 2009-08-21 19:15:49Z grobmeier $
  40. * @link http://logging.apache.org/log4php
  41. */
  42. /*
  43. * TODO:
  44. * Localization: setResourceBundle($bundle) : not supported
  45. * Localization: getResourceBundle: not supported
  46. * Localization: getResourceBundleString($key): not supported
  47. * Localization: l7dlog($priority, $key, $params, $t) : not supported
  48. */
  49. class Logger {
  50. private static $_classes = array(
  51. 'LoggerException' => '/LoggerException.php',
  52. 'LoggerHierarchy' => '/LoggerHierarchy.php',
  53. 'LoggerLayout' => '/LoggerLayout.php',
  54. 'LoggerLevel' => '/LoggerLevel.php',
  55. 'LoggerMDC' => '/LoggerMDC.php',
  56. 'LoggerNDC' => '/LoggerNDC.php',
  57. 'LoggerReflectionUtils' => '/LoggerReflectionUtils.php',
  58. 'LoggerConfigurator' => '/LoggerConfigurator.php',
  59. 'LoggerConfiguratorBasic' => '/configurators/LoggerConfiguratorBasic.php',
  60. 'LoggerConfiguratorIni' => '/configurators/LoggerConfiguratorIni.php',
  61. 'LoggerConfiguratorPhp' => '/configurators/LoggerConfiguratorPhp.php',
  62. 'LoggerConfiguratorXml' => '/configurators/LoggerConfiguratorXml.php',
  63. 'LoggerRoot' => '/LoggerRoot.php',
  64. 'LoggerAppender' => '/LoggerAppender.php',
  65. 'LoggerAppenderPool' => '/LoggerAppenderPool.php',
  66. 'LoggerAppenderAdodb' => '/appenders/LoggerAppenderAdodb.php',
  67. 'LoggerAppenderPDO' => '/appenders/LoggerAppenderPDO.php',
  68. 'LoggerAppenderConsole' => '/appenders/LoggerAppenderConsole.php',
  69. 'LoggerAppenderDailyFile' => '/appenders/LoggerAppenderDailyFile.php',
  70. 'LoggerAppenderEcho' => '/appenders/LoggerAppenderEcho.php',
  71. 'LoggerAppenderFile' => '/appenders/LoggerAppenderFile.php',
  72. 'LoggerAppenderMail' => '/appenders/LoggerAppenderMail.php',
  73. 'LoggerAppenderMailEvent' => '/appenders/LoggerAppenderMailEvent.php',
  74. 'LoggerAppenderNull' => '/appenders/LoggerAppenderNull.php',
  75. 'LoggerAppenderPhp' => '/appenders/LoggerAppenderPhp.php',
  76. 'LoggerAppenderRollingFile' => '/appenders/LoggerAppenderRollingFile.php',
  77. 'LoggerAppenderSocket' => '/appenders/LoggerAppenderSocket.php',
  78. 'LoggerAppenderSyslog' => '/appenders/LoggerAppenderSyslog.php',
  79. 'LoggerFormattingInfo' => '/helpers/LoggerFormattingInfo.php',
  80. 'LoggerOptionConverter' => '/helpers/LoggerOptionConverter.php',
  81. 'LoggerPatternConverter' => '/helpers/LoggerPatternConverter.php',
  82. 'LoggerBasicPatternConverter' => '/helpers/LoggerBasicPatternConverter.php',
  83. 'LoggerCategoryPatternConverter' => '/helpers/LoggerCategoryPatternConverter.php',
  84. 'LoggerClassNamePatternConverter' => '/helpers/LoggerClassNamePatternConverter.php',
  85. 'LoggerDatePatternConverter' => '/helpers/LoggerDatePatternConverter.php',
  86. 'LoggerLiteralPatternConverter' => '/helpers/LoggerLiteralPatternConverter.php',
  87. 'LoggerLocationPatternConverter' => '/helpers/LoggerLocationPatternConverter.php',
  88. 'LoggerMDCPatternConverter' => '/helpers/LoggerMDCPatternConverter.php',
  89. 'LoggerNamedPatternConverter' => '/helpers/LoggerNamedPatternConverter.php',
  90. 'LoggerBasicPatternConverter' => '/helpers/LoggerBasicPatternConverter.php',
  91. 'LoggerLiteralPatternConverter' => '/helpers/LoggerLiteralPatternConverter.php',
  92. 'LoggerDatePatternConverter' => '/helpers/LoggerDatePatternConverter.php',
  93. 'LoggerMDCPatternConverter' => '/helpers/LoggerMDCPatternConverter.php',
  94. 'LoggerLocationPatternConverter' => '/helpers/LoggerLocationPatternConverter.php',
  95. 'LoggerNamedPatternConverter' => '/helpers/LoggerNamedPatternConverter.php',
  96. 'LoggerClassNamePatternConverter' => '/helpers/LoggerClassNamePatternConverter.php',
  97. 'LoggerCategoryPatternConverter' => '/helpers/LoggerCategoryPatternConverter.php',
  98. 'LoggerPatternParser' => '/helpers/LoggerPatternParser.php',
  99. 'LoggerLayoutHtml' => '/layouts/LoggerLayoutHtml.php',
  100. 'LoggerLayoutSimple' => '/layouts/LoggerLayoutSimple.php',
  101. 'LoggerLayoutTTCC' => '/layouts/LoggerLayoutTTCC.php',
  102. 'LoggerLayoutPattern' => '/layouts/LoggerLayoutPattern.php',
  103. 'LoggerLayoutXml' => '/layouts/LoggerLayoutXml.php',
  104. 'LoggerRendererDefault' => '/renderers/LoggerRendererDefault.php',
  105. 'LoggerRendererObject' => '/renderers/LoggerRendererObject.php',
  106. 'LoggerRendererMap' => '/renderers/LoggerRendererMap.php',
  107. 'LoggerLocationInfo' => '/LoggerLocationInfo.php',
  108. 'LoggerLoggingEvent' => '/LoggerLoggingEvent.php',
  109. 'LoggerFilter' => '/LoggerFilter.php',
  110. 'LoggerFilterDenyAll' => '/filters/LoggerFilterDenyAll.php',
  111. 'LoggerFilterLevelMatch' => '/filters/LoggerFilterLevelMatch.php',
  112. 'LoggerFilterLevelRange' => '/filters/LoggerFilterLevelRange.php',
  113. 'LoggerFilterStringMatch' => '/filters/LoggerFilterStringMatch.php',
  114. );
  115. /**
  116. * Class autoloader
  117. * This method is provided to be invoked within an __autoload() magic method.
  118. * @param string class name
  119. */
  120. public static function autoload($className) {
  121. if(isset(self::$_classes[$className])) {
  122. include LOG4PHP_DIR.self::$_classes[$className];
  123. }
  124. }
  125. /**
  126. * Additivity is set to true by default, that is children inherit the
  127. * appenders of their ancestors by default.
  128. * @var boolean
  129. */
  130. private $additive = true;
  131. /** @var string fully qualified class name */
  132. private $fqcn = 'Logger';
  133. /** @var LoggerLevel The assigned level of this category. */
  134. private $level = null;
  135. /** @var string name of this category. */
  136. private $name = '';
  137. /** @var Logger The parent of this category. Null if this is the root logger*/
  138. private $parent = null;
  139. /**
  140. * @var array collection of appenders
  141. * @see LoggerAppender
  142. */
  143. private $aai = array();
  144. /** the hierarchy used by log4php */
  145. private static $hierarchy;
  146. /** the configurator class name */
  147. private static $configurationClass = 'LoggerConfiguratorBasic';
  148. /** the path to the configuration file */
  149. private static $configurationFile = null;
  150. /** inidicates if log4php has already been initialized */
  151. private static $initialized = false;
  152. /**
  153. * Constructor.
  154. * @param string $name Category name
  155. */
  156. public function __construct($name) {
  157. $this->name = $name;
  158. }
  159. /**
  160. * Return the category name.
  161. * @return string
  162. */
  163. public function getName() {
  164. return $this->name;
  165. }
  166. /**
  167. * Returns the parent of this category.
  168. * @return Logger
  169. */
  170. public function getParent() {
  171. return $this->parent;
  172. }
  173. /**
  174. * Returns the hierarchy used by this Logger.
  175. * Caution: do not use this hierarchy unless you have called initialize().
  176. * To get Loggers, use the Logger::getLogger and Logger::getRootLogger methods
  177. * instead of operating on on the hierarchy directly.
  178. *
  179. * @deprecated - will be moved to private
  180. */
  181. public static function getHierarchy() {
  182. if(!isset(self::$hierarchy)) {
  183. self::$hierarchy = new LoggerHierarchy(new LoggerRoot());
  184. }
  185. return self::$hierarchy;
  186. }
  187. /* Logging methods */
  188. /**
  189. * Log a message object with the DEBUG level including the caller.
  190. *
  191. * @param mixed $message message
  192. * @param mixed $caller caller object or caller string id
  193. */
  194. public function debug($message, $caller = null) {
  195. $this->logLevel($message, LoggerLevel::getLevelDebug(), $caller);
  196. }
  197. /**
  198. * Log a message object with the INFO Level.
  199. *
  200. * @param mixed $message message
  201. * @param mixed $caller caller object or caller string id
  202. */
  203. public function info($message, $caller = null) {
  204. $this->logLevel($message, LoggerLevel::getLevelInfo(), $caller);
  205. }
  206. /**
  207. * Log a message with the WARN level.
  208. *
  209. * @param mixed $message message
  210. * @param mixed $caller caller object or caller string id
  211. */
  212. public function warn($message, $caller = null) {
  213. $this->logLevel($message, LoggerLevel::getLevelWarn(), $caller);
  214. }
  215. /**
  216. * Log a message object with the ERROR level including the caller.
  217. *
  218. * @param mixed $message message
  219. * @param mixed $caller caller object or caller string id
  220. */
  221. public function error($message, $caller = null) {
  222. $this->logLevel($message, LoggerLevel::getLevelError(), $caller);
  223. }
  224. /**
  225. * Log a message object with the FATAL level including the caller.
  226. *
  227. * @param mixed $message message
  228. * @param mixed $caller caller object or caller string id
  229. */
  230. public function fatal($message, $caller = null) {
  231. $this->logLevel($message, LoggerLevel::getLevelFatal(), $caller);
  232. }
  233. /**
  234. * This method creates a new logging event and logs the event without further checks.
  235. *
  236. * It should not be called directly. Use {@link info()}, {@link debug()}, {@link warn()},
  237. * {@link error()} and {@link fatal()} wrappers.
  238. *
  239. * @param string $fqcn Fully Qualified Class Name of the Logger
  240. * @param mixed $caller caller object or caller string id
  241. * @param LoggerLevel $level log level
  242. * @param mixed $message message
  243. * @see LoggerLoggingEvent
  244. */
  245. public function forcedLog($fqcn, $caller, $level, $message) {
  246. $this->callAppenders(new LoggerLoggingEvent($fqcn, $this, $level, $message));
  247. }
  248. /**
  249. * Check whether this category is enabled for the DEBUG Level.
  250. * @return boolean
  251. */
  252. public function isDebugEnabled() {
  253. return $this->isEnabledFor(LoggerLevel::getLevelDebug());
  254. }
  255. /**
  256. * Check whether this category is enabled for a given Level passed as parameter.
  257. *
  258. * @param LoggerLevel level
  259. * @return boolean
  260. */
  261. public function isEnabledFor($level) {
  262. return (bool)($level->isGreaterOrEqual($this->getEffectiveLevel()));
  263. }
  264. /**
  265. * Check whether this category is enabled for the info Level.
  266. * @return boolean
  267. * @see LoggerLevel
  268. */
  269. public function isInfoEnabled() {
  270. return $this->isEnabledFor(LoggerLevel::getLevelInfo());
  271. }
  272. /**
  273. * This generic form is intended to be used by wrappers.
  274. *
  275. * @param LoggerLevel $priority a valid level
  276. * @param mixed $message message
  277. * @param mixed $caller caller object or caller string id
  278. */
  279. public function log($priority, $message, $caller = null) {
  280. if($this->isEnabledFor($priority)) {
  281. $this->forcedLog($this->fqcn, $caller, $priority, $message);
  282. }
  283. }
  284. /**
  285. * If assertion parameter is false, then logs msg as an error statement.
  286. *
  287. * @param bool $assertion
  288. * @param string $msg message to log
  289. */
  290. public function assertLog($assertion = true, $msg = '') {
  291. if($assertion == false) {
  292. $this->error($msg);
  293. }
  294. }
  295. private function logLevel($message, $level, $caller = null) {
  296. if($level->isGreaterOrEqual($this->getEffectiveLevel())) {
  297. $this->forcedLog($this->fqcn, $caller, $level, $message);
  298. }
  299. }
  300. /* Factory methods */
  301. /**
  302. * Get a Logger by name (Delegate to {@link Logger})
  303. *
  304. * @param string $name logger name
  305. * @param LoggerFactory $factory a {@link LoggerFactory} instance or null
  306. * @return Logger
  307. * @static
  308. */
  309. public static function getLogger($name) {
  310. if(!self::isInitialized()) {
  311. self::initialize();
  312. }
  313. return self::getHierarchy()->getLogger($name);
  314. }
  315. /**
  316. * get the Root Logger (Delegate to {@link Logger})
  317. * @return LoggerRoot
  318. * @static
  319. */
  320. public static function getRootLogger() {
  321. if(!self::isInitialized()) {
  322. self::initialize();
  323. }
  324. return self::getHierarchy()->getRootLogger();
  325. }
  326. /* Configuration methods */
  327. /**
  328. * Add a new Appender to the list of appenders of this Category instance.
  329. *
  330. * @param LoggerAppender $newAppender
  331. */
  332. public function addAppender($newAppender) {
  333. $appenderName = $newAppender->getName();
  334. $this->aai[$appenderName] = $newAppender;
  335. }
  336. /**
  337. * Remove all previously added appenders from this Category instance.
  338. */
  339. public function removeAllAppenders() {
  340. $appenderNames = array_keys($this->aai);
  341. $enumAppenders = count($appenderNames);
  342. for($i = 0; $i < $enumAppenders; $i++) {
  343. $this->removeAppender($appenderNames[$i]);
  344. }
  345. }
  346. /**
  347. * Remove the appender passed as parameter form the list of appenders.
  348. *
  349. * @param mixed $appender can be an appender name or a {@link LoggerAppender} object
  350. */
  351. public function removeAppender($appender) {
  352. if($appender instanceof LoggerAppender) {
  353. $appender->close();
  354. unset($this->aai[$appender->getName()]);
  355. } else if (is_string($appender) and isset($this->aai[$appender])) {
  356. $this->aai[$appender]->close();
  357. unset($this->aai[$appender]);
  358. }
  359. }
  360. /**
  361. * Call the appenders in the hierarchy starting at this.
  362. *
  363. * @param LoggerLoggingEvent $event
  364. */
  365. public function callAppenders($event) {
  366. if(count($this->aai) > 0) {
  367. foreach(array_keys($this->aai) as $appenderName) {
  368. $this->aai[$appenderName]->doAppend($event);
  369. }
  370. }
  371. if($this->parent != null and $this->getAdditivity()) {
  372. $this->parent->callAppenders($event);
  373. }
  374. }
  375. /**
  376. * Get the appenders contained in this category as an array.
  377. * @return array collection of appenders
  378. */
  379. public function getAllAppenders() {
  380. return array_values($this->aai);
  381. }
  382. /**
  383. * Look for the appender named as name.
  384. * @return LoggerAppender
  385. */
  386. public function getAppender($name) {
  387. return $this->aai[$name];
  388. }
  389. /**
  390. * Get the additivity flag for this Category instance.
  391. * @return boolean
  392. */
  393. public function getAdditivity() {
  394. return $this->additive;
  395. }
  396. /**
  397. * Starting from this category, search the category hierarchy for a non-null level and return it.
  398. * @see LoggerLevel
  399. * @return LoggerLevel or null
  400. */
  401. public function getEffectiveLevel() {
  402. for($c = $this; $c != null; $c = $c->parent) {
  403. if($c->getLevel() !== null) {
  404. return $c->getLevel();
  405. }
  406. }
  407. return null;
  408. }
  409. /**
  410. * Returns the assigned Level, if any, for this Category.
  411. * @return LoggerLevel or null
  412. */
  413. public function getLevel() {
  414. return $this->level;
  415. }
  416. /**
  417. * Set the level of this Category.
  418. *
  419. * @param LoggerLevel $level a level string or a level constant
  420. */
  421. public function setLevel($level) {
  422. $this->level = $level;
  423. }
  424. /**
  425. * Clears all logger definitions
  426. *
  427. * @static
  428. * @return boolean
  429. */
  430. public static function clear() {
  431. return self::getHierarchy()->clear();
  432. }
  433. /**
  434. * Destroy configurations for logger definitions
  435. *
  436. * @static
  437. * @return boolean
  438. */
  439. public static function resetConfiguration() {
  440. $result = self::getHierarchy()->resetConfiguration();
  441. self::$initialized = false;
  442. self::$configurationClass = 'LoggerConfiguratorBasic';
  443. self::$configurationFile = null;
  444. return $result;
  445. }
  446. /**
  447. * Safely close all appenders.
  448. * This is not longer necessary due the appenders shutdown via
  449. * destructors.
  450. * @deprecated
  451. * @static
  452. */
  453. public static function shutdown() {
  454. return self::getHierarchy()->shutdown();
  455. }
  456. /**
  457. * check if a given logger exists.
  458. *
  459. * @param string $name logger name
  460. * @static
  461. * @return boolean
  462. */
  463. public static function exists($name) {
  464. return self::getHierarchy()->exists($name);
  465. }
  466. /**
  467. * Returns an array this whole Logger instances.
  468. *
  469. * @static
  470. * @see Logger
  471. * @return array
  472. */
  473. public static function getCurrentLoggers() {
  474. return self::getHierarchy()->getCurrentLoggers();
  475. }
  476. /**
  477. * Is the appender passed as parameter attached to this category?
  478. *
  479. * @param LoggerAppender $appender
  480. */
  481. public function isAttached($appender) {
  482. return isset($this->aai[$appender->getName()]);
  483. }
  484. /**
  485. * Set the additivity flag for this Category instance.
  486. *
  487. * @param boolean $additive
  488. */
  489. public function setAdditivity($additive) {
  490. $this->additive = (bool)$additive;
  491. }
  492. /**
  493. * Sets the parent logger of this logger
  494. */
  495. public function setParent(Logger $logger) {
  496. $this->parent = $logger;
  497. }
  498. /**
  499. * Configures Log4PHP.
  500. * This method needs to be called before the first logging event
  501. * has occured. If this methode is never called, the standard configuration
  502. * takes place (@see LoggerConfiguratorBasic).
  503. * If only the configuration file is given, the configurator class will
  504. * be the XML Configurator or the INI Configurator, if no .xml ending
  505. * could be determined.
  506. *
  507. * If a custom configurator should be used, the configuration file
  508. * is either null or the path to file the custom configurator uses.
  509. * Make sure the configurator is already or can be loaded by PHP when necessary.
  510. *
  511. * @param String $configurationFile the configuration file
  512. * @param String $configurationClass the configurator class
  513. */
  514. public static function configure($configurationFile = null,
  515. $configurationClass = null ) {
  516. if($configurationClass === null && $configurationFile === null) {
  517. self::$configurationClass = 'LoggerConfiguratorBasic';
  518. return;
  519. }
  520. if($configurationClass !== null) {
  521. self::$configurationFile = $configurationFile;
  522. self::$configurationClass = $configurationClass;
  523. return;
  524. }
  525. if (strtolower(substr( $configurationFile, -4 )) == '.xml') {
  526. self::$configurationFile = $configurationFile;
  527. self::$configurationClass = 'LoggerConfiguratorXml';
  528. } else {
  529. self::$configurationFile = $configurationFile;
  530. self::$configurationClass = 'LoggerConfiguratorIni';
  531. }
  532. }
  533. /**
  534. * Returns the current configurator
  535. * @return the configurator
  536. */
  537. public static function getConfigurationClass() {
  538. return self::$configurationClass;
  539. }
  540. /**
  541. * Returns the current configuration file
  542. * @return the configuration file
  543. */
  544. public static function getConfigurationFile() {
  545. return self::$configurationFile;
  546. }
  547. /**
  548. * Returns, true, if the log4php framework is already initialized
  549. */
  550. private static function isInitialized() {
  551. return self::$initialized;
  552. }
  553. /**
  554. * Initializes the log4php framework.
  555. * @return boolean
  556. */
  557. public static function initialize() {
  558. self::$initialized = true;
  559. $instance = LoggerReflectionUtils::createObject(self::$configurationClass);
  560. $result = $instance->configure(self::getHierarchy(), self::$configurationFile);
  561. return $result;
  562. }
  563. }