1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-08-10 23:24:02 +02:00

Merge branch 'master' into feature/elasticsearch

# Conflicts:
#	composer.json
#	src/Monolog/Handler/ElasticSearchHandler.php
This commit is contained in:
Avtandil Kikabidze
2018-06-24 20:43:55 +04:00
83 changed files with 1210 additions and 336 deletions

View File

@@ -40,7 +40,7 @@ class FluentdFormatterTest extends TestCase
$formatter = new FluentdFormatter();
$this->assertEquals(
'["test",0,{"message":"test","extra":[],"level":300,"level_name":"WARNING"}]',
'["test",0,{"message":"test","context":[],"extra":[],"level":300,"level_name":"WARNING"}]',
$formatter->format($record)
);
}
@@ -55,7 +55,7 @@ class FluentdFormatterTest extends TestCase
$formatter = new FluentdFormatter(true);
$this->assertEquals(
'["test.error",0,{"message":"test","extra":[]}]',
'["test.error",0,{"message":"test","context":[],"extra":[]}]',
$formatter->format($record)
);
}

View File

@@ -234,7 +234,7 @@ class GelfMessageFormatterTest extends \PHPUnit\Framework\TestCase
'context' => array('exception' => str_repeat(' ', 32767 * 2)),
'datetime' => new \DateTime("@0"),
'extra' => array('key' => str_repeat(' ', 32767 * 2)),
'message' => 'log'
'message' => 'log',
);
$message = $formatter->format($record);
$messageArray = $message->toArray();

View File

@@ -38,11 +38,12 @@ class JsonFormatterTest extends TestCase
{
$formatter = new JsonFormatter();
$record = $this->getRecord();
$record['context'] = $record['extra'] = new \stdClass;
$this->assertEquals(json_encode($record)."\n", $formatter->format($record));
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
$record = $this->getRecord();
$this->assertEquals('{"message":"test","context":[],"level":300,"level_name":"WARNING","channel":"test","datetime":"'.$record['datetime']->format('Y-m-d\TH:i:s.uP').'","extra":[]}', $formatter->format($record));
$this->assertEquals('{"message":"test","context":{},"level":300,"level_name":"WARNING","channel":"test","datetime":"'.$record['datetime']->format('Y-m-d\TH:i:s.uP').'","extra":{}}', $formatter->format($record));
}
/**
@@ -71,6 +72,7 @@ class JsonFormatterTest extends TestCase
$this->getRecord(Logger::DEBUG),
];
array_walk($expected, function (&$value, $key) {
$value['context'] = $value['extra'] = new \stdClass;
$value = json_encode($value);
});
$this->assertEquals(implode("\n", $expected), $formatter->formatBatch($records));
@@ -110,6 +112,47 @@ class JsonFormatterTest extends TestCase
$this->assertContextContainsFormattedException($formattedThrowable, $message);
}
public function testMaxNormalizeDepth()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(1);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertContextContainsFormattedException('"Over 1 levels deep, aborting normalization"', $message);
}
public function testMaxNormalizeItemCountWith0ItemsMax()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(0);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'{"...":"Over 0 items (6 total), aborting normalization"}'."\n",
$message
);
}
public function testMaxNormalizeItemCountWith2ItemsMax()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(2);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'{"level_name":"CRITICAL","channel":"core","...":"Over 2 items (6 total), aborting normalization"}'."\n",
$message
);
}
/**
* @param string $expected
* @param string $actual
@@ -119,18 +162,18 @@ class JsonFormatterTest extends TestCase
private function assertContextContainsFormattedException($expected, $actual)
{
$this->assertEquals(
'{"level_name":"CRITICAL","channel":"core","context":{"exception":'.$expected.'},"datetime":null,"extra":[],"message":"foobar"}'."\n",
'{"level_name":"CRITICAL","channel":"core","context":{"exception":'.$expected.'},"datetime":null,"extra":{},"message":"foobar"}'."\n",
$actual
);
}
/**
* @param JsonFormatter $formatter
* @param \Exception|\Throwable $exception
* @param JsonFormatter $formatter
* @param \Throwable $exception
*
* @return string
*/
private function formatRecordWithExceptionInContext(JsonFormatter $formatter, $exception)
private function formatRecordWithExceptionInContext(JsonFormatter $formatter, \Throwable $exception)
{
$message = $formatter->format([
'level_name' => 'CRITICAL',
@@ -176,4 +219,40 @@ class JsonFormatterTest extends TestCase
return $formattedException;
}
public function testNormalizeHandleLargeArraysWithExactly1000Items()
{
$formatter = new NormalizerFormatter();
$largeArray = range(1, 1000);
$res = $formatter->format(array(
'level_name' => 'CRITICAL',
'channel' => 'test',
'message' => 'bar',
'context' => array($largeArray),
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertCount(1000, $res['context'][0]);
$this->assertArrayNotHasKey('...', $res['context'][0]);
}
public function testNormalizeHandleLargeArrays()
{
$formatter = new NormalizerFormatter();
$largeArray = range(1, 2000);
$res = $formatter->format(array(
'level_name' => 'CRITICAL',
'channel' => 'test',
'message' => 'bar',
'context' => array($largeArray),
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertCount(1001, $res['context'][0]);
$this->assertEquals('Over 1000 items (2000 total), aborting normalization', $res['context'][0]['...']);
}
}

View File

@@ -170,7 +170,7 @@ class LineFormatterTest extends \PHPUnit\Framework\TestCase
$path = str_replace('\\/', '/', json_encode(__FILE__));
$this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).', LogicException(code: 0): Wut? at '.substr($path, 1, -1).':'.(__LINE__ - 12).')"} []'."\n", $message);
$this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).')\n[previous exception] [object] (LogicException(code: 0): Wut? at '.substr($path, 1, -1).':'.(__LINE__ - 12).')"} []'."\n", $message);
}
public function testBatchFormat()

