MongoDBFormatterTest.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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\Formatter;
  11. use MongoDB\BSON\ObjectId;
  12. use MongoDB\BSON\Regex;
  13. use MongoDB\BSON\UTCDateTime;
  14. use Monolog\Level;
  15. use PHPUnit\Framework\Attributes\DataProvider;
  16. use PHPUnit\Framework\Attributes\RequiresPhpExtension;
  17. /**
  18. * @author Florian Plattner <me@florianplattner.de>
  19. */
  20. #[RequiresPhpExtension('mongodb')]
  21. class MongoDBFormatterTest extends \Monolog\Test\MonologTestCase
  22. {
  23. public static function constructArgumentProvider()
  24. {
  25. return [
  26. [1, true, 1, true],
  27. [0, false, 0, false],
  28. ];
  29. }
  30. #[DataProvider('constructArgumentProvider')]
  31. public function testConstruct($traceDepth, $traceAsString, $expectedTraceDepth, $expectedTraceAsString)
  32. {
  33. $formatter = new MongoDBFormatter($traceDepth, $traceAsString);
  34. $reflTrace = new \ReflectionProperty($formatter, 'exceptionTraceAsString');
  35. $this->assertEquals($expectedTraceAsString, $reflTrace->getValue($formatter));
  36. $reflDepth = new \ReflectionProperty($formatter, 'maxNestingLevel');
  37. $this->assertEquals($expectedTraceDepth, $reflDepth->getValue($formatter));
  38. }
  39. public function testSimpleFormat()
  40. {
  41. $record = $this->getRecord(
  42. message: 'some log message',
  43. level: Level::Warning,
  44. channel: 'test',
  45. datetime: new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'),
  46. );
  47. $formatter = new MongoDBFormatter();
  48. $formattedRecord = $formatter->format($record);
  49. $this->assertCount(7, $formattedRecord);
  50. $this->assertEquals('some log message', $formattedRecord['message']);
  51. $this->assertEquals([], $formattedRecord['context']);
  52. $this->assertEquals(Level::Warning->value, $formattedRecord['level']);
  53. $this->assertEquals(Level::Warning->getName(), $formattedRecord['level_name']);
  54. $this->assertEquals('test', $formattedRecord['channel']);
  55. $this->assertInstanceOf(UTCDateTime::class, $formattedRecord['datetime']);
  56. $this->assertEquals('1453410690123', $formattedRecord['datetime']->__toString());
  57. $this->assertEquals([], $formattedRecord['extra']);
  58. }
  59. public function testRecursiveFormat()
  60. {
  61. $someObject = new \stdClass();
  62. $someObject->foo = 'something';
  63. $someObject->bar = 'stuff';
  64. $record = $this->getRecord(
  65. message: 'some log message',
  66. context: [
  67. 'stuff' => new \DateTimeImmutable('1969-01-21T21:11:30.213000+00:00'),
  68. 'some_object' => $someObject,
  69. 'context_string' => 'some string',
  70. 'context_int' => 123456,
  71. 'except' => new \Exception('exception message', 987),
  72. ],
  73. level: Level::Warning,
  74. channel: 'test',
  75. datetime: new \DateTimeImmutable('2016-01-21T21:11:30.213000+00:00'),
  76. );
  77. $formatter = new MongoDBFormatter();
  78. $formattedRecord = $formatter->format($record);
  79. $this->assertCount(5, $formattedRecord['context']);
  80. $this->assertInstanceOf(UTCDateTime::class, $formattedRecord['context']['stuff']);
  81. $this->assertEquals('-29731710213', $formattedRecord['context']['stuff']->__toString());
  82. $this->assertEquals(
  83. [
  84. 'foo' => 'something',
  85. 'bar' => 'stuff',
  86. 'class' => 'stdClass',
  87. ],
  88. $formattedRecord['context']['some_object']
  89. );
  90. $this->assertEquals('some string', $formattedRecord['context']['context_string']);
  91. $this->assertEquals(123456, $formattedRecord['context']['context_int']);
  92. $this->assertCount(5, $formattedRecord['context']['except']);
  93. $this->assertEquals('exception message', $formattedRecord['context']['except']['message']);
  94. $this->assertEquals(987, $formattedRecord['context']['except']['code']);
  95. $this->assertIsString($formattedRecord['context']['except']['file']);
  96. $this->assertIsInt($formattedRecord['context']['except']['code']);
  97. $this->assertIsString($formattedRecord['context']['except']['trace']);
  98. $this->assertEquals('Exception', $formattedRecord['context']['except']['class']);
  99. }
  100. public function testFormatDepthArray()
  101. {
  102. $record = $this->getRecord(
  103. message: 'some log message',
  104. context: [
  105. 'nest2' => [
  106. 'property' => 'anything',
  107. 'nest3' => [
  108. 'nest4' => 'value',
  109. 'property' => 'nothing',
  110. ],
  111. ],
  112. ],
  113. level: Level::Warning,
  114. channel: 'test',
  115. datetime: new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'),
  116. );
  117. $formatter = new MongoDBFormatter(2);
  118. $formattedResult = $formatter->format($record);
  119. $this->assertEquals(
  120. [
  121. 'nest2' => [
  122. 'property' => 'anything',
  123. 'nest3' => '[...]',
  124. ],
  125. ],
  126. $formattedResult['context']
  127. );
  128. }
  129. public function testFormatDepthArrayInfiniteNesting()
  130. {
  131. $record = $this->getRecord(
  132. message: 'some log message',
  133. context: [
  134. 'nest2' => [
  135. 'property' => 'something',
  136. 'nest3' => [
  137. 'property' => 'anything',
  138. 'nest4' => [
  139. 'property' => 'nothing',
  140. ],
  141. ],
  142. ],
  143. ],
  144. level: Level::Warning,
  145. channel: 'test',
  146. datetime: new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'),
  147. );
  148. $formatter = new MongoDBFormatter(0);
  149. $formattedResult = $formatter->format($record);
  150. $this->assertEquals(
  151. [
  152. 'nest2' => [
  153. 'property' => 'something',
  154. 'nest3' => [
  155. 'property' => 'anything',
  156. 'nest4' => [
  157. 'property' => 'nothing',
  158. ],
  159. ],
  160. ],
  161. ],
  162. $formattedResult['context']
  163. );
  164. }
  165. public function testFormatDepthObjects()
  166. {
  167. $someObject = new \stdClass();
  168. $someObject->property = 'anything';
  169. $someObject->nest3 = new \stdClass();
  170. $someObject->nest3->property = 'nothing';
  171. $someObject->nest3->nest4 = 'invisible';
  172. $record = $this->getRecord(
  173. message: 'some log message',
  174. context: [
  175. 'nest2' => $someObject,
  176. ],
  177. level: Level::Warning,
  178. channel: 'test',
  179. datetime: new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'),
  180. );
  181. $formatter = new MongoDBFormatter(2, true);
  182. $formattedResult = $formatter->format($record);
  183. $this->assertEquals(
  184. [
  185. 'nest2' => [
  186. 'property' => 'anything',
  187. 'nest3' => '[...]',
  188. 'class' => 'stdClass',
  189. ],
  190. ],
  191. $formattedResult['context']
  192. );
  193. }
  194. public function testFormatDepthException()
  195. {
  196. $record = $this->getRecord(
  197. message: 'some log message',
  198. context: [
  199. 'nest2' => new \Exception('exception message', 987),
  200. ],
  201. level: Level::Warning,
  202. channel: 'test',
  203. datetime: new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'),
  204. );
  205. $formatter = new MongoDBFormatter(2, false);
  206. $formattedRecord = $formatter->format($record);
  207. $this->assertEquals('exception message', $formattedRecord['context']['nest2']['message']);
  208. $this->assertEquals(987, $formattedRecord['context']['nest2']['code']);
  209. $this->assertEquals('[...]', $formattedRecord['context']['nest2']['trace']);
  210. }
  211. public function testBsonTypes()
  212. {
  213. $record = $this->getRecord(
  214. message: 'some log message',
  215. context: [
  216. 'objectid' => new ObjectId(),
  217. 'nest' => [
  218. 'timestamp' => new UTCDateTime(),
  219. 'regex' => new Regex('pattern'),
  220. ],
  221. ],
  222. level: Level::Warning,
  223. channel: 'test',
  224. datetime: new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'),
  225. );
  226. $formatter = new MongoDBFormatter();
  227. $formattedRecord = $formatter->format($record);
  228. $this->assertInstanceOf(ObjectId::class, $formattedRecord['context']['objectid']);
  229. $this->assertInstanceOf(UTCDateTime::class, $formattedRecord['context']['nest']['timestamp']);
  230. $this->assertInstanceOf(Regex::class, $formattedRecord['context']['nest']['regex']);
  231. }
  232. }