| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919 |
- <?php declare(strict_types=1);
- /*
- * This file is part of the Monolog package.
- *
- * (c) Jordi Boggiano <j.boggiano@seld.be>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Monolog;
- use Monolog\Handler\HandlerInterface;
- use Monolog\Processor\WebProcessor;
- use Monolog\Handler\TestHandler;
- use Monolog\Test\TestCase;
- use PHPUnit\Framework\Attributes\DataProvider;
- class LoggerTest extends TestCase
- {
- /**
- * @covers Logger::getName
- */
- public function testGetName()
- {
- $logger = new Logger('foo');
- $this->assertEquals('foo', $logger->getName());
- }
- /**
- * @covers Logger::withName
- */
- public function testWithName()
- {
- $first = new Logger('first', [$handler = new TestHandler()]);
- $second = $first->withName('second');
- $this->assertSame('first', $first->getName());
- $this->assertSame('second', $second->getName());
- $this->assertSame($handler, $second->popHandler());
- }
- /**
- * @covers Logger::toMonologLevel
- */
- public function testConvertPSR3ToMonologLevel()
- {
- $this->assertEquals(Logger::toMonologLevel('debug'), Level::Debug);
- $this->assertEquals(Logger::toMonologLevel('info'), Level::Info);
- $this->assertEquals(Logger::toMonologLevel('notice'), Level::Notice);
- $this->assertEquals(Logger::toMonologLevel('warning'), Level::Warning);
- $this->assertEquals(Logger::toMonologLevel('error'), Level::Error);
- $this->assertEquals(Logger::toMonologLevel('critical'), Level::Critical);
- $this->assertEquals(Logger::toMonologLevel('alert'), Level::Alert);
- $this->assertEquals(Logger::toMonologLevel('emergency'), Level::Emergency);
- }
- /**
- * @covers Monolog\Logger::addRecord
- * @covers Monolog\Logger::log
- */
- public function testConvertRFC5424ToMonologLevelInAddRecordAndLog()
- {
- $logger = new Logger('test');
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- foreach ([
- 7 => 100,
- 6 => 200,
- 5 => 250,
- 4 => 300,
- 3 => 400,
- 2 => 500,
- 1 => 550,
- 0 => 600,
- ] as $rfc5424Level => $monologLevel) {
- $handler->reset();
- $logger->addRecord($rfc5424Level, 'test');
- $logger->log($rfc5424Level, 'test');
- $records = $handler->getRecords();
- self::assertCount(2, $records);
- self::assertSame($monologLevel, $records[0]['level']);
- self::assertSame($monologLevel, $records[1]['level']);
- }
- }
- /**
- * @covers Logger::__construct
- */
- public function testChannel()
- {
- $logger = new Logger('foo');
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->warning('test');
- list($record) = $handler->getRecords();
- $this->assertEquals('foo', $record->channel);
- }
- /**
- * @covers Logger::addRecord
- */
- public function testLogPreventsCircularLogging()
- {
- $logger = new Logger(__METHOD__);
- $loggingHandler = new LoggingHandler($logger);
- $testHandler = new TestHandler();
- $logger->pushHandler($loggingHandler);
- $logger->pushHandler($testHandler);
- $logger->addRecord(Level::Alert, 'test');
- $records = $testHandler->getRecords();
- $this->assertCount(3, $records);
- $this->assertSame('ALERT', $records[0]->level->getName());
- $this->assertSame('DEBUG', $records[1]->level->getName());
- $this->assertSame('WARNING', $records[2]->level->getName());
- }
- /**
- * @covers Monolog\Logger::addRecord
- */
- public function testLog()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->getMockBuilder('Monolog\Handler\HandlerInterface')->getMock();
- $handler->expects($this->never())->method('isHandling');
- $handler->expects($this->once())->method('handle');
- $logger->pushHandler($handler);
- $this->assertTrue($logger->addRecord(Level::Warning, 'test'));
- }
- /**
- * @covers Logger::addRecord
- */
- public function testLogAlwaysHandledIfNoProcessorsArePresent()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->getMockBuilder('Monolog\Handler\HandlerInterface')->getMock();
- $handler->expects($this->never())->method('isHandling');
- $handler->expects($this->once())->method('handle');
- $logger->pushHandler($handler);
- $this->assertTrue($logger->addRecord(Level::Warning, 'test'));
- }
- /**
- * @covers Logger::addRecord
- */
- public function testLogNotHandledIfProcessorsArePresent()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->getMockBuilder('Monolog\Handler\HandlerInterface')->getMock();
- $handler->expects($this->once())->method('isHandling')->willReturn(false);
- $handler->expects($this->never())->method('handle');
- $logger->pushProcessor(fn (LogRecord $record) => $record);
- $logger->pushHandler($handler);
- $this->assertFalse($logger->addRecord(Level::Warning, 'test'));
- }
- public function testHandlersInCtor()
- {
- $handler1 = new TestHandler;
- $handler2 = new TestHandler;
- $logger = new Logger(__METHOD__, [$handler1, $handler2]);
- $this->assertEquals($handler1, $logger->popHandler());
- $this->assertEquals($handler2, $logger->popHandler());
- }
- public function testProcessorsInCtor()
- {
- $processor1 = new WebProcessor;
- $processor2 = new WebProcessor;
- $logger = new Logger(__METHOD__, [], [$processor1, $processor2]);
- $this->assertEquals($processor1, $logger->popProcessor());
- $this->assertEquals($processor2, $logger->popProcessor());
- }
- /**
- * @covers Logger::pushHandler
- * @covers Logger::popHandler
- */
- public function testPushPopHandler()
- {
- $logger = new Logger(__METHOD__);
- $handler1 = new TestHandler;
- $handler2 = new TestHandler;
- $logger->pushHandler($handler1);
- $logger->pushHandler($handler2);
- $this->assertEquals($handler2, $logger->popHandler());
- $this->assertEquals($handler1, $logger->popHandler());
- $this->expectException(\LogicException::class);
- $logger->popHandler();
- }
- /**
- * @covers Logger::setHandlers
- */
- public function testSetHandlers()
- {
- $logger = new Logger(__METHOD__);
- $handler1 = new TestHandler;
- $handler2 = new TestHandler;
- $logger->pushHandler($handler1);
- $logger->setHandlers([$handler2]);
- // handler1 has been removed
- $this->assertEquals([$handler2], $logger->getHandlers());
- $logger->setHandlers([
- "AMapKey" => $handler1,
- "Woop" => $handler2,
- ]);
- // Keys have been scrubbed
- $this->assertEquals([$handler1, $handler2], $logger->getHandlers());
- }
- /**
- * @covers Logger::pushProcessor
- * @covers Logger::popProcessor
- */
- public function testPushPopProcessor()
- {
- $logger = new Logger(__METHOD__);
- $processor1 = new WebProcessor;
- $processor2 = new WebProcessor;
- $logger->pushProcessor($processor1);
- $logger->pushProcessor($processor2);
- $this->assertEquals($processor2, $logger->popProcessor());
- $this->assertEquals($processor1, $logger->popProcessor());
- $this->expectException(\LogicException::class);
- $logger->popProcessor();
- }
- /**
- * @covers Logger::addRecord
- */
- public function testProcessorsAreExecuted()
- {
- $logger = new Logger(__METHOD__);
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->pushProcessor(function ($record) {
- $record->extra['win'] = true;
- return $record;
- });
- $logger->error('test');
- list($record) = $handler->getRecords();
- $this->assertTrue($record->extra['win']);
- }
- /**
- * @covers Logger::addRecord
- */
- public function testProcessorsAreCalledOnlyOnce()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $handler->expects($this->any())
- ->method('handle')
- ->willReturn(true);
- $logger->pushHandler($handler);
- $processor = $this->getMockBuilder('Monolog\Processor\WebProcessor')
- ->disableOriginalConstructor()
- ->onlyMethods(['__invoke'])
- ->getMock()
- ;
- $processor->expects($this->once())
- ->method('__invoke')
- ->willReturnArgument(0)
- ;
- $logger->pushProcessor($processor);
- $logger->error('test');
- }
- /**
- * @covers Logger::addRecord
- */
- public function testProcessorsNotCalledWhenNotHandled()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler->expects($this->once())
- ->method('isHandling')
- ->willReturn(false);
- $logger->pushHandler($handler);
- $that = $this;
- $logger->pushProcessor(function ($record) use ($that) {
- $that->fail('The processor should not be called');
- });
- $logger->alert('test');
- }
- /**
- * @covers Logger::addRecord
- */
- public function testHandlersNotCalledBeforeFirstHandlingWhenProcessorsPresent()
- {
- $logger = new Logger(__METHOD__);
- $logger->pushProcessor(fn ($record) => $record);
- $handler1 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->never())
- ->method('isHandling')
- ->willReturn(false);
- $handler1->expects($this->once())
- ->method('handle')
- ->willReturn(false);
- $logger->pushHandler($handler1);
- $handler2 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->once())
- ->method('isHandling')
- ->willReturn(true);
- $handler2->expects($this->once())
- ->method('handle')
- ->willReturn(false);
- $logger->pushHandler($handler2);
- $handler3 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler3->expects($this->once())
- ->method('isHandling')
- ->willReturn(false);
- $handler3->expects($this->never())
- ->method('handle')
- ;
- $logger->pushHandler($handler3);
- $logger->debug('test');
- }
- /**
- * @covers Logger::addRecord
- */
- public function testHandlersNotCalledBeforeFirstHandlingWhenProcessorsPresentWithAssocArray()
- {
- $handler1 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->never())
- ->method('isHandling')
- ->willReturn(false);
- $handler1->expects($this->once())
- ->method('handle')
- ->willReturn(false);
- $handler2 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->once())
- ->method('isHandling')
- ->willReturn(true);
- $handler2->expects($this->once())
- ->method('handle')
- ->willReturn(false);
- $handler3 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler3->expects($this->once())
- ->method('isHandling')
- ->willReturn(false);
- $handler3->expects($this->never())
- ->method('handle')
- ;
- $logger = new Logger(__METHOD__, ['last' => $handler3, 'second' => $handler2, 'first' => $handler1]);
- $logger->pushProcessor(fn ($record) => $record);
- $logger->debug('test');
- }
- /**
- * @covers Logger::addRecord
- */
- public function testBubblingWhenTheHandlerReturnsFalse()
- {
- $logger = new Logger(__METHOD__);
- $handler1 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $handler1->expects($this->once())
- ->method('handle')
- ->willReturn(false);
- $logger->pushHandler($handler1);
- $handler2 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $handler2->expects($this->once())
- ->method('handle')
- ->willReturn(false);
- $logger->pushHandler($handler2);
- $logger->debug('test');
- }
- /**
- * @covers Logger::addRecord
- */
- public function testNotBubblingWhenTheHandlerReturnsTrue()
- {
- $logger = new Logger(__METHOD__);
- $handler1 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $handler1->expects($this->never())
- ->method('handle')
- ;
- $logger->pushHandler($handler1);
- $handler2 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $handler2->expects($this->once())
- ->method('handle')
- ->willReturn(true);
- $logger->pushHandler($handler2);
- $logger->debug('test');
- }
- /**
- * @covers Logger::isHandling
- */
- public function testIsHandling()
- {
- $logger = new Logger(__METHOD__);
- $handler1 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler1->expects($this->any())
- ->method('isHandling')
- ->willReturn(false);
- $logger->pushHandler($handler1);
- $this->assertFalse($logger->isHandling(Level::Debug));
- $handler2 = $this->createMock('Monolog\Handler\HandlerInterface');
- $handler2->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $logger->pushHandler($handler2);
- $this->assertTrue($logger->isHandling(Level::Debug));
- }
- /**
- * @covers Level::Debug
- * @covers Level::Info
- * @covers Level::Notice
- * @covers Level::Warning
- * @covers Level::Error
- * @covers Level::Critical
- * @covers Level::Alert
- * @covers Level::Emergency
- */
- #[DataProvider('logMethodProvider')]
- public function testLogMethods(string $method, Level $expectedLevel)
- {
- $logger = new Logger('foo');
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->{$method}('test');
- list($record) = $handler->getRecords();
- $this->assertEquals($expectedLevel, $record->level);
- }
- public static function logMethodProvider()
- {
- return [
- // PSR-3 methods
- ['debug', Level::Debug],
- ['info', Level::Info],
- ['notice', Level::Notice],
- ['warning', Level::Warning],
- ['error', Level::Error],
- ['critical', Level::Critical],
- ['alert', Level::Alert],
- ['emergency', Level::Emergency],
- ];
- }
- /**
- * @covers Logger::setTimezone
- */
- #[DataProvider('setTimezoneProvider')]
- public function testSetTimezone($tz)
- {
- $logger = new Logger('foo');
- $logger->setTimezone($tz);
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->info('test');
- list($record) = $handler->getRecords();
- $this->assertEquals($tz, $record->datetime->getTimezone());
- }
- public static function setTimezoneProvider()
- {
- return array_map(
- function ($tz) {
- return [new \DateTimeZone($tz)];
- },
- \DateTimeZone::listIdentifiers()
- );
- }
- /**
- * @covers Logger::setTimezone
- * @covers DateTimeImmutable::__construct
- */
- public function testTimezoneIsRespectedInUTC()
- {
- foreach ([true, false] as $microseconds) {
- $logger = new Logger('foo');
- $logger->useMicrosecondTimestamps($microseconds);
- $tz = new \DateTimeZone('America/New_York');
- $logger->setTimezone($tz);
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $dt = new \DateTime('now', $tz);
- $logger->info('test');
- list($record) = $handler->getRecords();
- $this->assertEquals($tz, $record->datetime->getTimezone());
- $this->assertEquals($dt->format('Y/m/d H:i'), $record->datetime->format('Y/m/d H:i'), 'Time should match timezone with microseconds set to: '.var_export($microseconds, true));
- }
- }
- /**
- * @covers Logger::setTimezone
- * @covers DateTimeImmutable::__construct
- */
- public function testTimezoneIsRespectedInOtherTimezone()
- {
- date_default_timezone_set('CET');
- foreach ([true, false] as $microseconds) {
- $logger = new Logger('foo');
- $logger->useMicrosecondTimestamps($microseconds);
- $tz = new \DateTimeZone('America/New_York');
- $logger->setTimezone($tz);
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $dt = new \DateTime('now', $tz);
- $logger->info('test');
- list($record) = $handler->getRecords();
- $this->assertEquals($tz, $record->datetime->getTimezone());
- $this->assertEquals($dt->format('Y/m/d H:i'), $record->datetime->format('Y/m/d H:i'), 'Time should match timezone with microseconds set to: '.var_export($microseconds, true));
- }
- }
- public function tearDown(): void
- {
- date_default_timezone_set('UTC');
- }
- /**
- * @covers Logger::useMicrosecondTimestamps
- * @covers Logger::addRecord
- */
- #[DataProvider('useMicrosecondTimestampsProvider')]
- public function testUseMicrosecondTimestamps($micro, $assert, $assertFormat)
- {
- if (PHP_VERSION_ID === 70103) {
- $this->markTestSkipped();
- }
- $logger = new Logger('foo');
- $logger->useMicrosecondTimestamps($micro);
- $handler = new TestHandler;
- $logger->pushHandler($handler);
- $logger->info('test');
- list($record) = $handler->getRecords();
- $this->{$assert}('000000', $record->datetime->format('u'));
- $this->assertSame($record->datetime->format($assertFormat), (string) $record->datetime);
- }
- public static function useMicrosecondTimestampsProvider()
- {
- return [
- // this has a very small chance of a false negative (1/10^6)
- 'with microseconds' => [true, 'assertNotSame', 'Y-m-d\TH:i:s.uP'],
- // php 7.1 always includes microseconds, so we keep them in, but we format the datetime without
- 'without microseconds' => [false, 'assertNotSame', 'Y-m-d\TH:i:sP'],
- ];
- }
- public function testProcessorsDoNotInterfereBetweenHandlers()
- {
- $logger = new Logger('foo');
- $logger->pushHandler($t1 = new TestHandler());
- $logger->pushHandler($t2 = new TestHandler());
- $t1->pushProcessor(function (LogRecord $record) {
- $record->extra['foo'] = 'bar';
- return $record;
- });
- $logger->error('Foo');
- self::assertSame([], $t2->getRecords()[0]->extra);
- }
- /**
- * @covers Logger::setExceptionHandler
- */
- public function testSetExceptionHandler()
- {
- $logger = new Logger(__METHOD__);
- $this->assertNull($logger->getExceptionHandler());
- $callback = function ($ex) {
- };
- $logger->setExceptionHandler($callback);
- $this->assertEquals($callback, $logger->getExceptionHandler());
- }
- /**
- * @covers Logger::handleException
- */
- public function testDefaultHandleException()
- {
- $logger = new Logger(__METHOD__);
- $handler = $this->getMockBuilder('Monolog\Handler\HandlerInterface')->getMock();
- $handler->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $handler->expects($this->any())
- ->method('handle')
- ->will($this->throwException(new \Exception('Some handler exception')))
- ;
- $this->expectException(\Exception::class);
- $logger->pushHandler($handler);
- $logger->info('test');
- }
- /**
- * @covers Logger::handleException
- * @covers Logger::addRecord
- */
- public function testCustomHandleException()
- {
- $logger = new Logger(__METHOD__);
- $that = $this;
- $logger->setExceptionHandler(function ($e, $record) use ($that) {
- $that->assertEquals($e->getMessage(), 'Some handler exception');
- $that->assertInstanceOf(LogRecord::class, $record);
- $that->assertEquals($record->message, 'test');
- });
- $handler = $this->getMockBuilder('Monolog\Handler\HandlerInterface')->getMock();
- $handler->expects($this->any())
- ->method('isHandling')
- ->willReturn(true);
- $handler->expects($this->any())
- ->method('handle')
- ->will($this->throwException(new \Exception('Some handler exception')))
- ;
- $logger->pushHandler($handler);
- $logger->info('test');
- }
- public function testSerializable()
- {
- $logger = new Logger(__METHOD__);
- $copy = unserialize(serialize($logger));
- self::assertInstanceOf(Logger::class, $copy);
- self::assertSame($logger->getName(), $copy->getName());
- self::assertSame($logger->getTimezone()->getName(), $copy->getTimezone()->getName());
- self::assertSame($logger->getHandlers(), $copy->getHandlers());
- }
- public function testReset()
- {
- $logger = new Logger('app');
- $testHandler = new Handler\TestHandler();
- $testHandler->setSkipReset(true);
- $bufferHandler = new Handler\BufferHandler($testHandler);
- $groupHandler = new Handler\GroupHandler([$bufferHandler]);
- $fingersCrossedHandler = new Handler\FingersCrossedHandler($groupHandler);
- $logger->pushHandler($fingersCrossedHandler);
- $processorUid1 = new Processor\UidProcessor(10);
- $uid1 = $processorUid1->getUid();
- $groupHandler->pushProcessor($processorUid1);
- $processorUid2 = new Processor\UidProcessor(5);
- $uid2 = $processorUid2->getUid();
- $logger->pushProcessor($processorUid2);
- $getProperty = function ($object, $property) {
- $reflectionProperty = new \ReflectionProperty(\get_class($object), $property);
- return $reflectionProperty->getValue($object);
- };
- $assertBufferOfBufferHandlerEmpty = function () use ($getProperty, $bufferHandler) {
- self::assertEmpty($getProperty($bufferHandler, 'buffer'));
- };
- $assertBuffersEmpty = function () use ($assertBufferOfBufferHandlerEmpty, $getProperty, $fingersCrossedHandler) {
- $assertBufferOfBufferHandlerEmpty();
- self::assertEmpty($getProperty($fingersCrossedHandler, 'buffer'));
- };
- $logger->debug('debug1');
- $logger->reset();
- $assertBuffersEmpty();
- $this->assertFalse($testHandler->hasDebugRecords());
- $this->assertFalse($testHandler->hasErrorRecords());
- $this->assertNotSame($uid1, $uid1 = $processorUid1->getUid());
- $this->assertNotSame($uid2, $uid2 = $processorUid2->getUid());
- $logger->debug('debug2');
- $logger->error('error2');
- $logger->reset();
- $assertBuffersEmpty();
- $this->assertTrue($testHandler->hasRecordThatContains('debug2', Level::Debug));
- $this->assertTrue($testHandler->hasRecordThatContains('error2', Level::Error));
- $this->assertNotSame($uid1, $uid1 = $processorUid1->getUid());
- $this->assertNotSame($uid2, $uid2 = $processorUid2->getUid());
- $logger->info('info3');
- $this->assertNotEmpty($getProperty($fingersCrossedHandler, 'buffer'));
- $assertBufferOfBufferHandlerEmpty();
- $this->assertFalse($testHandler->hasInfoRecords());
- $logger->reset();
- $assertBuffersEmpty();
- $this->assertFalse($testHandler->hasInfoRecords());
- $this->assertNotSame($uid1, $uid1 = $processorUid1->getUid());
- $this->assertNotSame($uid2, $uid2 = $processorUid2->getUid());
- $logger->notice('notice4');
- $logger->emergency('emergency4');
- $logger->reset();
- $assertBuffersEmpty();
- $this->assertFalse($testHandler->hasInfoRecords());
- $this->assertTrue($testHandler->hasRecordThatContains('notice4', Level::Notice));
- $this->assertTrue($testHandler->hasRecordThatContains('emergency4', Level::Emergency));
- $this->assertNotSame($uid1, $processorUid1->getUid());
- $this->assertNotSame($uid2, $processorUid2->getUid());
- }
- /**
- * @covers Logger::addRecord
- */
- public function testLogWithDateTime()
- {
- foreach ([true, false] as $microseconds) {
- $logger = new Logger(__METHOD__);
- $loggingHandler = new LoggingHandler($logger);
- $testHandler = new TestHandler();
- $logger->pushHandler($loggingHandler);
- $logger->pushHandler($testHandler);
- $datetime = (new DateTimeImmutable($microseconds))->modify('2022-03-04 05:06:07');
- $logger->addRecord(Level::Debug, 'test', [], $datetime);
- list($record) = $testHandler->getRecords();
- $this->assertEquals($datetime->format('Y-m-d H:i:s'), $record->datetime->format('Y-m-d H:i:s'));
- }
- }
- public function testLogCycleDetectionWithFibersWithoutCycle()
- {
- $logger = new Logger(__METHOD__);
- $fiberSuspendHandler = new FiberSuspendHandler();
- $testHandler = new TestHandler();
- $logger->pushHandler($fiberSuspendHandler);
- $logger->pushHandler($testHandler);
- $fibers = [];
- for ($i = 0; $i < 10; $i++) {
- $fiber = new \Fiber(static function () use ($logger) {
- $logger->info('test');
- });
- $fiber->start();
- // We need to keep a reference here, because otherwise the fiber gets automatically cleaned up
- $fibers[] = $fiber;
- }
- self::assertCount(10, $testHandler->getRecords());
- }
- public function testLogCycleDetectionWithFibersWithCycle()
- {
- $logger = new Logger(__METHOD__);
- $fiberSuspendHandler = new FiberSuspendHandler();
- $loggingHandler = new LoggingHandler($logger);
- $testHandler = new TestHandler();
- $logger->pushHandler($fiberSuspendHandler);
- $logger->pushHandler($loggingHandler);
- $logger->pushHandler($testHandler);
- $fiber = new \Fiber(static function () use ($logger) {
- $logger->info('test');
- });
- $fiber->start();
- self::assertCount(3, $testHandler->getRecords());
- }
- }
- class LoggingHandler implements HandlerInterface
- {
- /**
- * @var Logger
- */
- private $logger;
- public function __construct(Logger $logger)
- {
- $this->logger = $logger;
- }
- public function isHandling(LogRecord $record): bool
- {
- return true;
- }
- public function handle(LogRecord $record): bool
- {
- $this->logger->debug('Log triggered while logging');
- return false;
- }
- public function handleBatch(array $records): void
- {
- }
- public function close(): void
- {
- }
- }
- class FiberSuspendHandler implements HandlerInterface
- {
- public function isHandling(LogRecord $record): bool
- {
- return true;
- }
- public function handle(LogRecord $record): bool
- {
- \Fiber::suspend();
- return true;
- }
- public function handleBatch(array $records): void
- {
- }
- public function close(): void
- {
- }
- }
|