DeduplicationHandlerTest.php 6.0 KB

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