View File

@@ -17,7 +17,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
{
public function tearDown()
{
\PHPUnit_Framework_Error_Warning::$enabled = true;
\PHPUnit\Framework\Error\Warning::$enabled = true;
return parent::tearDown();
}
@@ -27,7 +27,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testDefaultFormatterV1()
{
$formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_');
$formatter = new LogstashFormatter('test', 'hostname');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -49,7 +49,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('test', $message['type']);
$this->assertEquals('hostname', $message['host']);
$formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_');
$formatter = new LogstashFormatter('mysystem');
$message = json_decode($formatter->format($record), true);
@@ -61,7 +61,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testFormatWithFileAndLineV1()
{
$formatter = new LogstashFormatter('test', null, null, 'ctxt_');
$formatter = new LogstashFormatter('test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -83,7 +83,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testFormatWithContextV1()
{
$formatter = new LogstashFormatter('test', null, null, 'ctxt_');
$formatter = new LogstashFormatter('test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -96,17 +96,17 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
$message = json_decode($formatter->format($record), true);
$this->assertArrayHasKey('ctxt_context', $message);
$this->assertArrayHasKey('from', $message['ctxt_context']);
$this->assertEquals('logger', $message['ctxt_context']['from']);
$this->assertArrayHasKey('context', $message);
$this->assertArrayHasKey('from', $message['context']);
$this->assertEquals('logger', $message['context']['from']);
// Test with extraPrefix
$formatter = new LogstashFormatter('test', null, null, 'CTX');
$formatter = new LogstashFormatter('test', null, 'extra', 'CTX');
$message = json_decode($formatter->format($record), true);
$this->assertArrayHasKey('CTXcontext', $message);
$this->assertArrayHasKey('from', $message['CTXcontext']);
$this->assertEquals('logger', $message['CTXcontext']['from']);
$this->assertArrayHasKey('CTX', $message);
$this->assertArrayHasKey('from', $message['CTX']);
$this->assertEquals('logger', $message['CTX']['from']);
}
/**
@@ -114,7 +114,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testFormatWithExtraV1()
{
$formatter = new LogstashFormatter('test', null, null, 'ctxt_');
$formatter = new LogstashFormatter('test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -132,17 +132,17 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('pair', $message['extra']['key']);
// Test with extraPrefix
$formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_');
$formatter = new LogstashFormatter('test', null, 'EXTRA');
$message = json_decode($formatter->format($record), true);
$this->assertArrayHasKey('EXTextra', $message);
$this->assertArrayHasKey('key', $message['EXTextra']);
$this->assertEquals('pair', $message['EXTextra']['key']);
$this->assertArrayHasKey('EXTRA', $message);
$this->assertArrayHasKey('key', $message['EXTRA']);
$this->assertEquals('pair', $message['EXTRA']['key']);
}
public function testFormatWithApplicationNameV1()
{
$formatter = new LogstashFormatter('app', 'test', null, 'ctxt_');
$formatter = new LogstashFormatter('app', 'test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',

View File

@@ -18,7 +18,7 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
{
public function tearDown()
{
\PHPUnit_Framework_Error_Warning::$enabled = true;
\PHPUnit\Framework\Error\Warning::$enabled = true;
return parent::tearDown();
}
@@ -227,6 +227,24 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertEquals(@json_encode([$resource]), $res);
}
public function testNormalizeHandleLargeArraysWithExactly1000Items()
{
$formatter = new NormalizerFormatter();
$largeArray = range(1, 1000);
$res = $formatter->format(array(
'level_name' => 'CRITICAL',
'channel' => 'test',
'message' => 'bar',
'context' => array($largeArray),
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertCount(1000, $res['context'][0]);
$this->assertArrayNotHasKey('...', $res['context'][0]);
}
public function testNormalizeHandleLargeArrays()
{
$formatter = new NormalizerFormatter();
@@ -241,7 +259,7 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
'extra' => array(),
));
$this->assertCount(1000, $res['context'][0]);
$this->assertCount(1001, $res['context'][0]);
$this->assertEquals('Over 1000 items (2000 total), aborting normalization', $res['context'][0]['...']);
}
@@ -271,6 +289,48 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertSame('{"message":"€ŠšŽžŒœŸ"}', $res);
}
public function testMaxNormalizeDepth()
{
$formatter = new NormalizerFormatter();
$formatter->setMaxNormalizeDepth(1);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'Over 1 levels deep, aborting normalization',
$message['context']['exception']
);
}
public function testMaxNormalizeItemCountWith0ItemsMax()
{
$formatter = new NormalizerFormatter();
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(0);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
["..." => "Over 0 items (6 total), aborting normalization"],
$message
);
}
public function testMaxNormalizeItemCountWith3ItemsMax()
{
$formatter = new NormalizerFormatter();
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(2);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
["level_name" => "CRITICAL", "channel" => "core", "..." => "Over 2 items (6 total), aborting normalization"],
$message
);
}
/**
* @param mixed $in Input
* @param mixed $expect Expected output
@@ -333,10 +393,6 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
// and no file or line are included in the trace because it's treated as internal function
public function testExceptionTraceWithArgs()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('Not supported in HHVM since it detects errors differently');
}
try {
// This will contain $resource and $wrappedResource as arguments in the trace item
$resource = fopen('php://memory', 'rw+');
@@ -356,19 +412,54 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
$record = ['context' => ['exception' => $e]];
$result = $formatter->format($record);
$this->assertRegExp(
'%\[resource\(stream\)\]%',
$this->assertSame(
'{"function":"Monolog\\\\Formatter\\\\{closure}","class":"Monolog\\\\Formatter\\\\NormalizerFormatterTest","type":"->","args":["[object] (Monolog\\\\Formatter\\\\TestFooNorm)","[resource(stream)]"]}',
$result['context']['exception']['trace'][0]
);
}
$pattern = '%\[\{"Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm":"JSON_ERROR"\}%';
/**
* @param NormalizerFormatter $formatter
* @param \Throwable $exception
*
* @return string
*/
private function formatRecordWithExceptionInContext(NormalizerFormatter $formatter, \Throwable $exception)
{
$message = $formatter->format([
'level_name' => 'CRITICAL',
'channel' => 'core',
'context' => ['exception' => $exception],
'datetime' => null,
'extra' => [],
'message' => 'foobar',
]);
// Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4
$this->assertRegExp(
$pattern,
return $message;
}
public function testExceptionTraceDoesNotLeakCallUserFuncArgs()
{
try {
$arg = new TestInfoLeak;
call_user_func(array($this, 'throwHelper'), $arg, $dt = new \DateTime());
} catch (\Exception $e) {
}
$formatter = new NormalizerFormatter();
$record = array('context' => array('exception' => $e));
$result = $formatter->format($record);
$this->assertSame(
'{"function":"throwHelper","class":"Monolog\\\\Formatter\\\\NormalizerFormatterTest","type":"->","args":["[object] (Monolog\\\\Formatter\\\\TestInfoLeak)","'.$dt->format('Y-m-d\TH:i:sP').'"]}',
$result['context']['exception']['trace'][0]
);
}
private function throwHelper($arg)
{
throw new \RuntimeException('Thrown');
}
}
class TestFooNorm
@@ -410,3 +501,11 @@ class TestToStringError
throw new \RuntimeException('Could not convert to string');
}
}
class TestInfoLeak
{
public function __toString()
{
return 'Sensitive information';
}
}