LogCapturingSpi.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. namespace MediaWiki\Logger;
  3. use Psr\Log\AbstractLogger;
  4. use Psr\Log\LoggerInterface;
  5. /**
  6. * Wraps another spi to capture all logs generated. This can be
  7. * used, for example, to collect all logs generated during a
  8. * unit test and report them when the test fails.
  9. */
  10. class LogCapturingSpi implements Spi {
  11. /** @var LoggerInterface[] */
  12. private $singletons;
  13. /** @var Spi */
  14. private $inner;
  15. /** @var array */
  16. private $logs = [];
  17. public function __construct( Spi $inner ) {
  18. $this->inner = $inner;
  19. }
  20. /**
  21. * @return array
  22. */
  23. public function getLogs() {
  24. return $this->logs;
  25. }
  26. /**
  27. * @param string $channel
  28. * @return LoggerInterface
  29. */
  30. public function getLogger( $channel ) {
  31. if ( !isset( $this->singletons[$channel] ) ) {
  32. $this->singletons[$channel] = $this->createLogger( $channel );
  33. }
  34. return $this->singletons[$channel];
  35. }
  36. /**
  37. * @param array $log
  38. */
  39. public function capture( $log ) {
  40. $this->logs[] = $log;
  41. }
  42. /**
  43. * @param string $channel
  44. * @return LoggerInterface
  45. */
  46. private function createLogger( $channel ) {
  47. $inner = $this->inner->getLogger( $channel );
  48. return new class( $channel, $inner, $this ) extends AbstractLogger {
  49. /** @var string */
  50. private $channel;
  51. /** @var LoggerInterface */
  52. private $logger;
  53. /** @var LogCapturingSpi */
  54. private $parent;
  55. // phpcs:ignore MediaWiki.Usage.NestedFunctions.NestedFunction
  56. public function __construct( $channel, LoggerInterface $logger, LogCapturingSpi $parent ) {
  57. $this->channel = $channel;
  58. $this->logger = $logger;
  59. $this->parent = $parent;
  60. }
  61. // phpcs:ignore MediaWiki.Usage.NestedFunctions.NestedFunction
  62. public function log( $level, $message, array $context = [] ) {
  63. $this->parent->capture( [
  64. 'channel' => $this->channel,
  65. 'level' => $level,
  66. 'message' => $message,
  67. 'context' => $context
  68. ] );
  69. $this->logger->log( $level, $message, $context );
  70. }
  71. };
  72. }
  73. }