Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.7KB

  1. <?php
  2. namespace Friendica\Factory;
  3. use Friendica\Core\Config\Configuration;
  4. use Friendica\Core\Logger;
  5. use Friendica\Network\HTTPException\InternalServerErrorException;
  6. use Friendica\Util\Logger\FriendicaDevelopHandler;
  7. use Friendica\Util\Logger\FriendicaIntrospectionProcessor;
  8. use Friendica\Util\Profiler;
  9. use Monolog;
  10. use Psr\Log\LoggerInterface;
  11. use Psr\Log\LogLevel;
  12. /**
  13. * A logger factory
  14. *
  15. * Currently only Monolog is supported
  16. */
  17. class LoggerFactory
  18. {
  19. /**
  20. * Creates a new PSR-3 compliant logger instances
  21. *
  22. * @param string $channel The channel of the logger instance
  23. * @param Configuration $config The config
  24. *
  25. * @return LoggerInterface The PSR-3 compliant logger instance
  26. */
  27. public static function create($channel, Configuration $config)
  28. {
  29. $logger = new Monolog\Logger($channel);
  30. $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
  31. $logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
  32. $logger->pushProcessor(new Monolog\Processor\UidProcessor());
  33. $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, [Logger::class, Profiler::class]));
  34. $debugging = $config->get('system', 'debugging');
  35. $stream = $config->get('system', 'logfile');
  36. $level = $config->get('system', 'loglevel');
  37. if ($debugging) {
  38. $loglevel = self::mapLegacyConfigDebugLevel((string)$level);
  39. static::addStreamHandler($logger, $stream, $loglevel);
  40. }
  41. Logger::setLogger($logger);
  42. return $logger;
  43. }
  44. /**
  45. * Creates a new PSR-3 compliant develop logger
  46. *
  47. * If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
  48. * you'll use this logger instance for the duration of your work.
  49. *
  50. * It should never get filled during normal usage of Friendica
  51. *
  52. * @param string $channel The channel of the logger instance
  53. * @param Configuration $config The config
  54. *
  55. * @return LoggerInterface The PSR-3 compliant logger instance
  56. */
  57. public static function createDev($channel, Configuration $config)
  58. {
  59. $debugging = $config->get('system', 'debugging');
  60. $stream = $config->get('system', 'dlogfile');
  61. $developerIp = $config->get('system', 'dlogip');
  62. if (!isset($developerIp) || !$debugging) {
  63. return null;
  64. }
  65. $logger = new Monolog\Logger($channel);
  66. $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
  67. $logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
  68. $logger->pushProcessor(new Monolog\Processor\UidProcessor());
  69. $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, ['Friendica\\Core\\Logger']));
  70. $logger->pushHandler(new FriendicaDevelopHandler($developerIp));
  71. static::addStreamHandler($logger, $stream, LogLevel::DEBUG);
  72. Logger::setDevLogger($logger);
  73. return $logger;
  74. }
  75. /**
  76. * Mapping a legacy level to the PSR-3 compliant levels
  77. * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
  78. *
  79. * @param string $level the level to be mapped
  80. *
  81. * @return string the PSR-3 compliant level
  82. */
  83. private static function mapLegacyConfigDebugLevel($level)
  84. {
  85. switch ($level) {
  86. // legacy WARNING
  87. case "0":
  88. return LogLevel::ERROR;
  89. // legacy INFO
  90. case "1":
  91. return LogLevel::WARNING;
  92. // legacy TRACE
  93. case "2":
  94. return LogLevel::NOTICE;
  95. // legacy DEBUG
  96. case "3":
  97. return LogLevel::INFO;
  98. // legacy DATA
  99. case "4":
  100. return LogLevel::DEBUG;
  101. // legacy ALL
  102. case "5":
  103. return LogLevel::DEBUG;
  104. // default if nothing set
  105. default:
  106. return $level;
  107. }
  108. }
  109. /**
  110. * Adding a handler to a given logger instance
  111. *
  112. * @param LoggerInterface $logger The logger instance
  113. * @param mixed $stream The stream which handles the logger output
  114. * @param string $level The level, for which this handler at least should handle logging
  115. *
  116. * @return void
  117. *
  118. * @throws InternalServerErrorException if the logger is incompatible to the logger factory
  119. * @throws \Exception in case of general failures
  120. */
  121. public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
  122. {
  123. if ($logger instanceof Monolog\Logger) {
  124. $loglevel = Monolog\Logger::toMonologLevel($level);
  125. // fallback to notice if an invalid loglevel is set
  126. if (!is_int($loglevel)) {
  127. $loglevel = LogLevel::NOTICE;
  128. }
  129. $fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel);
  130. $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
  131. $fileHandler->setFormatter($formatter);
  132. $logger->pushHandler($fileHandler);
  133. } else {
  134. throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
  135. }
  136. }
  137. }