Logger.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace Codeception\Extension;
  3. use Codeception\Event\FailEvent;
  4. use Codeception\Event\StepEvent;
  5. use Codeception\Event\SuiteEvent;
  6. use Codeception\Event\TestEvent;
  7. use Codeception\Events;
  8. use Codeception\Exception\ConfigurationException;
  9. use Codeception\Exception\ExtensionException;
  10. use Codeception\Extension;
  11. use Codeception\Test\Descriptor;
  12. use Monolog\Formatter\LineFormatter;
  13. use Monolog\Handler\RotatingFileHandler;
  14. /**
  15. * Log suites/tests/steps using Monolog library.
  16. * Monolog should be installed additionally by Composer.
  17. *
  18. * ```
  19. * composer require monolog/monolog
  20. * ```
  21. *
  22. * Steps are logged into `tests/_output/codeception.log`
  23. *
  24. * To enable this module add to your `codeception.yml`:
  25. *
  26. * ``` yaml
  27. * extensions:
  28. * enabled: [Codeception\Extension\Logger]
  29. * ```
  30. *
  31. * #### Config
  32. *
  33. * * `max_files` (default: 3) - how many log files to keep
  34. *
  35. */
  36. class Logger extends Extension
  37. {
  38. public static $events = [
  39. Events::SUITE_BEFORE => 'beforeSuite',
  40. Events::TEST_BEFORE => 'beforeTest',
  41. Events::TEST_AFTER => 'afterTest',
  42. Events::TEST_END => 'endTest',
  43. Events::STEP_BEFORE => 'beforeStep',
  44. Events::TEST_FAIL => 'testFail',
  45. Events::TEST_ERROR => 'testError',
  46. Events::TEST_INCOMPLETE => 'testIncomplete',
  47. Events::TEST_SKIPPED => 'testSkipped',
  48. ];
  49. protected $logHandler;
  50. /**
  51. * @var \Monolog\Logger
  52. */
  53. protected static $logger;
  54. protected $path;
  55. protected $config = ['max_files' => 3];
  56. public function _initialize()
  57. {
  58. if (!class_exists('\Monolog\Logger')) {
  59. throw new ConfigurationException("Logger extension requires Monolog library to be installed");
  60. }
  61. $this->path = $this->getLogDir();
  62. // internal log
  63. $logHandler = new RotatingFileHandler($this->path . 'codeception.log', $this->config['max_files']);
  64. $formatter = $logHandler->getFormatter();
  65. if ($formatter instanceof LineFormatter) {
  66. $formatter->ignoreEmptyContextAndExtra(true);
  67. }
  68. self::$logger = new \Monolog\Logger('Codeception');
  69. self::$logger->pushHandler($logHandler);
  70. }
  71. public static function getLogger()
  72. {
  73. return self::$logger;
  74. }
  75. public function beforeSuite(SuiteEvent $e)
  76. {
  77. $suite = str_replace('\\', '_', $e->getSuite()->getName());
  78. $this->logHandler = new RotatingFileHandler($this->path . $suite, $this->config['max_files']);
  79. }
  80. public function beforeTest(TestEvent $e)
  81. {
  82. self::$logger = new \Monolog\Logger(Descriptor::getTestFileName($e->getTest()));
  83. self::$logger->pushHandler($this->logHandler);
  84. self::$logger->info('------------------------------------');
  85. self::$logger->info("STARTED: " . ucfirst(Descriptor::getTestAsString($e->getTest())));
  86. }
  87. public function afterTest(TestEvent $e)
  88. {
  89. }
  90. public function endTest(TestEvent $e)
  91. {
  92. self::$logger->info("PASSED");
  93. }
  94. public function testFail(FailEvent $e)
  95. {
  96. self::$logger->alert($e->getFail()->getMessage());
  97. self::$logger->info("# FAILED #");
  98. }
  99. public function testError(FailEvent $e)
  100. {
  101. self::$logger->alert($e->getFail()->getMessage());
  102. self::$logger->info("# ERROR #");
  103. }
  104. public function testSkipped(FailEvent $e)
  105. {
  106. self::$logger->info("# Skipped #");
  107. }
  108. public function testIncomplete(FailEvent $e)
  109. {
  110. self::$logger->info("# Incomplete #");
  111. }
  112. public function beforeStep(StepEvent $e)
  113. {
  114. self::$logger->info((string) $e->getStep());
  115. }
  116. }
  117. if (!function_exists('codecept_log')) {
  118. function codecept_log()
  119. {
  120. return Logger::getLogger();
  121. }
  122. } else {
  123. throw new ExtensionException('Codeception\Extension\Logger', "function 'codecept_log' already defined");
  124. }