DeduplicationHandlerTest.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of the Monolog package.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Monolog\Handler;
  11. use Monolog\Level;
  12. class DeduplicationHandlerTest extends \Monolog\Test\MonologTestCase
  13. {
  14. /**
  15. * @covers Monolog\Handler\DeduplicationHandler::flush
  16. */
  17. public function testFlushPassthruIfAllRecordsUnderTrigger()
  18. {
  19. $test = new TestHandler();
  20. @unlink(sys_get_temp_dir().'/monolog_dedup.log');
  21. $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', Level::Debug);
  22. $handler->handle($this->getRecord(Level::Debug));
  23. $handler->handle($this->getRecord(Level::Info));
  24. $handler->flush();
  25. $this->assertTrue($test->hasInfoRecords());
  26. $this->assertTrue($test->hasDebugRecords());
  27. $this->assertFalse($test->hasWarningRecords());
  28. }
  29. /**
  30. * @covers Monolog\Handler\DeduplicationHandler::flush
  31. * @covers Monolog\Handler\DeduplicationHandler::appendRecord
  32. */
  33. public function testFlushPassthruIfEmptyLog()
  34. {
  35. $test = new TestHandler();
  36. @unlink(sys_get_temp_dir().'/monolog_dedup.log');
  37. $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', Level::Debug);
  38. $handler->handle($this->getRecord(Level::Error, 'Foo:bar'));
  39. $handler->handle($this->getRecord(Level::Critical, "Foo\nbar"));
  40. $handler->flush();
  41. $this->assertTrue($test->hasErrorRecords());
  42. $this->assertTrue($test->hasCriticalRecords());
  43. $this->assertFalse($test->hasWarningRecords());
  44. }
  45. /**
  46. * @covers Monolog\Handler\DeduplicationHandler::flush
  47. * @covers Monolog\Handler\DeduplicationHandler::appendRecord
  48. * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
  49. * @depends testFlushPassthruIfEmptyLog
  50. */
  51. public function testFlushSkipsIfLogExists()
  52. {
  53. $test = new TestHandler();
  54. $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', Level::Debug);
  55. $handler->handle($this->getRecord(Level::Error, 'Foo:bar'));
  56. $handler->handle($this->getRecord(Level::Critical, "Foo\nbar"));
  57. $handler->flush();
  58. $this->assertFalse($test->hasErrorRecords());
  59. $this->assertFalse($test->hasCriticalRecords());
  60. $this->assertFalse($test->hasWarningRecords());
  61. }
  62. /**
  63. * @covers Monolog\Handler\DeduplicationHandler::flush
  64. * @covers Monolog\Handler\DeduplicationHandler::appendRecord
  65. * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
  66. * @depends testFlushPassthruIfEmptyLog
  67. */
  68. public function testFlushPassthruIfLogTooOld()
  69. {
  70. $test = new TestHandler();
  71. $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', Level::Debug);
  72. $record = $this->getRecord(Level::Error, datetime: new \DateTimeImmutable('+62seconds'));
  73. $handler->handle($record);
  74. $record = $this->getRecord(Level::Critical, datetime: new \DateTimeImmutable('+62seconds'));
  75. $handler->handle($record);
  76. $handler->flush();
  77. $this->assertTrue($test->hasErrorRecords());
  78. $this->assertTrue($test->hasCriticalRecords());
  79. $this->assertFalse($test->hasWarningRecords());
  80. }
  81. /**
  82. * @covers Monolog\Handler\DeduplicationHandler::flush
  83. * @covers Monolog\Handler\DeduplicationHandler::appendRecord
  84. * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
  85. * @covers Monolog\Handler\DeduplicationHandler::collectLogs
  86. */
  87. public function testGcOldLogs()
  88. {
  89. $test = new TestHandler();
  90. @unlink(sys_get_temp_dir().'/monolog_dedup.log');
  91. $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', Level::Debug);
  92. // handle two records from yesterday, and one recent
  93. $record = $this->getRecord(Level::Error, datetime: new \DateTimeImmutable('-1day -10seconds'));
  94. $handler->handle($record);
  95. $record2 = $this->getRecord(Level::Critical, datetime: new \DateTimeImmutable('-1day -10seconds'));
  96. $handler->handle($record2);
  97. $record3 = $this->getRecord(Level::Critical, datetime: new \DateTimeImmutable('-30seconds'));
  98. $handler->handle($record3);
  99. // log is written as none of them are duplicate
  100. $handler->flush();
  101. $this->assertSame(
  102. $record->datetime->getTimestamp() . ":ERROR:test\n" .
  103. $record2['datetime']->getTimestamp() . ":CRITICAL:test\n" .
  104. $record3['datetime']->getTimestamp() . ":CRITICAL:test\n",
  105. file_get_contents(sys_get_temp_dir() . '/monolog_dedup.log')
  106. );
  107. $this->assertTrue($test->hasErrorRecords());
  108. $this->assertTrue($test->hasCriticalRecords());
  109. $this->assertFalse($test->hasWarningRecords());
  110. // clear test handler
  111. $test->clear();
  112. $this->assertFalse($test->hasErrorRecords());
  113. $this->assertFalse($test->hasCriticalRecords());
  114. // log new records, duplicate log gets GC'd at the end of this flush call
  115. $handler->handle($record = $this->getRecord(Level::Error));
  116. $handler->handle($record2 = $this->getRecord(Level::Critical));
  117. $handler->flush();
  118. // log should now contain the new errors and the previous one that was recent enough
  119. $this->assertSame(
  120. $record3['datetime']->getTimestamp() . ":CRITICAL:test\n" .
  121. $record->datetime->getTimestamp() . ":ERROR:test\n" .
  122. $record2['datetime']->getTimestamp() . ":CRITICAL:test\n",
  123. file_get_contents(sys_get_temp_dir() . '/monolog_dedup.log')
  124. );
  125. $this->assertTrue($test->hasErrorRecords());
  126. $this->assertTrue($test->hasCriticalRecords());
  127. $this->assertFalse($test->hasWarningRecords());
  128. }
  129. public static function tearDownAfterClass(): void
  130. {
  131. @unlink(sys_get_temp_dir().'/monolog_dedup.log');
  132. }
  133. }