44
55namespace Sentry \Tests \Monolog ;
66
7+ use Monolog \Level ;
78use Monolog \Logger ;
89use PHPUnit \Framework \TestCase ;
910use Sentry \ClientBuilder ;
10- use Sentry \Event ;
1111use Sentry \Logs \Log ;
1212use Sentry \Logs \LogLevel ;
1313use Sentry \Logs \Logs ;
1414use Sentry \Monolog \LogsHandler ;
1515use Sentry \SentrySdk ;
1616use Sentry \State \Hub ;
17- use Sentry \Transport \Result ;
18- use Sentry \Transport \ResultStatus ;
19- use Sentry \Transport \TransportInterface ;
17+ use Sentry \Tests \StubTransport ;
2018
2119final class LogsHandlerTest extends TestCase
2220{
@@ -64,42 +62,47 @@ static function (string $key) {
6462 }
6563
6664 /**
67- * @dataProvider logLevelDataProvider
65+ * @dataProvider monologLegacyLevelDataProvider
6866 */
69- public function testLogLevels ( $ record , int $ countLogs ): void
67+ public function testFiltersAndMapsUsingLegacyMonologThreshold ( int $ threshold , int $ recordLevel , int $ expectedCount , ? LogLevel $ expectedMappedLevel ): void
7068 {
71- $ handler = new LogsHandler (LogLevel:: warn () );
72- $ handler ->handle ($ record );
69+ $ handler = new LogsHandler ($ threshold );
70+ $ handler ->handle (RecordFactory:: create ( ' foo bar ' , $ recordLevel , ' channel.foo ' , [], []) );
7371
7472 $ logs = Logs::getInstance ()->aggregator ()->all ();
75- $ this ->assertCount ($ countLogs , $ logs );
73+ $ this ->assertCount ($ expectedCount , $ logs );
74+
75+ if ($ expectedMappedLevel !== null ) {
76+ $ this ->assertEquals ($ expectedMappedLevel , $ logs [0 ]->getLevel ());
77+ }
78+ }
79+
80+ /**
81+ * @dataProvider monologLevelDataProvider
82+ */
83+ public function testFiltersAndMapsUsingMonologEnumThreshold ($ threshold , $ recordLevel , int $ expectedCount , ?LogLevel $ expectedMappedLevel ): void
84+ {
85+ if (!class_exists (Level::class)) {
86+ $ this ->markTestSkipped ('Test only works for Monolog >= 3 ' );
87+ }
88+
89+ $ this ->assertInstanceOf (Level::class, $ threshold );
90+ $ this ->assertInstanceOf (Level::class, $ recordLevel );
91+
92+ $ handler = new LogsHandler ($ threshold );
93+ $ handler ->handle (RecordFactory::create ('foo bar ' , $ recordLevel ->value , 'channel.foo ' , [], []));
94+
95+ $ logs = Logs::getInstance ()->aggregator ()->all ();
96+ $ this ->assertCount ($ expectedCount , $ logs );
97+
98+ if ($ expectedMappedLevel !== null ) {
99+ $ this ->assertEquals ($ expectedMappedLevel , $ logs [0 ]->getLevel ());
100+ }
76101 }
77102
78103 public function testLogsHandlerDestructor ()
79104 {
80- $ transport = new class implements TransportInterface {
81- private $ events = [];
82-
83- public function send (Event $ event ): Result
84- {
85- $ this ->events [] = $ event ;
86-
87- return new Result (ResultStatus::success ());
88- }
89-
90- public function close (?int $ timeout = null ): Result
91- {
92- return new Result (ResultStatus::success ());
93- }
94-
95- /**
96- * @return Event[]
97- */
98- public function getEvents (): array
99- {
100- return $ this ->events ;
101- }
102- };
105+ $ transport = new StubTransport ();
103106 $ client = ClientBuilder::create ([
104107 'enable_logs ' => true ,
105108 ])->setTransport ($ transport )
@@ -110,8 +113,8 @@ public function getEvents(): array
110113
111114 $ this ->handleLogAndDrop ();
112115
113- $ this ->assertCount (1 , $ transport -> getEvents () );
114- $ this ->assertSame ('I was dropped :( ' , $ transport -> getEvents () [0 ]->getLogs ()[0 ]->getBody ());
116+ $ this ->assertCount (1 , StubTransport:: $ events );
117+ $ this ->assertSame ('I was dropped :( ' , StubTransport:: $ events [0 ]->getLogs ()[0 ]->getBody ());
115118 }
116119
117120 private function handleLogAndDrop (): void
@@ -283,83 +286,127 @@ public static function handleDataProvider(): iterable
283286 ];
284287 }
285288
286- public static function logLevelDataProvider (): iterable
289+ public static function monologLegacyLevelDataProvider (): iterable
287290 {
288- yield [
289- RecordFactory::create (
290- 'foo bar ' ,
291- Logger::DEBUG ,
292- 'channel.foo ' ,
293- [],
294- []
295- ),
291+ yield 'NOTICE threshold drops INFO (both map to sentry info) ' => [
292+ Logger::NOTICE ,
293+ Logger::INFO ,
296294 0 ,
295+ null ,
297296 ];
298297
299- yield [
300- RecordFactory::create (
301- 'foo bar ' ,
302- Logger::NOTICE ,
303- 'channel.foo ' ,
304- [],
305- []
306- ),
298+ yield 'NOTICE threshold keeps NOTICE (mapped to sentry info) ' => [
299+ Logger::NOTICE ,
300+ Logger::NOTICE ,
301+ 1 ,
302+ LogLevel::info (),
303+ ];
304+
305+ yield 'NOTICE threshold keeps WARNING (mapped to sentry warn) ' => [
306+ Logger::NOTICE ,
307+ Logger::WARNING ,
308+ 1 ,
309+ LogLevel::warn (),
310+ ];
311+
312+ yield 'ALERT threshold drops CRITICAL (both map to sentry fatal) ' => [
313+ Logger::ALERT ,
314+ Logger::CRITICAL ,
307315 0 ,
316+ null ,
308317 ];
309318
310- yield [
311- RecordFactory::create (
312- 'foo bar ' ,
313- Logger::INFO ,
314- 'channel.foo ' ,
315- [],
316- []
317- ),
319+ yield 'ALERT threshold keeps ALERT (mapped to sentry fatal) ' => [
320+ Logger::ALERT ,
321+ Logger::ALERT ,
322+ 1 ,
323+ LogLevel::fatal (),
324+ ];
325+
326+ yield 'ALERT threshold keeps EMERGENCY (mapped to sentry fatal) ' => [
327+ Logger::ALERT ,
328+ Logger::EMERGENCY ,
329+ 1 ,
330+ LogLevel::fatal (),
331+ ];
332+
333+ yield 'EMERGENCY threshold drops ALERT (both map to sentry fatal) ' => [
334+ Logger::EMERGENCY ,
335+ Logger::ALERT ,
318336 0 ,
337+ null ,
319338 ];
320339
321- yield [
322- RecordFactory::create (
323- 'foo bar ' ,
324- Logger::WARNING ,
325- 'channel.foo ' ,
326- [],
327- []
328- ),
340+ yield 'EMERGENCY threshold keeps EMERGENCY (mapped to sentry fatal) ' => [
341+ Logger::EMERGENCY ,
342+ Logger::EMERGENCY ,
329343 1 ,
344+ LogLevel::fatal (),
330345 ];
346+ }
331347
332- yield [
333- RecordFactory::create (
334- 'foo bar ' ,
335- Logger::CRITICAL ,
336- 'channel.foo ' ,
337- [],
338- []
339- ),
348+ public static function monologLevelDataProvider (): iterable
349+ {
350+ if (!class_exists (Level::class)) {
351+ yield 'Monolog < 3 (skipped) ' => [null , null , 0 , null ];
352+
353+ return ;
354+ }
355+
356+ yield 'NOTICE threshold drops INFO (both map to sentry info) ' => [
357+ Level::Notice,
358+ Level::Info,
359+ 0 ,
360+ null ,
361+ ];
362+
363+ yield 'NOTICE threshold keeps NOTICE (mapped to sentry info) ' => [
364+ Level::Notice,
365+ Level::Notice,
340366 1 ,
367+ LogLevel::info (),
341368 ];
342369
343- yield [
344- RecordFactory::create (
345- 'foo bar ' ,
346- Logger::ALERT ,
347- 'channel.foo ' ,
348- [],
349- []
350- ),
370+ yield 'NOTICE threshold keeps WARNING (mapped to sentry warn) ' => [
371+ Level::Notice,
372+ Level::Warning,
351373 1 ,
374+ LogLevel::warn (),
352375 ];
353376
354- yield [
355- RecordFactory::create (
356- 'foo bar ' ,
357- Logger::EMERGENCY ,
358- 'channel.foo ' ,
359- [],
360- []
361- ),
377+ yield 'ALERT threshold drops CRITICAL (both map to sentry fatal) ' => [
378+ Level::Alert,
379+ Level::Critical,
380+ 0 ,
381+ null ,
382+ ];
383+
384+ yield 'ALERT threshold keeps ALERT (mapped to sentry fatal) ' => [
385+ Level::Alert,
386+ Level::Alert,
387+ 1 ,
388+ LogLevel::fatal (),
389+ ];
390+
391+ yield 'ALERT threshold keeps EMERGENCY (mapped to sentry fatal) ' => [
392+ Level::Alert,
393+ Level::Emergency,
394+ 1 ,
395+ LogLevel::fatal (),
396+ ];
397+
398+ yield 'EMERGENCY threshold drops ALERT (both map to sentry fatal) ' => [
399+ Level::Emergency,
400+ Level::Alert,
401+ 0 ,
402+ null ,
403+ ];
404+
405+ yield 'EMERGENCY threshold keeps EMERGENCY (mapped to sentry fatal) ' => [
406+ Level::Emergency,
407+ Level::Emergency,
362408 1 ,
409+ LogLevel::fatal (),
363410 ];
364411 }
365412}
0 commit comments