From 864bda5d67dba1f89e9efd549d317207783228c4 Mon Sep 17 00:00:00 2001 From: Westin Shafer Date: Tue, 11 Jul 2017 14:14:04 -0600 Subject: [PATCH 01/80] Update AmqpHandler Docs Update AmqpHandler docs to reflect that https://github.com/php-amqplib/php-amqplib can be used in place of ext php-amqp --- doc/02-handlers-formatters-processors.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/02-handlers-formatters-processors.md b/doc/02-handlers-formatters-processors.md index 9987908c..3fc74499 100644 --- a/doc/02-handlers-formatters-processors.md +++ b/doc/02-handlers-formatters-processors.md @@ -45,8 +45,9 @@ - [_SocketHandler_](../src/Monolog/Handler/SocketHandler.php): Logs records to [sockets](http://php.net/fsockopen), use this for UNIX and TCP sockets. See an [example](sockets.md). -- [_AmqpHandler_](../src/Monolog/Handler/AmqpHandler.php): Logs records to an [amqp](http://www.amqp.org/) compatible - server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+). +- [_AmqpHandler_](../src/Monolog/Handler/AmqpHandler.php): Logs records to an [AMQP](http://www.amqp.org/) compatible + server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+) or + [php-amqplib](https://github.com/php-amqplib/php-amqplib) library. - [_GelfHandler_](../src/Monolog/Handler/GelfHandler.php): Logs records to a [Graylog2](http://www.graylog2.org) server. - [_CubeHandler_](../src/Monolog/Handler/CubeHandler.php): Logs records to a [Cube](http://square.github.com/cube/) server. - [_RavenHandler_](../src/Monolog/Handler/RavenHandler.php): Logs records to a [Sentry](http://getsentry.com/) server using From a4973fade6e3629eb242854e4e689d76887fa2a3 Mon Sep 17 00:00:00 2001 From: dis1 Date: Thu, 13 Jul 2017 11:50:43 +0300 Subject: [PATCH 02/80] fix-for-slack-record-encoding --- src/Monolog/Handler/Slack/SlackRecord.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Handler/Slack/SlackRecord.php b/src/Monolog/Handler/Slack/SlackRecord.php index d9e6a4cb..8abb5918 100644 --- a/src/Monolog/Handler/Slack/SlackRecord.php +++ b/src/Monolog/Handler/Slack/SlackRecord.php @@ -211,8 +211,8 @@ class SlackRecord $hasNonNumericKeys = !count(array_filter(array_keys($normalized), 'is_numeric')); return $hasSecondDimension || $hasNonNumericKeys - ? json_encode($normalized, $prettyPrintFlag) - : json_encode($normalized); + ? json_encode($normalized, $prettyPrintFlag|JSON_UNESCAPED_UNICODE) + : json_encode($normalized, JSON_UNESCAPED_UNICODE); } /** From 207c91699e8e50a4837b92e17e9919a2bf0573db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Par=C3=A9?= Date: Tue, 27 Jun 2017 23:29:27 +0200 Subject: [PATCH 03/80] Custom exception handler (#500) Add custom exception handler to let the user change the default behavior when Monolog raise an exception while logging a record. --- src/Monolog/Logger.php | 65 ++++++++++++++++++++++++++++----- tests/Monolog/LoggerTest.php | 69 ++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 8 deletions(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 49d00af1..8686c8aa 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -133,6 +133,11 @@ class Logger implements LoggerInterface */ protected $microsecondTimestamps = true; + /** + * @var callable + */ + protected $exceptionHandler; + /** * @param string $name The logging channel * @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc. @@ -329,16 +334,20 @@ class Logger implements LoggerInterface 'extra' => array(), ); - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } - - while ($handler = current($this->handlers)) { - if (true === $handler->handle($record)) { - break; + try { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); } - next($this->handlers); + while ($handler = current($this->handlers)) { + if (true === $handler->handle($record)) { + break; + } + + next($this->handlers); + } + } catch (\Exception $ex) { + $this->handleException($ex, $record); } return true; @@ -501,6 +510,46 @@ class Logger implements LoggerInterface return false; } + /** + * Set a custom exception handler + * + * @param callable $callback + * @return $this + */ + public function setExceptionHandler($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Exception handler must be valid callable (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + $this->exceptionHandler = $callback; + + return $this; + } + + /** + * @return callable + */ + public function getExceptionHandler() + { + return $this->exceptionHandler; + } + + /** + * Delegates exception management to the custom exception handler, + * or throws the exception if no custom handler is set. + * + * @param Exception $ex + * @param array $record + */ + protected function handleException(\Exception $ex, $record) + { + if ($this->exceptionHandler) { + call_user_func($this->exceptionHandler, $ex, $record); + } else { + throw $ex; + } + } + /** * Adds a log record at an arbitrary level. * diff --git a/tests/Monolog/LoggerTest.php b/tests/Monolog/LoggerTest.php index 1ecc34a0..f938ea02 100644 --- a/tests/Monolog/LoggerTest.php +++ b/tests/Monolog/LoggerTest.php @@ -545,4 +545,73 @@ class LoggerTest extends \PHPUnit_Framework_TestCase 'without microseconds' => array(false, PHP_VERSION_ID >= 70100 ? 'assertNotSame' : 'assertSame'), ); } + + /** + * @covers Monolog\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 Monolog\Logger::setExceptionHandler + * @expectedException InvalidArgumentException + */ + public function testBadExceptionHandlerType() + { + $logger = new Logger(__METHOD__); + $logger->setExceptionHandler(false); + } + + /** + * @covers Monolog\Logger::handleException + * @expectedException Exception + */ + public function testDefaultHandleException() + { + $logger = new Logger(__METHOD__); + $handler = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler->expects($this->any()) + ->method('handle') + ->will($this->throwException(new \Exception('Some handler exception'))) + ; + $logger->pushHandler($handler); + $logger->info('test'); + } + + /** + * @covers Monolog\Logger::handleException + * @covers Monolog\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->assertTrue(is_array($record)); + $that->assertEquals($record['message'], 'test'); + }); + $handler = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler->expects($this->any()) + ->method('handle') + ->will($this->throwException(new \Exception('Some handler exception'))) + ; + $logger->pushHandler($handler); + $logger->info('test'); + } } From 548309c2c12474e394089dcbee208a8d29725cc8 Mon Sep 17 00:00:00 2001 From: Honza Machala Date: Tue, 25 Jul 2017 01:09:16 +0200 Subject: [PATCH 04/80] Check maximum allowed size of sqs message and send smaller portion of it, when size is exceeded --- src/Monolog/Handler/SqsHandler.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Monolog/Handler/SqsHandler.php b/src/Monolog/Handler/SqsHandler.php index 01c70dce..3b2a713d 100644 --- a/src/Monolog/Handler/SqsHandler.php +++ b/src/Monolog/Handler/SqsHandler.php @@ -21,6 +21,12 @@ use Monolog\Logger; */ class SqsHandler extends AbstractProcessingHandler { + + /** 256 KB in bytes - maximum message size in SQS */ + const MAX_MESSAGE_SIZE = 262144; + /** 100 KB in bytes - head message size for new error log */ + const HEAD_MESSAGE_SIZE = 102400; + /** @var SqsClient */ private $client; /** @var string */ @@ -45,9 +51,14 @@ class SqsHandler extends AbstractProcessingHandler throw new \InvalidArgumentException('SqsHandler accepts only formatted records as a string'); } + $messageBody = $record['formatted']; + if (strlen($messageBody) >= self::MAX_MESSAGE_SIZE) { + $messageBody = substr($messageBody, 0, self::HEAD_MESSAGE_SIZE); + } + $this->client->sendMessage([ 'QueueUrl' => $this->queueUrl, - 'MessageBody' => $record['formatted'], + 'MessageBody' => $messageBody, ]); } } From c7eb1a0f7524ac8085d45fcb864f93416aa43bb8 Mon Sep 17 00:00:00 2001 From: Fabrizio Castellarin Date: Thu, 10 Aug 2017 15:40:55 +0200 Subject: [PATCH 05/80] Remove misleading reference to RFC 5424 standard --- src/Monolog/Logger.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 88ecf0dc..748b1456 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -87,8 +87,6 @@ class Logger implements LoggerInterface const API = 2; /** - * Logging levels from syslog protocol defined in RFC 5424 - * * This is a static variable and not a constant to serve as an extension point for custom levels * * @var string[] $levels Logging levels with the levels as key From 889b25a72bef53f05e0a54fe2d5a5443c4936344 Mon Sep 17 00:00:00 2001 From: mahone3297 <329730566@qq.com> Date: Mon, 14 Aug 2017 14:19:59 +0800 Subject: [PATCH 06/80] [feature] add host processor --- doc/02-handlers-formatters-processors.md | 1 + src/Monolog/Processor/HostnameProcessor.php | 34 +++++++++++++++++++ .../Processor/HostnameProcessorTest.php | 30 ++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 src/Monolog/Processor/HostnameProcessor.php create mode 100644 tests/Monolog/Processor/HostnameProcessorTest.php diff --git a/doc/02-handlers-formatters-processors.md b/doc/02-handlers-formatters-processors.md index 9987908c..92ba360b 100644 --- a/doc/02-handlers-formatters-processors.md +++ b/doc/02-handlers-formatters-processors.md @@ -155,6 +155,7 @@ - [_GitProcessor_](../src/Monolog/Processor/GitProcessor.php): Adds the current git branch and commit to a log record. - [_MercurialProcessor_](../src/Monolog/Processor/MercurialProcessor.php): Adds the current hg branch and commit to a log record. - [_TagProcessor_](../src/Monolog/Processor/TagProcessor.php): Adds an array of predefined tags to a log record. +- [_HostnameProcessor_](../src/Monolog/Processor/HostnameProcessor.php): Adds the current hostname to a log record. ## Third Party Packages diff --git a/src/Monolog/Processor/HostnameProcessor.php b/src/Monolog/Processor/HostnameProcessor.php new file mode 100644 index 00000000..23ddaf48 --- /dev/null +++ b/src/Monolog/Processor/HostnameProcessor.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\Logger; + +/** + * Injects value of gethostname in all records + */ +class HostnameProcessor +{ + private static $host; + + public function __construct() + { + self::$host = (string) gethostname(); + } + + public function __invoke(array $record): array + { + $record['extra']['hostname'] = self::$host; + + return $record; + } +} diff --git a/tests/Monolog/Processor/HostnameProcessorTest.php b/tests/Monolog/Processor/HostnameProcessorTest.php new file mode 100644 index 00000000..1659851b --- /dev/null +++ b/tests/Monolog/Processor/HostnameProcessorTest.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\Test\TestCase; + +class HostnameProcessorTest extends TestCase +{ + /** + * @covers Monolog\Processor\HostnameProcessor::__invoke + */ + public function testProcessor() + { + $processor = new HostnameProcessor(); + $record = $processor($this->getRecord()); + $this->assertArrayHasKey('hostname', $record['extra']); + $this->assertInternalType('string', $record['extra']['hostname']); + $this->assertNotEmpty($record['extra']['hostname']); + $this->assertEquals(gethostname(), $record['extra']['hostname']); + } +} From 009d4151b4189da9367a344b727166bbe1f5eb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ch=C3=A1bek?= Date: Mon, 21 Aug 2017 09:55:09 +0200 Subject: [PATCH 07/80] PsrLogMessageProcessor: add option to remove used context fields --- .../Processor/PsrLogMessageProcessor.php | 24 +++++++++++++++---- .../Processor/PsrLogMessageProcessorTest.php | 14 +++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/Monolog/Processor/PsrLogMessageProcessor.php b/src/Monolog/Processor/PsrLogMessageProcessor.php index 80784038..a10cd76c 100644 --- a/src/Monolog/Processor/PsrLogMessageProcessor.php +++ b/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -24,12 +24,17 @@ class PsrLogMessageProcessor private $dateFormat; + /** @var bool */ + private $removeUsedContextFields; + /** * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + * @param bool $removeUsedContextFields If set to true the fields interpolated into message gets unset */ - public function __construct(string $dateFormat = null) + public function __construct(string $dateFormat = null, bool $removeUsedContextFields = false) { $this->dateFormat = null === $dateFormat ? static::SIMPLE_DATE : $dateFormat; + $this->removeUsedContextFields = $removeUsedContextFields; } /** @@ -44,14 +49,23 @@ class PsrLogMessageProcessor $replacements = []; foreach ($record['context'] as $key => $val) { + $placeholder = '{' . $key . '}'; + if (strpos($record['message'], $placeholder) === false) { + continue; + } + if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) { - $replacements['{'.$key.'}'] = $val; + $replacements[$placeholder] = $val; } elseif ($val instanceof \DateTimeInterface) { - $replacements['{'.$key.'}'] = $val->format($this->dateFormat); + $replacements[$placeholder] = $val->format($this->dateFormat); } elseif (is_object($val)) { - $replacements['{'.$key.'}'] = '[object '.get_class($val).']'; + $replacements[$placeholder] = '[object '.get_class($val).']'; } else { - $replacements['{'.$key.'}'] = '['.gettype($val).']'; + $replacements[$placeholder] = '['.gettype($val).']'; + } + + if ($this->removeUsedContextFields) { + unset($record['context'][$key]); } } diff --git a/tests/Monolog/Processor/PsrLogMessageProcessorTest.php b/tests/Monolog/Processor/PsrLogMessageProcessorTest.php index 5071d892..60fafc64 100644 --- a/tests/Monolog/Processor/PsrLogMessageProcessorTest.php +++ b/tests/Monolog/Processor/PsrLogMessageProcessorTest.php @@ -25,6 +25,19 @@ class PsrLogMessageProcessorTest extends \PHPUnit\Framework\TestCase 'context' => ['foo' => $val], ]); $this->assertEquals($expected, $message['message']); + $this->assertSame(['foo' => $val], $message['context']); + } + + public function testReplacementWithContextRemoval() + { + $proc = new PsrLogMessageProcessor($dateFormat = null, $removeUsedContextFields = true); + + $message = $proc([ + 'message' => '{foo}', + 'context' => ['foo' => 'bar', 'lorem' => 'ipsum'], + ]); + $this->assertSame('bar', $message['message']); + $this->assertSame(['lorem' => 'ipsum'], $message['context']); } public function testCustomDateFormat() @@ -39,6 +52,7 @@ class PsrLogMessageProcessorTest extends \PHPUnit\Framework\TestCase 'context' => ['foo' => $date], ]); $this->assertEquals($date->format($format), $message['message']); + $this->assertSame(['foo' => $date], $message['context']); } public function getPairs() From 81db432c02406825fa5a0be2b3decb274b0fcd2e Mon Sep 17 00:00:00 2001 From: gmsantos Date: Sun, 10 Sep 2017 00:10:30 -0300 Subject: [PATCH 08/80] Include insightops handler --- doc/02-handlers-formatters-processors.md | 1 + src/Monolog/Handler/InsightOpsHandler.php | 62 ++++++++++++++ .../Monolog/Handler/InsightOpsHandlerTest.php | 80 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 src/Monolog/Handler/InsightOpsHandler.php create mode 100644 tests/Monolog/Handler/InsightOpsHandlerTest.php diff --git a/doc/02-handlers-formatters-processors.md b/doc/02-handlers-formatters-processors.md index bea968ac..af45913a 100644 --- a/doc/02-handlers-formatters-processors.md +++ b/doc/02-handlers-formatters-processors.md @@ -55,6 +55,7 @@ - _RollbarHandler_: Logs records to a [Rollbar](https://rollbar.com/) account. - _SyslogUdpHandler_: Logs records to a remote [Syslogd](http://www.rsyslog.com/) server. - _LogEntriesHandler_: Logs records to a [LogEntries](http://logentries.com/) account. +- _InsightOpsHandler_: Logs records to a [InsightOps](https://www.rapid7.com/products/insightops/) account. ### Logging in development diff --git a/src/Monolog/Handler/InsightOpsHandler.php b/src/Monolog/Handler/InsightOpsHandler.php new file mode 100644 index 00000000..a12e3de5 --- /dev/null +++ b/src/Monolog/Handler/InsightOpsHandler.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + namespace Monolog\Handler; + + use Monolog\Logger; + +/** + * Inspired on LogEntriesHandler. + * + * @author Robert Kaufmann III + * @author Gabriel Machado + */ +class InsightOpsHandler extends SocketHandler +{ + /** + * @var string + */ + protected $logToken; + + /** + * @param string $token Log token supplied by InsightOps + * @param string $region Region where InsightOps account is hosted. Could be 'us' or 'eu'. + * @param bool $useSSL Whether or not SSL encryption should be used + * @param int $level The minimum logging level to trigger this handler + * @param bool $bubble Whether or not messages that are handled should bubble up the stack. + * + * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing + */ + public function __construct($token, $region = 'us', $useSSL = true, $level = Logger::DEBUG, $bubble = true) + { + if ($useSSL && !extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler'); + } + + $endpoint = $useSSL + ? 'ssl://' . $region . '.data.logs.insight.rapid7.com:443' + : $region . '.data.logs.insight.rapid7.com:80'; + + parent::__construct($endpoint, $level, $bubble); + $this->logToken = $token; + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + return $this->logToken . ' ' . $record['formatted']; + } +} diff --git a/tests/Monolog/Handler/InsightOpsHandlerTest.php b/tests/Monolog/Handler/InsightOpsHandlerTest.php new file mode 100644 index 00000000..97c18b59 --- /dev/null +++ b/tests/Monolog/Handler/InsightOpsHandlerTest.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + namespace Monolog\Handler; + + use Monolog\TestCase; + use Monolog\Logger; + +/** + * @author Robert Kaufmann III + * @author Gabriel Machado + */ +class InsightOpsHandlerTest extends TestCase +{ + /** + * @var resource + */ + private $resource; + + /** + * @var LogEntriesHandler + */ + private $handler; + + public function testWriteContent() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Critical write test')); + + fseek($this->resource, 0); + $content = fread($this->resource, 1024); + + $this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] test.CRITICAL: Critical write test/', $content); + } + + public function testWriteBatchContent() + { + $this->createHandler(); + $this->handler->handleBatch($this->getMultipleRecords()); + + fseek($this->resource, 0); + $content = fread($this->resource, 1024); + + $this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] .* \[\] \[\]\n){3}/', $content); + } + + private function createHandler() + { + $useSSL = extension_loaded('openssl'); + $args = array('testToken', 'us', $useSSL, Logger::DEBUG, true); + $this->resource = fopen('php://memory', 'a'); + $this->handler = $this->getMock( + '\Monolog\Handler\InsightOpsHandler', + array('fsockopen', 'streamSetTimeout', 'closeSocket'), + $args + ); + + $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->handler, 'localhost:1234'); + + $this->handler->expects($this->any()) + ->method('fsockopen') + ->will($this->returnValue($this->resource)); + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + $this->handler->expects($this->any()) + ->method('closeSocket') + ->will($this->returnValue(true)); + } +} From f5d968ba955de59d89240fa6b5d743775b2a01bd Mon Sep 17 00:00:00 2001 From: "From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be \"Sir!" Date: Tue, 19 Sep 2017 20:07:32 +0900 Subject: [PATCH 09/80] Fix Comparison operator in RotatingFileHandler --- src/Monolog/Handler/RotatingFileHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Handler/RotatingFileHandler.php b/src/Monolog/Handler/RotatingFileHandler.php index a4a5ba44..b349fd06 100644 --- a/src/Monolog/Handler/RotatingFileHandler.php +++ b/src/Monolog/Handler/RotatingFileHandler.php @@ -98,7 +98,7 @@ class RotatingFileHandler extends StreamHandler $this->mustRotate = !file_exists($this->url); } - if ($this->nextRotation < $record['datetime']) { + if ($this->nextRotation <= $record['datetime']) { $this->mustRotate = true; $this->close(); } From a21b037a00c6480c5af7106d0a08edde564b2265 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Tue, 3 Oct 2017 12:22:44 -0500 Subject: [PATCH 10/80] Change LogstashFormatter to have extra/context keys instead of prefixes for the keys. --- src/Monolog/Formatter/LogstashFormatter.php | 22 ++++++------ .../Formatter/LogstashFormatterTest.php | 34 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Monolog/Formatter/LogstashFormatter.php b/src/Monolog/Formatter/LogstashFormatter.php index 3cf31dd4..d576b3b1 100644 --- a/src/Monolog/Formatter/LogstashFormatter.php +++ b/src/Monolog/Formatter/LogstashFormatter.php @@ -32,30 +32,30 @@ class LogstashFormatter extends NormalizerFormatter protected $applicationName; /** - * @var string a prefix for 'extra' fields from the Monolog record (optional) + * @var string the key for 'extra' fields from the Monolog record */ - protected $extraPrefix; + protected $extraKey; /** - * @var string a prefix for 'context' fields from the Monolog record (optional) + * @var string the key for 'context' fields from the Monolog record */ - protected $contextPrefix; + protected $contextKey; /** * @param string $applicationName the application that sends the data, used as the "type" field of logstash * @param string $systemName the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine - * @param string $extraPrefix prefix for extra keys inside logstash "fields" - * @param string $contextPrefix prefix for context keys inside logstash "fields", defaults to ctxt_ + * @param string $extraKey the key for extra keys inside logstash "fields", defaults to extra + * @param string $contextKey the key for context keys inside logstash "fields", defaults to context */ - public function __construct(string $applicationName, string $systemName = null, string $extraPrefix = null, string $contextPrefix = 'ctxt_') + public function __construct(string $applicationName, string $systemName = null, string $extraKey = 'extra', string $contextKey = 'context') { // logstash requires a ISO 8601 format date with optional millisecond precision. parent::__construct('Y-m-d\TH:i:s.uP'); $this->systemName = $systemName ?: gethostname(); $this->applicationName = $applicationName; - $this->extraPrefix = $extraPrefix; - $this->contextPrefix = $contextPrefix; + $this->extraKey = $extraKey; + $this->contextKey = $contextKey; } /** @@ -90,10 +90,10 @@ class LogstashFormatter extends NormalizerFormatter $message['type'] = $this->applicationName; } if (!empty($record['extra'])) { - $message[$this->extraPrefix.'extra'] = $record['extra']; + $message[$this->extraKey] = $record['extra']; } if (!empty($record['context'])) { - $message[$this->contextPrefix.'context'] = $record['context']; + $message[$this->contextKey] = $record['context']; } return $this->toJson($message) . "\n"; diff --git a/tests/Monolog/Formatter/LogstashFormatterTest.php b/tests/Monolog/Formatter/LogstashFormatterTest.php index 2ca9f55e..b9404db6 100644 --- a/tests/Monolog/Formatter/LogstashFormatterTest.php +++ b/tests/Monolog/Formatter/LogstashFormatterTest.php @@ -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', From e3ab4e680bf28c40798ba79bad057fa01e45be9d Mon Sep 17 00:00:00 2001 From: Michael Dwyer Date: Tue, 31 Oct 2017 09:46:46 -0500 Subject: [PATCH 11/80] Fix typo All other documentation and code suggests that the replacement token is of the form `{var}` and not `%var%` --- doc/message-structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/message-structure.md b/doc/message-structure.md index 093a10ca..63c6f19b 100644 --- a/doc/message-structure.md +++ b/doc/message-structure.md @@ -5,7 +5,7 @@ The table below describes which keys are always available for every log message. key | type | description -----------|---------------------------|------------------------------------------------------------------------------- -message | string | The log message. When the `PsrLogMessageProcessor` is used this string may contain placeholders that will be replaced by variables from the context, e.g., "User %username% logged in" with `['username' => 'John']` as context will be written as "User John logged in". +message | string | The log message. When the `PsrLogMessageProcessor` is used this string may contain placeholders that will be replaced by variables from the context, e.g., "User {username} logged in" with `['username' => 'John']` as context will be written as "User John logged in". level | int | Severity of the log message. See log levels described in [01-usage.md](01-usage.md). level_name | string | String representation of log level. context | array | Arbitrary data passed with the construction of the message. For example the username of the current user or their IP address. From ecdfdc989718b10d7d3b3a80e40bc551f2f56654 Mon Sep 17 00:00:00 2001 From: Erik Booij Date: Sun, 22 Oct 2017 19:09:08 +0200 Subject: [PATCH 12/80] Rename Boolean in phpDocs to bool --- src/Monolog/Handler/AbstractHandler.php | 12 ++++++------ src/Monolog/Handler/AbstractSyslogHandler.php | 6 +++--- src/Monolog/Handler/BufferHandler.php | 4 ++-- src/Monolog/Handler/ChromePHPHandler.php | 6 +++--- src/Monolog/Handler/DeduplicationHandler.php | 2 +- src/Monolog/Handler/ElasticSearchHandler.php | 8 ++++---- src/Monolog/Handler/ErrorLogHandler.php | 8 ++++---- src/Monolog/Handler/FilterHandler.php | 4 ++-- .../FingersCrossed/ActivationStrategyInterface.php | 2 +- src/Monolog/Handler/FingersCrossedHandler.php | 4 ++-- src/Monolog/Handler/FirePHPHandler.php | 2 +- src/Monolog/Handler/GroupHandler.php | 4 ++-- src/Monolog/Handler/HandlerInterface.php | 4 ++-- src/Monolog/Handler/IFTTTHandler.php | 8 ++++---- src/Monolog/Handler/MandrillHandler.php | 2 +- src/Monolog/Handler/PsrHandler.php | 2 +- src/Monolog/Handler/PushoverHandler.php | 4 ++-- src/Monolog/Handler/RavenHandler.php | 2 +- src/Monolog/Handler/RotatingFileHandler.php | 4 ++-- src/Monolog/Handler/SocketHandler.php | 6 +++--- src/Monolog/Handler/StreamHandler.php | 4 ++-- src/Monolog/Handler/SyslogHandler.php | 10 +++++----- src/Monolog/Handler/SyslogUdpHandler.php | 12 ++++++------ src/Monolog/Logger.php | 4 ++-- 24 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/Monolog/Handler/AbstractHandler.php b/src/Monolog/Handler/AbstractHandler.php index 758a425c..bf56549d 100644 --- a/src/Monolog/Handler/AbstractHandler.php +++ b/src/Monolog/Handler/AbstractHandler.php @@ -32,8 +32,8 @@ abstract class AbstractHandler implements HandlerInterface protected $processors = array(); /** - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($level = Logger::DEBUG, $bubble = true) { @@ -141,8 +141,8 @@ abstract class AbstractHandler implements HandlerInterface /** * Sets the bubbling behavior. * - * @param Boolean $bubble true means that this handler allows bubbling. - * false means that bubbling is not permitted. + * @param bool $bubble true means that this handler allows bubbling. + * false means that bubbling is not permitted. * @return self */ public function setBubble($bubble) @@ -155,8 +155,8 @@ abstract class AbstractHandler implements HandlerInterface /** * Gets the bubbling behavior. * - * @return Boolean true means that this handler allows bubbling. - * false means that bubbling is not permitted. + * @return bool true means that this handler allows bubbling. + * false means that bubbling is not permitted. */ public function getBubble() { diff --git a/src/Monolog/Handler/AbstractSyslogHandler.php b/src/Monolog/Handler/AbstractSyslogHandler.php index e2b2832d..8c76aca0 100644 --- a/src/Monolog/Handler/AbstractSyslogHandler.php +++ b/src/Monolog/Handler/AbstractSyslogHandler.php @@ -53,9 +53,9 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler ); /** - * @param mixed $facility - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) { diff --git a/src/Monolog/Handler/BufferHandler.php b/src/Monolog/Handler/BufferHandler.php index 72f89535..c15e28a2 100644 --- a/src/Monolog/Handler/BufferHandler.php +++ b/src/Monolog/Handler/BufferHandler.php @@ -34,8 +34,8 @@ class BufferHandler extends AbstractHandler * @param HandlerInterface $handler Handler. * @param int $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not - * @param Boolean $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded */ public function __construct(HandlerInterface $handler, $bufferLimit = 0, $level = Logger::DEBUG, $bubble = true, $flushOnOverflow = false) { diff --git a/src/Monolog/Handler/ChromePHPHandler.php b/src/Monolog/Handler/ChromePHPHandler.php index 785cb0c9..ea8ae7fb 100644 --- a/src/Monolog/Handler/ChromePHPHandler.php +++ b/src/Monolog/Handler/ChromePHPHandler.php @@ -45,7 +45,7 @@ class ChromePHPHandler extends AbstractProcessingHandler * * Chrome limits the headers to 256KB, so when we sent 240KB we stop sending * - * @var Boolean + * @var bool */ protected static $overflowed = false; @@ -58,8 +58,8 @@ class ChromePHPHandler extends AbstractProcessingHandler protected static $sendHeaders = true; /** - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($level = Logger::DEBUG, $bubble = true) { diff --git a/src/Monolog/Handler/DeduplicationHandler.php b/src/Monolog/Handler/DeduplicationHandler.php index 7778c22a..35b55cb4 100644 --- a/src/Monolog/Handler/DeduplicationHandler.php +++ b/src/Monolog/Handler/DeduplicationHandler.php @@ -60,7 +60,7 @@ class DeduplicationHandler extends BufferHandler * @param string $deduplicationStore The file/path where the deduplication log should be kept * @param int $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes * @param int $time The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(HandlerInterface $handler, $deduplicationStore = null, $deduplicationLevel = Logger::ERROR, $time = 60, $bubble = true) { diff --git a/src/Monolog/Handler/ElasticSearchHandler.php b/src/Monolog/Handler/ElasticSearchHandler.php index 81967406..bb0f83eb 100644 --- a/src/Monolog/Handler/ElasticSearchHandler.php +++ b/src/Monolog/Handler/ElasticSearchHandler.php @@ -46,10 +46,10 @@ class ElasticSearchHandler extends AbstractProcessingHandler protected $options = array(); /** - * @param Client $client Elastica Client object - * @param array $options Handler configuration - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Client $client Elastica Client object + * @param array $options Handler configuration + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = true) { diff --git a/src/Monolog/Handler/ErrorLogHandler.php b/src/Monolog/Handler/ErrorLogHandler.php index 1447a584..b2986b0f 100644 --- a/src/Monolog/Handler/ErrorLogHandler.php +++ b/src/Monolog/Handler/ErrorLogHandler.php @@ -28,10 +28,10 @@ class ErrorLogHandler extends AbstractProcessingHandler protected $expandNewlines; /** - * @param int $messageType Says where the error should go. - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not - * @param Boolean $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries + * @param int $messageType Says where the error should go. + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries */ public function __construct($messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, $bubble = true, $expandNewlines = false) { diff --git a/src/Monolog/Handler/FilterHandler.php b/src/Monolog/Handler/FilterHandler.php index 2a0f7fd1..938c1a7e 100644 --- a/src/Monolog/Handler/FilterHandler.php +++ b/src/Monolog/Handler/FilterHandler.php @@ -40,7 +40,7 @@ class FilterHandler extends AbstractHandler /** * Whether the messages that are handled can bubble up the stack or not * - * @var Boolean + * @var bool */ protected $bubble; @@ -48,7 +48,7 @@ class FilterHandler extends AbstractHandler * @param callable|HandlerInterface $handler Handler or factory callable($record, $this). * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided * @param int $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, $bubble = true) { diff --git a/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php index c3e42efe..aaca12cc 100644 --- a/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php +++ b/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php @@ -22,7 +22,7 @@ interface ActivationStrategyInterface * Returns whether the given record activates the handler. * * @param array $record - * @return Boolean + * @return bool */ public function isHandlerActivated(array $record); } diff --git a/src/Monolog/Handler/FingersCrossedHandler.php b/src/Monolog/Handler/FingersCrossedHandler.php index d1dcaacf..d8026be6 100644 --- a/src/Monolog/Handler/FingersCrossedHandler.php +++ b/src/Monolog/Handler/FingersCrossedHandler.php @@ -41,8 +41,8 @@ class FingersCrossedHandler extends AbstractHandler * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler). * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not - * @param Boolean $stopBuffering Whether the handler should stop buffering after being triggered (default true) + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $stopBuffering Whether the handler should stop buffering after being triggered (default true) * @param int $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered */ public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true, $passthruLevel = null) diff --git a/src/Monolog/Handler/FirePHPHandler.php b/src/Monolog/Handler/FirePHPHandler.php index fee47950..c30b1843 100644 --- a/src/Monolog/Handler/FirePHPHandler.php +++ b/src/Monolog/Handler/FirePHPHandler.php @@ -158,7 +158,7 @@ class FirePHPHandler extends AbstractProcessingHandler /** * Verifies if the headers are accepted by the current user agent * - * @return Boolean + * @return bool */ protected function headersAccepted() { diff --git a/src/Monolog/Handler/GroupHandler.php b/src/Monolog/Handler/GroupHandler.php index 663f5a92..c38508c2 100644 --- a/src/Monolog/Handler/GroupHandler.php +++ b/src/Monolog/Handler/GroupHandler.php @@ -23,8 +23,8 @@ class GroupHandler extends AbstractHandler protected $handlers; /** - * @param array $handlers Array of Handlers. - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param array $handlers Array of Handlers. + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(array $handlers, $bubble = true) { diff --git a/src/Monolog/Handler/HandlerInterface.php b/src/Monolog/Handler/HandlerInterface.php index d920c4ba..8d5a4a09 100644 --- a/src/Monolog/Handler/HandlerInterface.php +++ b/src/Monolog/Handler/HandlerInterface.php @@ -31,7 +31,7 @@ interface HandlerInterface * * @param array $record Partial log record containing only a level key * - * @return Boolean + * @return bool */ public function isHandling(array $record); @@ -46,7 +46,7 @@ interface HandlerInterface * calling further handlers in the stack with a given log record. * * @param array $record The record to handle - * @return Boolean true means that this handler handled the record, and that bubbling is not permitted. + * @return bool true means that this handler handled the record, and that bubbling is not permitted. * false means the record was either not processed or that this handler allows bubbling. */ public function handle(array $record); diff --git a/src/Monolog/Handler/IFTTTHandler.php b/src/Monolog/Handler/IFTTTHandler.php index d60a3c82..7f226220 100644 --- a/src/Monolog/Handler/IFTTTHandler.php +++ b/src/Monolog/Handler/IFTTTHandler.php @@ -30,10 +30,10 @@ class IFTTTHandler extends AbstractProcessingHandler private $secretKey; /** - * @param string $eventName The name of the IFTTT Maker event that should be triggered - * @param string $secretKey A valid IFTTT secret key - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param string $eventName The name of the IFTTT Maker event that should be triggered + * @param string $secretKey A valid IFTTT secret key + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($eventName, $secretKey, $level = Logger::ERROR, $bubble = true) { diff --git a/src/Monolog/Handler/MandrillHandler.php b/src/Monolog/Handler/MandrillHandler.php index ab95924f..3f0956a9 100644 --- a/src/Monolog/Handler/MandrillHandler.php +++ b/src/Monolog/Handler/MandrillHandler.php @@ -27,7 +27,7 @@ class MandrillHandler extends MailHandler * @param string $apiKey A valid Mandrill API key * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($apiKey, $message, $level = Logger::ERROR, $bubble = true) { diff --git a/src/Monolog/Handler/PsrHandler.php b/src/Monolog/Handler/PsrHandler.php index 1ae85845..a99e6ab7 100644 --- a/src/Monolog/Handler/PsrHandler.php +++ b/src/Monolog/Handler/PsrHandler.php @@ -31,7 +31,7 @@ class PsrHandler extends AbstractHandler /** * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, $bubble = true) { diff --git a/src/Monolog/Handler/PushoverHandler.php b/src/Monolog/Handler/PushoverHandler.php index bba72005..168a1c7b 100644 --- a/src/Monolog/Handler/PushoverHandler.php +++ b/src/Monolog/Handler/PushoverHandler.php @@ -69,8 +69,8 @@ class PushoverHandler extends SocketHandler * @param string|array $users Pushover user id or array of ids the message will be sent to * @param string $title Title sent to the Pushover API * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not - * @param Boolean $useSSL Whether to connect via SSL. Required when pushing messages to users that are not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useSSL Whether to connect via SSL. Required when pushing messages to users that are not * the pushover.net app owner. OpenSSL is required for this option. * @param int $highPriorityLevel The minimum logging level at which this handler will start * sending "high priority" requests to the Pushover API diff --git a/src/Monolog/Handler/RavenHandler.php b/src/Monolog/Handler/RavenHandler.php index 53a8b391..eb5dda08 100644 --- a/src/Monolog/Handler/RavenHandler.php +++ b/src/Monolog/Handler/RavenHandler.php @@ -57,7 +57,7 @@ class RavenHandler extends AbstractProcessingHandler /** * @param Raven_Client $ravenClient * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(Raven_Client $ravenClient, $level = Logger::DEBUG, $bubble = true) { diff --git a/src/Monolog/Handler/RotatingFileHandler.php b/src/Monolog/Handler/RotatingFileHandler.php index 3b60b3d1..c8cdfab6 100644 --- a/src/Monolog/Handler/RotatingFileHandler.php +++ b/src/Monolog/Handler/RotatingFileHandler.php @@ -39,9 +39,9 @@ class RotatingFileHandler extends StreamHandler * @param string $filename * @param int $maxFiles The maximal amount of files to keep (0 means unlimited) * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) - * @param Boolean $useLocking Try to lock log file before doing any writes + * @param bool $useLocking Try to lock log file before doing any writes */ public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false) { diff --git a/src/Monolog/Handler/SocketHandler.php b/src/Monolog/Handler/SocketHandler.php index 7a61bf4e..73a51311 100644 --- a/src/Monolog/Handler/SocketHandler.php +++ b/src/Monolog/Handler/SocketHandler.php @@ -33,9 +33,9 @@ class SocketHandler extends AbstractProcessingHandler private $lastWritingAt; /** - * @param string $connectionString Socket connection string - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param string $connectionString Socket connection string + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($connectionString, $level = Logger::DEBUG, $bubble = true) { diff --git a/src/Monolog/Handler/StreamHandler.php b/src/Monolog/Handler/StreamHandler.php index 09a15738..dd4f7109 100644 --- a/src/Monolog/Handler/StreamHandler.php +++ b/src/Monolog/Handler/StreamHandler.php @@ -32,9 +32,9 @@ class StreamHandler extends AbstractProcessingHandler /** * @param resource|string $stream * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) - * @param Boolean $useLocking Try to lock log file before doing any writes + * @param bool $useLocking Try to lock log file before doing any writes * * @throws \Exception If a missing directory is not buildable * @throws \InvalidArgumentException If stream is not a resource or string diff --git a/src/Monolog/Handler/SyslogHandler.php b/src/Monolog/Handler/SyslogHandler.php index 376bc3b2..f770c802 100644 --- a/src/Monolog/Handler/SyslogHandler.php +++ b/src/Monolog/Handler/SyslogHandler.php @@ -32,11 +32,11 @@ class SyslogHandler extends AbstractSyslogHandler protected $logopts; /** - * @param string $ident - * @param mixed $facility - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not - * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID + * @param string $ident + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID */ public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $logopts = LOG_PID) { diff --git a/src/Monolog/Handler/SyslogUdpHandler.php b/src/Monolog/Handler/SyslogUdpHandler.php index 4718711b..e14b378c 100644 --- a/src/Monolog/Handler/SyslogUdpHandler.php +++ b/src/Monolog/Handler/SyslogUdpHandler.php @@ -25,12 +25,12 @@ class SyslogUdpHandler extends AbstractSyslogHandler protected $ident; /** - * @param string $host - * @param int $port - * @param mixed $facility - * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not - * @param string $ident Program name or tag for each log message. + * @param string $host + * @param int $port + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param string $ident Program name or tag for each log message. */ public function __construct($host, $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $ident = 'php') { diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 49d00af1..994bba96 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -281,7 +281,7 @@ class Logger implements LoggerInterface * @param int $level The logging level * @param string $message The log message * @param array $context The log context - * @return Boolean Whether the record has been processed + * @return bool Whether the record has been processed */ public function addRecord($level, $message, array $context = array()) { @@ -484,7 +484,7 @@ class Logger implements LoggerInterface * Checks whether the Logger has a handler that listens on the given level * * @param int $level - * @return Boolean + * @return bool */ public function isHandling($level) { From 9791cbcda362a7c82bc4aa06432ce845b0592da9 Mon Sep 17 00:00:00 2001 From: Aerendir Date: Mon, 23 Oct 2017 13:26:16 +0200 Subject: [PATCH 13/80] Fix #1066: Use correct docblock castings. --- src/Monolog/ErrorHandler.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Monolog/ErrorHandler.php b/src/Monolog/ErrorHandler.php index d0b1aa6d..e63ce346 100644 --- a/src/Monolog/ErrorHandler.php +++ b/src/Monolog/ErrorHandler.php @@ -49,10 +49,10 @@ class ErrorHandler * * By default it will handle errors, exceptions and fatal errors * - * @param LoggerInterface $logger - * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling - * @param array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling - * @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling + * @param LoggerInterface $logger + * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling + * @param array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling + * @param string|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling * @return ErrorHandler */ public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null): self From 18b93feea6281d726d979ec098d49e59dec2f54e Mon Sep 17 00:00:00 2001 From: MilesChou Date: Thu, 30 Nov 2017 13:47:47 +0800 Subject: [PATCH 14/80] Add getter for webhook url in SlackWebhookHandler class Add getter so that the subclass can easy to inherit SlackWebhookHandler class --- src/Monolog/Handler/SlackWebhookHandler.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Monolog/Handler/SlackWebhookHandler.php b/src/Monolog/Handler/SlackWebhookHandler.php index 9a1bbb44..1ef85fae 100644 --- a/src/Monolog/Handler/SlackWebhookHandler.php +++ b/src/Monolog/Handler/SlackWebhookHandler.php @@ -70,6 +70,11 @@ class SlackWebhookHandler extends AbstractProcessingHandler return $this->slackRecord; } + public function getWebhookUrl() + { + return $this->webhookUrl; + } + /** * {@inheritdoc} * From 2d9c905b76eb6103eb089c2fcde15538593106c7 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 15 Nov 2017 18:05:17 +1300 Subject: [PATCH 15/80] ENHANCEMENT Ensure 'trace' is captured for non-exceptions Fixes #693 --- src/Monolog/ErrorHandler.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Monolog/ErrorHandler.php b/src/Monolog/ErrorHandler.php index 7bfcd833..b3025738 100644 --- a/src/Monolog/ErrorHandler.php +++ b/src/Monolog/ErrorHandler.php @@ -38,6 +38,7 @@ class ErrorHandler private $hasFatalErrorHandler; private $fatalLevel; private $reservedMemory; + private $lastFatalTrace; private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR); public function __construct(LoggerInterface $logger) @@ -156,6 +157,13 @@ class ErrorHandler if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) { $level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL; $this->logger->log($level, self::codeToString($code).': '.$message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line)); + } else { + // http://php.net/manual/en/function.debug-backtrace.php + // As of 5.3.6, DEBUG_BACKTRACE_IGNORE_ARGS option was added. + // Any version less than 5.3.6 must use the DEBUG_BACKTRACE_IGNORE_ARGS constant value '2'. + $trace = debug_backtrace((PHP_VERSION_ID < 50306) ? 2 : DEBUG_BACKTRACE_IGNORE_ARGS); + array_shift($trace); // Exclude handleError from trace + $this->lastFatalTrace = $trace; } if ($this->previousErrorHandler === true) { @@ -177,7 +185,7 @@ class ErrorHandler $this->logger->log( $this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel, 'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'], - array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line']) + array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $this->lastFatalTrace) ); if ($this->logger instanceof Logger) { From 86d0984517d7c3b44ffc5852f466b71eedabf296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hinrik=20=C3=96rn=20Sigur=C3=B0sson?= Date: Thu, 18 Jan 2018 10:32:25 +0100 Subject: [PATCH 16/80] Set HTTP response code to 500 in case of exceptions Resolves Seldaek/monolog#1096. --- src/Monolog/ErrorHandler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Monolog/ErrorHandler.php b/src/Monolog/ErrorHandler.php index d0b1aa6d..dfccaa9f 100644 --- a/src/Monolog/ErrorHandler.php +++ b/src/Monolog/ErrorHandler.php @@ -166,6 +166,10 @@ class ErrorHandler call_user_func($this->previousExceptionHandler, $e); } + if (!headers_sent() && ini_get('display_errors') === 0) { + http_response_code(500); + } + exit(255); } From 9dba2f3431e6201589f2e08bca2b9cce48f8b094 Mon Sep 17 00:00:00 2001 From: elwin1234 Date: Wed, 14 Feb 2018 15:47:48 +0100 Subject: [PATCH 17/80] Update RotatingFileHandler.php Use own constant instead of hardcoded string for default dateFormat (const FILE_PER_DAY = 'Y-m-d';) --- src/Monolog/Handler/RotatingFileHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Handler/RotatingFileHandler.php b/src/Monolog/Handler/RotatingFileHandler.php index a4a5ba44..78703e45 100644 --- a/src/Monolog/Handler/RotatingFileHandler.php +++ b/src/Monolog/Handler/RotatingFileHandler.php @@ -50,7 +50,7 @@ class RotatingFileHandler extends StreamHandler $this->maxFiles = (int) $maxFiles; $this->nextRotation = new \DateTimeImmutable('tomorrow'); $this->filenameFormat = '{filename}-{date}'; - $this->dateFormat = 'Y-m-d'; + $this->dateFormat = self::FILE_PER_DAY; parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking); } From 276135c0fe773e87412f6a53d3b3254e775d507e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Fri, 2 Mar 2018 12:22:42 +0200 Subject: [PATCH 18/80] ErrorLogHandler: use strict comparison otherwise `null` and `false` get accepted as valid types --- src/Monolog/Handler/ErrorLogHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Handler/ErrorLogHandler.php b/src/Monolog/Handler/ErrorLogHandler.php index 2c801398..c5f888d0 100644 --- a/src/Monolog/Handler/ErrorLogHandler.php +++ b/src/Monolog/Handler/ErrorLogHandler.php @@ -38,7 +38,7 @@ class ErrorLogHandler extends AbstractProcessingHandler { parent::__construct($level, $bubble); - if (false === in_array($messageType, self::getAvailableTypes())) { + if (false === in_array($messageType, self::getAvailableTypes(), true)) { $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true)); throw new \InvalidArgumentException($message); } From a3388569cdabc527e6e8eea0f6286c5918e10c31 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Mon, 2 Apr 2018 00:16:28 +0900 Subject: [PATCH 19/80] upgrade phpunit to 6 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bc87c44c..380c05d8 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "psr/log": "^1.0.1" }, "require-dev": { - "phpunit/phpunit": "^5.7", + "phpunit/phpunit": "^6.5", "graylog2/gelf-php": "^1.4.2", "sentry/sentry": "^0.13", "ruflin/elastica": ">=0.90 <3.0", From 39f464bd582d0e053548b91dffd4b88869097b0a Mon Sep 17 00:00:00 2001 From: DQNEO Date: Mon, 2 Apr 2018 00:54:21 +0900 Subject: [PATCH 20/80] make compatible to phpunit 6 --- phpunit.xml.dist | 2 +- tests/Monolog/Formatter/LogstashFormatterTest.php | 2 +- tests/Monolog/Formatter/NormalizerFormatterTest.php | 2 +- tests/Monolog/Handler/ProcessHandlerTest.php | 10 +++++----- tests/Monolog/Handler/RotatingFileHandlerTest.php | 6 ++++-- tests/bootstrap.php | 6 ++++++ 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 54da2818..1a676b24 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,6 @@ - + tests/Monolog/ diff --git a/tests/Monolog/Formatter/LogstashFormatterTest.php b/tests/Monolog/Formatter/LogstashFormatterTest.php index 2ca9f55e..d7f243e7 100644 --- a/tests/Monolog/Formatter/LogstashFormatterTest.php +++ b/tests/Monolog/Formatter/LogstashFormatterTest.php @@ -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(); } diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index 68b275df..52a8c796 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -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(); } diff --git a/tests/Monolog/Handler/ProcessHandlerTest.php b/tests/Monolog/Handler/ProcessHandlerTest.php index dc2a427f..c78d5590 100644 --- a/tests/Monolog/Handler/ProcessHandlerTest.php +++ b/tests/Monolog/Handler/ProcessHandlerTest.php @@ -77,7 +77,7 @@ class ProcessHandlerTest extends TestCase */ public function testConstructWithInvalidCommandThrowsInvalidArgumentException($invalidCommand, $expectedExcep) { - $this->setExpectedException($expectedExcep); + $this->expectException($expectedExcep); new ProcessHandler($invalidCommand, Logger::DEBUG); } @@ -102,7 +102,7 @@ class ProcessHandlerTest extends TestCase */ public function testConstructWithInvalidCwdThrowsInvalidArgumentException($invalidCwd, $expectedExcep) { - $this->setExpectedException($expectedExcep); + $this->expectException($expectedExcep); new ProcessHandler(self::DUMMY_COMMAND, Logger::DEBUG, true, $invalidCwd); } @@ -135,7 +135,7 @@ class ProcessHandlerTest extends TestCase ->method('selectErrorStream') ->will($this->returnValue(false)); - $this->setExpectedException('\UnexpectedValueException'); + $this->expectException('\UnexpectedValueException'); /** @var ProcessHandler $handler */ $handler->handle($this->getRecord(Logger::WARNING, 'stream failing, whoops')); } @@ -147,7 +147,7 @@ class ProcessHandlerTest extends TestCase public function testStartupWithErrorsThrowsUnexpectedValueException() { $handler = new ProcessHandler('>&2 echo "some fake error message"'); - $this->setExpectedException('\UnexpectedValueException'); + $this->expectException('\UnexpectedValueException'); $handler->handle($this->getRecord(Logger::WARNING, 'some warning in the house')); } @@ -167,7 +167,7 @@ class ProcessHandlerTest extends TestCase ->method('readProcessErrors') ->willReturnOnConsecutiveCalls('', $this->returnValue('some fake error message here')); - $this->setExpectedException('\UnexpectedValueException'); + $this->expectException('\UnexpectedValueException'); /** @var ProcessHandler $handler */ $handler->handle($this->getRecord(Logger::WARNING, 'some test stuff')); } diff --git a/tests/Monolog/Handler/RotatingFileHandlerTest.php b/tests/Monolog/Handler/RotatingFileHandlerTest.php index f2d61db9..5fc4416a 100644 --- a/tests/Monolog/Handler/RotatingFileHandlerTest.php +++ b/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -134,7 +134,8 @@ class RotatingFileHandlerTest extends TestCase { $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2); if (!$valid) { - $this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid date format~'); + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageRegExp('~^Invalid date format~'); } $handler->setFilenameFormat('{filename}-{date}', $dateFormat); $this->assertTrue(true); @@ -174,7 +175,8 @@ class RotatingFileHandlerTest extends TestCase { $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2); if (!$valid) { - $this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid filename format~'); + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageRegExp('~^Invalid filename format~'); } $handler->setFilenameFormat($filenameFormat, RotatingFileHandler::FILE_PER_DAY); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d475dd33..688777d3 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -12,3 +12,9 @@ date_default_timezone_set('UTC'); require __DIR__.'/../vendor/autoload.php'; + +// B.C. for PSR Log's old inheritance +// see https://github.com/php-fig/log/pull/52 +if (!class_exists('\\PHPUnit_Framework_TestCase', true)) { + class_alias('\\PHPUnit\\Framework\\TestCase', '\\PHPUnit_Framework_TestCase'); +} From 50de6999ae022c3d572bbf16bc4434dd62dcd0ec Mon Sep 17 00:00:00 2001 From: Jeroen Stolp Date: Tue, 10 Apr 2018 13:25:02 +0200 Subject: [PATCH 21/80] Happy 2018 to Monolog --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index b97667f8..713dc045 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2017 Jordi Boggiano +Copyright (c) 2011-2018 Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 1e8deb4672c3cb0cd65cd6e6b2c0fbc8c8f5005f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 16 Apr 2018 15:03:26 +0200 Subject: [PATCH 22/80] Drop HHVM in .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b821b452..fa6119c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ php: - 5.6 - 7.0 - 7.1 - - hhvm - nightly matrix: From 1107013b9c3952db74284a7640f1f78581b164c9 Mon Sep 17 00:00:00 2001 From: MilesChou Date: Tue, 24 Apr 2018 23:17:02 +0800 Subject: [PATCH 23/80] Open visibility for slack handlers --- src/Monolog/Handler/SlackHandler.php | 4 ++-- src/Monolog/Handler/SlackWebhookHandler.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Monolog/Handler/SlackHandler.php b/src/Monolog/Handler/SlackHandler.php index 3ac4d836..2c2cc4c0 100644 --- a/src/Monolog/Handler/SlackHandler.php +++ b/src/Monolog/Handler/SlackHandler.php @@ -27,13 +27,13 @@ class SlackHandler extends SocketHandler * Slack API token * @var string */ - private $token; + protected $token; /** * Instance of the SlackRecord util class preparing data for Slack API. * @var SlackRecord */ - private $slackRecord; + protected $slackRecord; /** * @param string $token Slack API token diff --git a/src/Monolog/Handler/SlackWebhookHandler.php b/src/Monolog/Handler/SlackWebhookHandler.php index 9a1bbb44..19f92cef 100644 --- a/src/Monolog/Handler/SlackWebhookHandler.php +++ b/src/Monolog/Handler/SlackWebhookHandler.php @@ -27,13 +27,13 @@ class SlackWebhookHandler extends AbstractProcessingHandler * Slack Webhook token * @var string */ - private $webhookUrl; + protected $webhookUrl; /** * Instance of the SlackRecord util class preparing data for Slack API. * @var SlackRecord */ - private $slackRecord; + protected $slackRecord; /** * @param string $webhookUrl Slack Webhook URL From 985fdb3eae0ad1085e2ccb291278d69b18d6919a Mon Sep 17 00:00:00 2001 From: MilesChou Date: Wed, 25 Apr 2018 15:51:22 +0800 Subject: [PATCH 24/80] Add getter for webhook and token property --- src/Monolog/Handler/SlackHandler.php | 9 +++++++-- src/Monolog/Handler/SlackWebhookHandler.php | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Monolog/Handler/SlackHandler.php b/src/Monolog/Handler/SlackHandler.php index 2c2cc4c0..45d634f4 100644 --- a/src/Monolog/Handler/SlackHandler.php +++ b/src/Monolog/Handler/SlackHandler.php @@ -27,13 +27,13 @@ class SlackHandler extends SocketHandler * Slack API token * @var string */ - protected $token; + private $token; /** * Instance of the SlackRecord util class preparing data for Slack API. * @var SlackRecord */ - protected $slackRecord; + private $slackRecord; /** * @param string $token Slack API token @@ -75,6 +75,11 @@ class SlackHandler extends SocketHandler return $this->slackRecord; } + public function getToken() + { + return $this->token; + } + /** * {@inheritdoc} * diff --git a/src/Monolog/Handler/SlackWebhookHandler.php b/src/Monolog/Handler/SlackWebhookHandler.php index 19f92cef..1ef85fae 100644 --- a/src/Monolog/Handler/SlackWebhookHandler.php +++ b/src/Monolog/Handler/SlackWebhookHandler.php @@ -27,13 +27,13 @@ class SlackWebhookHandler extends AbstractProcessingHandler * Slack Webhook token * @var string */ - protected $webhookUrl; + private $webhookUrl; /** * Instance of the SlackRecord util class preparing data for Slack API. * @var SlackRecord */ - protected $slackRecord; + private $slackRecord; /** * @param string $webhookUrl Slack Webhook URL @@ -70,6 +70,11 @@ class SlackWebhookHandler extends AbstractProcessingHandler return $this->slackRecord; } + public function getWebhookUrl() + { + return $this->webhookUrl; + } + /** * {@inheritdoc} * From ccb95c08fdffacfa7a1315d71f12f1c726202342 Mon Sep 17 00:00:00 2001 From: Paul Webster Date: Thu, 3 May 2018 11:15:17 +1200 Subject: [PATCH 25/80] NewRelicHandler - handle Throwable in PHP7 --- src/Monolog/Handler/NewRelicHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Handler/NewRelicHandler.php b/src/Monolog/Handler/NewRelicHandler.php index 6718e9e0..ed2efa27 100644 --- a/src/Monolog/Handler/NewRelicHandler.php +++ b/src/Monolog/Handler/NewRelicHandler.php @@ -84,7 +84,7 @@ class NewRelicHandler extends AbstractProcessingHandler unset($record['formatted']['context']['transaction_name']); } - if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) { + if (isset($record['context']['exception']) && ($record['context']['exception'] instanceof \Exception || (PHP_VERSION_ID >= 70000 && $record['context']['exception'] instanceof \Throwable))) { newrelic_notice_error($record['message'], $record['context']['exception']); unset($record['formatted']['context']['exception']); } else { From 5f95356f3a3f89ef9c5217fa244dfa053f576ed0 Mon Sep 17 00:00:00 2001 From: Florent Viel Date: Thu, 17 May 2018 15:46:52 +0200 Subject: [PATCH 26/80] fix @see reference for logstash Logstash has a new home and is also writte in java instead of ruby. --- src/Monolog/Formatter/LogstashFormatter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Formatter/LogstashFormatter.php b/src/Monolog/Formatter/LogstashFormatter.php index 3cf31dd4..7fa357c4 100644 --- a/src/Monolog/Formatter/LogstashFormatter.php +++ b/src/Monolog/Formatter/LogstashFormatter.php @@ -14,8 +14,8 @@ namespace Monolog\Formatter; /** * Serializes a log message to Logstash Event Format * - * @see http://logstash.net/ - * @see https://github.com/elastic/logstash/blob/master/logstash-core-event/lib/logstash/event.rb + * @see https://www.elastic.co/products/logstash + * @see https://github.com/elastic/logstash/blob/master/logstash-core/src/main/java/org/logstash/Event.java * * @author Tim Mower */ From cf0ac7e33d1cecfa35c55c2193749eb1877cb35c Mon Sep 17 00:00:00 2001 From: Flavio Maria De Stefano Date: Fri, 18 May 2018 12:13:16 +0200 Subject: [PATCH 27/80] Typo on method name --- tests/Monolog/Handler/ErrorLogHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Monolog/Handler/ErrorLogHandlerTest.php b/tests/Monolog/Handler/ErrorLogHandlerTest.php index d230fb1f..16d8e47d 100644 --- a/tests/Monolog/Handler/ErrorLogHandlerTest.php +++ b/tests/Monolog/Handler/ErrorLogHandlerTest.php @@ -32,7 +32,7 @@ class ErrorLogHandlerTest extends TestCase * @expectedException InvalidArgumentException * @expectedExceptionMessage The given message type "42" is not supported */ - public function testShouldNotAcceptAnInvalidTypeOnContructor() + public function testShouldNotAcceptAnInvalidTypeOnConstructor() { new ErrorLogHandler(42); } From a15c1daf9136bda720978775e52ad407db41f353 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Mon, 4 Jun 2018 13:35:27 +0200 Subject: [PATCH 28/80] Use late static bindings in BrowserConsoleHandler --- src/Monolog/Handler/BrowserConsoleHandler.php | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Monolog/Handler/BrowserConsoleHandler.php b/src/Monolog/Handler/BrowserConsoleHandler.php index b3a21bd4..0225ee71 100644 --- a/src/Monolog/Handler/BrowserConsoleHandler.php +++ b/src/Monolog/Handler/BrowserConsoleHandler.php @@ -43,11 +43,11 @@ class BrowserConsoleHandler extends AbstractProcessingHandler protected function write(array $record) { // Accumulate records - self::$records[] = $record; + static::$records[] = $record; // Register shutdown handler if not already done - if (!self::$initialized) { - self::$initialized = true; + if (!static::$initialized) { + static::$initialized = true; $this->registerShutdownFunction(); } } @@ -58,18 +58,18 @@ class BrowserConsoleHandler extends AbstractProcessingHandler */ public static function send() { - $format = self::getResponseFormat(); + $format = static::getResponseFormat(); if ($format === 'unknown') { return; } - if (count(self::$records)) { + if (count(static::$records)) { if ($format === 'html') { - self::writeOutput(''); + static::writeOutput(''); } elseif ($format === 'js') { - self::writeOutput(self::generateScript()); + static::writeOutput(static::generateScript()); } - self::reset(); + static::reset(); } } @@ -78,7 +78,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler */ public static function reset() { - self::$records = array(); + static::$records = array(); } /** @@ -133,18 +133,18 @@ class BrowserConsoleHandler extends AbstractProcessingHandler private static function generateScript() { $script = array(); - foreach (self::$records as $record) { - $context = self::dump('Context', $record['context']); - $extra = self::dump('Extra', $record['extra']); + foreach (static::$records as $record) { + $context = static::dump('Context', $record['context']); + $extra = static::dump('Extra', $record['extra']); if (empty($context) && empty($extra)) { - $script[] = self::call_array('log', self::handleStyles($record['formatted'])); + $script[] = static::call_array('log', static::handleStyles($record['formatted'])); } else { $script = array_merge($script, - array(self::call_array('groupCollapsed', self::handleStyles($record['formatted']))), + array(static::call_array('groupCollapsed', static::handleStyles($record['formatted']))), $context, $extra, - array(self::call('groupEnd')) + array(static::call('groupEnd')) ); } } @@ -154,19 +154,19 @@ class BrowserConsoleHandler extends AbstractProcessingHandler private static function handleStyles($formatted) { - $args = array(self::quote('font-weight: normal')); + $args = array(static::quote('font-weight: normal')); $format = '%c' . $formatted; preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); foreach (array_reverse($matches) as $match) { - $args[] = self::quote(self::handleCustomStyles($match[2][0], $match[1][0])); + $args[] = static::quote(static::handleCustomStyles($match[2][0], $match[1][0])); $args[] = '"font-weight: normal"'; $pos = $match[0][1]; $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0])); } - array_unshift($args, self::quote($format)); + array_unshift($args, static::quote($format)); return $args; } @@ -198,13 +198,13 @@ class BrowserConsoleHandler extends AbstractProcessingHandler if (empty($dict)) { return $script; } - $script[] = self::call('log', self::quote('%c%s'), self::quote('font-weight: bold'), self::quote($title)); + $script[] = static::call('log', static::quote('%c%s'), static::quote('font-weight: bold'), static::quote($title)); foreach ($dict as $key => $value) { $value = json_encode($value); if (empty($value)) { - $value = self::quote(''); + $value = static::quote(''); } - $script[] = self::call('log', self::quote('%s: %o'), self::quote($key), $value); + $script[] = static::call('log', static::quote('%s: %o'), static::quote($key), $value); } return $script; @@ -220,7 +220,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler $args = func_get_args(); $method = array_shift($args); - return self::call_array($method, $args); + return static::call_array($method, $args); } private static function call_array($method, array $args) From 678693e5eff4c360b376d28311fbce15601ab0be Mon Sep 17 00:00:00 2001 From: tnucera Date: Tue, 11 Jul 2017 12:40:56 +0200 Subject: [PATCH 29/80] Add context to fluentd formatter --- src/Monolog/Formatter/FluentdFormatter.php | 1 + tests/Monolog/Formatter/FluentdFormatterTest.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Formatter/FluentdFormatter.php b/src/Monolog/Formatter/FluentdFormatter.php index 02632bb5..46a91ffe 100644 --- a/src/Monolog/Formatter/FluentdFormatter.php +++ b/src/Monolog/Formatter/FluentdFormatter.php @@ -62,6 +62,7 @@ class FluentdFormatter implements FormatterInterface $message = array( 'message' => $record['message'], + 'context' => $record['context'], 'extra' => $record['extra'], ); diff --git a/tests/Monolog/Formatter/FluentdFormatterTest.php b/tests/Monolog/Formatter/FluentdFormatterTest.php index 622b2bae..fd36dbcf 100644 --- a/tests/Monolog/Formatter/FluentdFormatterTest.php +++ b/tests/Monolog/Formatter/FluentdFormatterTest.php @@ -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) ); } From 68e39bd84f4ba24d9bc36bd44dfaa4dfd75c5c45 Mon Sep 17 00:00:00 2001 From: George Mponos Date: Sun, 18 Mar 2018 11:30:04 +0200 Subject: [PATCH 30/80] Add a record with an object as context --- tests/Monolog/Handler/Slack/SlackRecordTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Monolog/Handler/Slack/SlackRecordTest.php b/tests/Monolog/Handler/Slack/SlackRecordTest.php index e1aa96d7..ae42393c 100644 --- a/tests/Monolog/Handler/Slack/SlackRecordTest.php +++ b/tests/Monolog/Handler/Slack/SlackRecordTest.php @@ -353,6 +353,14 @@ class SlackRecordTest extends TestCase $this->assertSame($record['datetime']->getTimestamp(), $attachment['ts']); } + public function testContextHasException() + { + $record = $this->getRecord(Logger::CRITICAL, 'This is a critical message.', array('exception' => new \Exception())); + $slackRecord = new SlackRecord(null, null, true, null, false, true); + $data = $slackRecord->getSlackData($record); + $this->assertInternalType('string', $data['attachments'][0]['fields'][1]['value']); + } + public function testExcludeExtraAndContextFields() { $record = $this->getRecord( From 07681ea4ba6fc0cb0077110000369f638863d8e8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 7 Jun 2018 18:23:28 +0200 Subject: [PATCH 31/80] Fix normalization of objects in SlackRecord, closes #1127 --- src/Monolog/Handler/Slack/SlackRecord.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 src/Monolog/Handler/Slack/SlackRecord.php diff --git a/src/Monolog/Handler/Slack/SlackRecord.php b/src/Monolog/Handler/Slack/SlackRecord.php old mode 100644 new mode 100755 index 38bc838a..71b42960 --- a/src/Monolog/Handler/Slack/SlackRecord.php +++ b/src/Monolog/Handler/Slack/SlackRecord.php @@ -229,8 +229,8 @@ class SlackRecord /** * Generates attachment field * - * @param string $title - * @param string|array $value\ + * @param string $title + * @param string|array $value * * @return array */ @@ -257,7 +257,7 @@ class SlackRecord private function generateAttachmentFields(array $data) { $fields = array(); - foreach ($data as $key => $value) { + foreach ($this->normalizerFormatter->format($data) as $key => $value) { $fields[] = $this->generateAttachmentField($key, $value); } From 8c4539f1fea4f37998d95eedc917edb1620b8abf Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 7 Jun 2018 18:45:07 +0200 Subject: [PATCH 32/80] More boolean=>bool --- src/Monolog/Handler/ChromePHPHandler.php | 4 +- src/Monolog/Handler/PushoverHandler.php | 2 +- src/Monolog/Handler/SocketHandler.php | 2 +- src/Monolog/Handler/SwiftMailerHandler.php | 2 +- src/Monolog/Logger.php | 126 ++++++++++----------- src/Monolog/Processor/MemoryProcessor.php | 4 +- 6 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/Monolog/Handler/ChromePHPHandler.php b/src/Monolog/Handler/ChromePHPHandler.php index ea8ae7fb..37419a06 100644 --- a/src/Monolog/Handler/ChromePHPHandler.php +++ b/src/Monolog/Handler/ChromePHPHandler.php @@ -32,7 +32,7 @@ class ChromePHPHandler extends AbstractProcessingHandler * Header name */ const HEADER_NAME = 'X-ChromeLogger-Data'; - + /** * Regular expression to detect supported browsers (matches any Chrome, or Firefox 43+) */ @@ -174,7 +174,7 @@ class ChromePHPHandler extends AbstractProcessingHandler /** * Verifies if the headers are accepted by the current user agent * - * @return Boolean + * @return bool */ protected function headersAccepted() { diff --git a/src/Monolog/Handler/PushoverHandler.php b/src/Monolog/Handler/PushoverHandler.php index 168a1c7b..f27bb3da 100644 --- a/src/Monolog/Handler/PushoverHandler.php +++ b/src/Monolog/Handler/PushoverHandler.php @@ -180,6 +180,6 @@ class PushoverHandler extends SocketHandler */ public function useFormattedMessage($value) { - $this->useFormattedMessage = (boolean) $value; + $this->useFormattedMessage = (bool) $value; } } diff --git a/src/Monolog/Handler/SocketHandler.php b/src/Monolog/Handler/SocketHandler.php index 73a51311..79d49ece 100644 --- a/src/Monolog/Handler/SocketHandler.php +++ b/src/Monolog/Handler/SocketHandler.php @@ -87,7 +87,7 @@ class SocketHandler extends AbstractProcessingHandler */ public function setPersistent($persistent) { - $this->persistent = (boolean) $persistent; + $this->persistent = (bool) $persistent; } /** diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index 72f44a53..bcba88e6 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -29,7 +29,7 @@ class SwiftMailerHandler extends MailHandler * @param \Swift_Mailer $mailer The mailer to use * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced * @param int $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true) { diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 994bba96..db67777f 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -347,9 +347,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the DEBUG level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addDebug($message, array $context = array()) { @@ -359,9 +359,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the INFO level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addInfo($message, array $context = array()) { @@ -371,9 +371,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the NOTICE level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addNotice($message, array $context = array()) { @@ -383,9 +383,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the WARNING level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addWarning($message, array $context = array()) { @@ -395,9 +395,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the ERROR level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addError($message, array $context = array()) { @@ -407,9 +407,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the CRITICAL level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addCritical($message, array $context = array()) { @@ -419,9 +419,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the ALERT level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addAlert($message, array $context = array()) { @@ -431,9 +431,9 @@ class Logger implements LoggerInterface /** * Adds a log record at the EMERGENCY level. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addEmergency($message, array $context = array()) { @@ -507,9 +507,9 @@ class Logger implements LoggerInterface * This method allows for compatibility with common interfaces. * * @param mixed $level The log level - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function log($level, $message, array $context = array()) { @@ -523,9 +523,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function debug($message, array $context = array()) { @@ -537,9 +537,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function info($message, array $context = array()) { @@ -551,9 +551,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function notice($message, array $context = array()) { @@ -565,9 +565,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function warn($message, array $context = array()) { @@ -579,9 +579,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function warning($message, array $context = array()) { @@ -593,9 +593,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function err($message, array $context = array()) { @@ -607,9 +607,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function error($message, array $context = array()) { @@ -621,9 +621,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function crit($message, array $context = array()) { @@ -635,9 +635,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function critical($message, array $context = array()) { @@ -649,9 +649,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function alert($message, array $context = array()) { @@ -663,9 +663,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function emerg($message, array $context = array()) { @@ -677,9 +677,9 @@ class Logger implements LoggerInterface * * This method allows for compatibility with common interfaces. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function emergency($message, array $context = array()) { diff --git a/src/Monolog/Processor/MemoryProcessor.php b/src/Monolog/Processor/MemoryProcessor.php index 85f9dc5e..73f132d7 100644 --- a/src/Monolog/Processor/MemoryProcessor.php +++ b/src/Monolog/Processor/MemoryProcessor.php @@ -34,8 +34,8 @@ abstract class MemoryProcessor */ public function __construct($realUsage = true, $useFormatting = true) { - $this->realUsage = (boolean) $realUsage; - $this->useFormatting = (boolean) $useFormatting; + $this->realUsage = (bool) $realUsage; + $this->useFormatting = (bool) $useFormatting; } /** From 9d654f4389ec3396a8e02fdcfc042937cb457f3a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 7 Jun 2018 19:14:19 +0200 Subject: [PATCH 33/80] Update minimum PHP requirement for upcoming 2.0 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index bc87c44c..9135f7b6 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ } ], "require": { - "php": "^7.0", + "php": "^7.1", "psr/log": "^1.0.1" }, "require-dev": { @@ -54,7 +54,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.x-dev" } }, "scripts": { From dfa21a506e9395fe9fe83436bf4c3bb13e093d1c Mon Sep 17 00:00:00 2001 From: Mponos George Date: Thu, 7 Jun 2018 20:17:53 +0300 Subject: [PATCH 34/80] Update .travis.yml (#1120) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index fa6119c8..07bad617 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ php: - 5.6 - 7.0 - 7.1 + - 7.2 - nightly matrix: From 2aa45553d8770c9b6c66820ad18d3e4b2ac3e5d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Thu, 7 Jun 2018 19:20:58 +0200 Subject: [PATCH 35/80] Fix: Remove VersionEye badge (#1140) --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 7d8ade52..d7569446 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![Total Downloads](https://img.shields.io/packagist/dt/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) [![Latest Stable Version](https://img.shields.io/packagist/v/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) -[![Reference Status](https://www.versioneye.com/php/monolog:monolog/reference_badge.svg)](https://www.versioneye.com/php/monolog:monolog/references) Monolog sends your logs to files, sockets, inboxes, databases and various From 3507f48edb359410f26b080b80b979773f96898f Mon Sep 17 00:00:00 2001 From: Luke Waite Date: Thu, 7 Jun 2018 13:22:49 -0400 Subject: [PATCH 36/80] Remove conditional php version check for debug_backtrace legacy support (#1134) --- src/Monolog/Processor/IntrospectionProcessor.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Monolog/Processor/IntrospectionProcessor.php b/src/Monolog/Processor/IntrospectionProcessor.php index 3a275293..e1b5d3a3 100644 --- a/src/Monolog/Processor/IntrospectionProcessor.php +++ b/src/Monolog/Processor/IntrospectionProcessor.php @@ -51,12 +51,7 @@ class IntrospectionProcessor return $record; } - /* - * http://php.net/manual/en/function.debug-backtrace.php - * As of 5.3.6, DEBUG_BACKTRACE_IGNORE_ARGS option was added. - * Any version less than 5.3.6 must use the DEBUG_BACKTRACE_IGNORE_ARGS constant value '2'. - */ - $trace = debug_backtrace((PHP_VERSION_ID < 50306) ? 2 : DEBUG_BACKTRACE_IGNORE_ARGS); + $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // skip first since it's always the current method array_shift($trace); From 613097f5fe47cba5f1f1ccdac61278fdd71606f7 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 7 Jun 2018 19:24:05 +0200 Subject: [PATCH 37/80] Remove 7.0 build --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 29a4c720..04516150 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ sudo: false dist: trusty php: - - 7.0 - 7.1 - 7.2 - nightly @@ -15,7 +14,7 @@ cache: matrix: include: - - php: 7.0 + - php: 7.1 env: deps=low fast_finish: true From 80130283d588314bd9cbebf808cc58eabae4c0ae Mon Sep 17 00:00:00 2001 From: ilyaplot Date: Thu, 7 Jun 2018 20:30:30 +0300 Subject: [PATCH 38/80] Update README.md (#1098) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b5c9907..ba9f6da3 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/mono - [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog. - [FuelPHP](http://fuelphp.com/) comes out of the box with Monolog. - [Equip Framework](https://github.com/equip/framework) comes out of the box with Monolog. -- [Yii 2](http://www.yiiframework.com/) is usable with Monolog via the [yii2-monolog](https://github.com/merorafael/yii2-monolog) plugin. +- [Yii 2](http://www.yiiframework.com/) is usable with Monolog via the [yii2-monolog](https://github.com/merorafael/yii2-monolog) or [yii2-psr-log-target](https://github.com/samdark/yii2-psr-log-target) plugins. - [Hawkbit Micro Framework](https://github.com/HawkBitPhp/hawkbit) comes out of the box with Monolog. ### Author From 68cf3c69d11ea3366564ab29a4f7ddd579bb59d7 Mon Sep 17 00:00:00 2001 From: Tom Rochette Date: Fri, 5 Jan 2018 14:38:31 -0500 Subject: [PATCH 39/80] Allow JsonFormatter maximum normalized depth and maximum number of items per level to be configured in the constructor. --- src/Monolog/Formatter/JsonFormatter.php | 36 ++++++++++++++-- tests/Monolog/Formatter/JsonFormatterTest.php | 41 +++++++++++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index 8e2f2fdd..1fcfd579 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -27,6 +27,8 @@ class JsonFormatter extends NormalizerFormatter protected $batchMode; protected $appendNewline; + protected $maxNormalizeDepth = 9; + protected $maxNormalizeItemCount = 1000; /** * @var bool @@ -59,6 +61,32 @@ class JsonFormatter extends NormalizerFormatter return $this->appendNewline; } + /** + * The maximum number of normalization levels to go through + */ + public function getMaxNormalizeDepth(): int + { + return $this->maxNormalizeDepth; + } + + public function setMaxNormalizeDepth(int $maxNormalizeDepth): void + { + $this->maxNormalizeDepth = $maxNormalizeDepth; + } + + /** + * The maximum number of items to normalize per level + */ + public function getMaxNormalizeItemCount(): int + { + return $this->maxNormalizeItemCount; + } + + public function setMaxNormalizeItemCount(int $maxNormalizeItemCount): void + { + $this->maxNormalizeItemCount = $maxNormalizeItemCount; + } + /** * {@inheritdoc} */ @@ -122,8 +150,8 @@ class JsonFormatter extends NormalizerFormatter */ protected function normalize($data, int $depth = 0) { - if ($depth > 9) { - return 'Over 9 levels deep, aborting normalization'; + if ($depth > $this->maxNormalizeDepth) { + return 'Over '.$this->maxNormalizeDepth.' levels deep, aborting normalization'; } if (is_array($data) || $data instanceof \Traversable) { @@ -131,8 +159,8 @@ class JsonFormatter extends NormalizerFormatter $count = 1; foreach ($data as $key => $value) { - if ($count++ >= 1000) { - $normalized['...'] = 'Over 1000 items, aborting normalization'; + if ($count++ >= $this->maxNormalizeItemCount) { + $normalized['...'] = 'Over '.$this->maxNormalizeItemCount.' items, aborting normalization'; break; } $normalized[$key] = $this->normalize($value, $depth + 1); diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index 6dfdbb7a..699c27a3 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -110,6 +110,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, aborting normalization"}'."\n", + $message + ); + } + + public function testMaxNormalizeItemCountWith3ItemsMax() + { + $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true); + $formatter->setMaxNormalizeDepth(9); + $formatter->setMaxNormalizeItemCount(3); + $throwable = new \Error('Foo'); + + $message = $this->formatRecordWithExceptionInContext($formatter, $throwable); + + $this->assertEquals( + '{"level_name":"CRITICAL","channel":"core","...":"Over 3 items, aborting normalization"}'."\n", + $message + ); + } + /** * @param string $expected * @param string $actual From c0eeca76fdb1b5410e7af36bbfe5af265eeb5bf6 Mon Sep 17 00:00:00 2001 From: Josh McRae Date: Wed, 16 Aug 2017 13:54:33 +1000 Subject: [PATCH 40/80] Check for directory before throwing 'no existing directory' exception --- src/Monolog/Handler/StreamHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Handler/StreamHandler.php b/src/Monolog/Handler/StreamHandler.php index dd4f7109..a35b7e4c 100644 --- a/src/Monolog/Handler/StreamHandler.php +++ b/src/Monolog/Handler/StreamHandler.php @@ -167,7 +167,7 @@ class StreamHandler extends AbstractProcessingHandler set_error_handler(array($this, 'customErrorHandler')); $status = mkdir($dir, 0777, true); restore_error_handler(); - if (false === $status) { + if (false === $status && !is_dir($dir)) { throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and its not buildable: '.$this->errorMessage, $dir)); } } From 11b664d2764dcb420250012ef1b3447e56173768 Mon Sep 17 00:00:00 2001 From: George Mponos Date: Fri, 8 Jun 2018 20:30:09 +0300 Subject: [PATCH 41/80] Fix constructor of slack --- src/Monolog/Handler/SlackHandler.php | 3 +-- src/Monolog/Handler/SlackWebhookHandler.php | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Monolog/Handler/SlackHandler.php b/src/Monolog/Handler/SlackHandler.php index 45d634f4..4a16063d 100644 --- a/src/Monolog/Handler/SlackHandler.php +++ b/src/Monolog/Handler/SlackHandler.php @@ -63,8 +63,7 @@ class SlackHandler extends SocketHandler $iconEmoji, $useShortAttachment, $includeContextAndExtra, - $excludeFields, - $this->formatter + $excludeFields ); $this->token = $token; diff --git a/src/Monolog/Handler/SlackWebhookHandler.php b/src/Monolog/Handler/SlackWebhookHandler.php index 1ef85fae..265327d0 100644 --- a/src/Monolog/Handler/SlackWebhookHandler.php +++ b/src/Monolog/Handler/SlackWebhookHandler.php @@ -60,8 +60,7 @@ class SlackWebhookHandler extends AbstractProcessingHandler $iconEmoji, $useShortAttachment, $includeContextAndExtra, - $excludeFields, - $this->formatter + $excludeFields ); } From 22b92c7c00d495b4a9cb043bc592aa5a3f9065c8 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Mon, 10 Jul 2017 19:18:17 +1200 Subject: [PATCH 42/80] Fixed message not being passed to client when capturing an exception The raven client expects the message to be at the first level of the data array when passing an exception. see https://github.com/getsentry/sentry-php/blob/master/lib/Raven/Client.php#L795 --- src/Monolog/Handler/RavenHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Handler/RavenHandler.php b/src/Monolog/Handler/RavenHandler.php index eb5dda08..34ff0091 100644 --- a/src/Monolog/Handler/RavenHandler.php +++ b/src/Monolog/Handler/RavenHandler.php @@ -180,7 +180,7 @@ class RavenHandler extends AbstractProcessingHandler } if (isset($record['context']['exception']) && ($record['context']['exception'] instanceof \Exception || (PHP_VERSION_ID >= 70000 && $record['context']['exception'] instanceof \Throwable))) { - $options['extra']['message'] = $record['formatted']; + $options['message'] = $record['formatted']; $this->ravenClient->captureException($record['context']['exception'], $options); } else { $this->ravenClient->captureMessage($record['formatted'], array(), $options); From 513e237375a0e81c68f692a57a6b837891eed41d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 8 Jun 2018 20:27:50 +0200 Subject: [PATCH 43/80] Update docblocks some more --- src/Monolog/ErrorHandler.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Monolog/ErrorHandler.php b/src/Monolog/ErrorHandler.php index e63ce346..e8660134 100644 --- a/src/Monolog/ErrorHandler.php +++ b/src/Monolog/ErrorHandler.php @@ -49,9 +49,9 @@ class ErrorHandler * * By default it will handle errors, exceptions and fatal errors * - * @param LoggerInterface $logger - * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling - * @param array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling + * @param LoggerInterface $logger + * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling + * @param array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling * @param string|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling * @return ErrorHandler */ @@ -103,7 +103,11 @@ class ErrorHandler return $this; } - public function registerFatalHandler($level = null, $reservedMemorySize = 20): self + /** + * @param string|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling + * @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done + */ + public function registerFatalHandler($level = null, int $reservedMemorySize = 20): self { register_shutdown_function([$this, 'handleFatalError']); From 3035d4a251c989b4795635b33d4cc4e1bb662b7e Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Wed, 12 Jul 2017 07:45:50 +0100 Subject: [PATCH 44/80] Fix WhatFailureGroupHandler::handleBatch when the handler has processors --- .../Handler/WhatFailureGroupHandler.php | 10 ++++++++ .../Handler/WhatFailureGroupHandlerTest.php | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/Monolog/Handler/WhatFailureGroupHandler.php b/src/Monolog/Handler/WhatFailureGroupHandler.php index 2732ba3d..6bc4671c 100644 --- a/src/Monolog/Handler/WhatFailureGroupHandler.php +++ b/src/Monolog/Handler/WhatFailureGroupHandler.php @@ -48,6 +48,16 @@ class WhatFailureGroupHandler extends GroupHandler */ public function handleBatch(array $records) { + if ($this->processors) { + $processed = array(); + foreach ($records as $record) { + foreach ($this->processors as $processor) { + $processed[] = call_user_func($processor, $record); + } + } + $records = $processed; + } + foreach ($this->handlers as $handler) { try { $handler->handleBatch($records); diff --git a/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php b/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php index 8d37a1fc..0594a232 100644 --- a/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php +++ b/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php @@ -87,6 +87,29 @@ class WhatFailureGroupHandlerTest extends TestCase $this->assertTrue($records[0]['extra']['foo']); } + /** + * @covers Monolog\Handler\WhatFailureGroupHandler::handleBatch + */ + public function testHandleBatchUsesProcessors() + { + $testHandlers = array(new TestHandler(), new TestHandler()); + $handler = new WhatFailureGroupHandler($testHandlers); + $handler->pushProcessor(function ($record) { + $record['extra']['foo'] = true; + + return $record; + }); + $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO))); + foreach ($testHandlers as $test) { + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 2); + $records = $test->getRecords(); + $this->assertTrue($records[0]['extra']['foo']); + $this->assertTrue($records[1]['extra']['foo']); + } + } + /** * @covers Monolog\Handler\WhatFailureGroupHandler::handle */ From 6d79e51f91de32c7ea9d85e2a1ad1c92ea34779e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 8 Jun 2018 20:47:04 +0200 Subject: [PATCH 45/80] Tweaks to exception handler, refs #1012 --- src/Monolog/Logger.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index bb14a026..28e9cf98 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -15,6 +15,7 @@ use Monolog\Handler\HandlerInterface; use Monolog\Handler\StreamHandler; use Psr\Log\LoggerInterface; use Psr\Log\InvalidArgumentException; +use Exception; /** * Monolog log channel @@ -346,8 +347,8 @@ class Logger implements LoggerInterface next($this->handlers); } - } catch (\Exception $ex) { - $this->handleException($ex, $record); + } catch (Exception $e) { + $this->handleException($e, $record); } return true; @@ -537,17 +538,14 @@ class Logger implements LoggerInterface /** * Delegates exception management to the custom exception handler, * or throws the exception if no custom handler is set. - * - * @param Exception $ex - * @param array $record */ - protected function handleException(\Exception $ex, $record) + protected function handleException(Exception $e, array $record) { - if ($this->exceptionHandler) { - call_user_func($this->exceptionHandler, $ex, $record); - } else { - throw $ex; + if (!$this->exceptionHandler) { + throw $e; } + + call_user_func($this->exceptionHandler, $e, $record); } /** From 948bb4a6a0ec78b4912332aff3c38bb884017b83 Mon Sep 17 00:00:00 2001 From: Thomas Schulz Date: Mon, 26 Mar 2018 17:45:38 +0200 Subject: [PATCH 46/80] Improve table row output in HtmlFormatter --- src/Monolog/Formatter/HtmlFormatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Formatter/HtmlFormatter.php b/src/Monolog/Formatter/HtmlFormatter.php index 3eec95f6..8faa8030 100644 --- a/src/Monolog/Formatter/HtmlFormatter.php +++ b/src/Monolog/Formatter/HtmlFormatter.php @@ -58,7 +58,7 @@ class HtmlFormatter extends NormalizerFormatter $td = '
'.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'
'; } - return "\n$th:\n".$td."\n"; + return "\n$th:\n".$td."\n"; } /** From 2893c2b875877ba028029dbfd8b7f757d70b197d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 8 Jun 2018 21:43:50 +0200 Subject: [PATCH 47/80] Specify text color to improve dark theme support, refs #1128 --- src/Monolog/Formatter/HtmlFormatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Formatter/HtmlFormatter.php b/src/Monolog/Formatter/HtmlFormatter.php index 8faa8030..dfc0b4a3 100644 --- a/src/Monolog/Formatter/HtmlFormatter.php +++ b/src/Monolog/Formatter/HtmlFormatter.php @@ -58,7 +58,7 @@ class HtmlFormatter extends NormalizerFormatter $td = '
'.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'
'; } - return "\n$th:\n".$td."\n"; + return "\n$th:\n".$td."\n"; } /** From 1802e5ab25d5c47c2037d90a18661e448f79169b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 8 Jun 2018 21:58:29 +0200 Subject: [PATCH 48/80] Docblock improvements, fixes #1155 --- src/Monolog/Logger.php | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 4579f842..80fefd19 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -348,9 +348,7 @@ class Logger implements LoggerInterface /** * Gets the name of the logging level. * - * @param int $level * @throws \Psr\Log\InvalidArgumentException If level is not defined - * @return string */ public static function getLevelName(int $level): string { @@ -366,7 +364,6 @@ class Logger implements LoggerInterface * * @param string|int Level number (monolog) or name (PSR-3) * @throws \Psr\Log\InvalidArgumentException If level is not defined - * @return int */ public static function toMonologLevel($level): int { @@ -383,9 +380,6 @@ class Logger implements LoggerInterface /** * Checks whether the Logger has a handler that listens on the given level - * - * @param int $level - * @return bool */ public function isHandling(int $level): bool { @@ -540,9 +534,7 @@ class Logger implements LoggerInterface } /** - * Set the timezone to be used for the timestamp of log records. - * - * @param DateTimeZone $tz Timezone object + * Sets the timezone to be used for the timestamp of log records. */ public function setTimezone(DateTimeZone $tz): self { @@ -552,9 +544,7 @@ class Logger implements LoggerInterface } /** - * Set the timezone to be used for the timestamp of log records. - * - * @return DateTimeZone + * Returns the timezone to be used for the timestamp of log records. */ public function getTimezone(): DateTimeZone { From 5f8783686e6486a8080980c4662518197f5c89b5 Mon Sep 17 00:00:00 2001 From: Alban Kora Date: Tue, 3 Oct 2017 23:54:38 +0100 Subject: [PATCH 49/80] Fixing file rotation when similar files are present --- src/Monolog/Handler/RotatingFileHandler.php | 2 +- .../Handler/RotatingFileHandlerTest.php | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Monolog/Handler/RotatingFileHandler.php b/src/Monolog/Handler/RotatingFileHandler.php index c8cdfab6..cc9fd4d3 100644 --- a/src/Monolog/Handler/RotatingFileHandler.php +++ b/src/Monolog/Handler/RotatingFileHandler.php @@ -166,7 +166,7 @@ class RotatingFileHandler extends StreamHandler $fileInfo = pathinfo($this->filename); $glob = str_replace( array('{filename}', '{date}'), - array($fileInfo['filename'], '*'), + array($fileInfo['filename'], '[0-9][0-9][0-9][0-9]*'), $fileInfo['dirname'] . '/' . $this->filenameFormat ); if (!empty($fileInfo['extension'])) { diff --git a/tests/Monolog/Handler/RotatingFileHandlerTest.php b/tests/Monolog/Handler/RotatingFileHandlerTest.php index f1feb228..0f99580c 100644 --- a/tests/Monolog/Handler/RotatingFileHandlerTest.php +++ b/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -191,6 +191,40 @@ class RotatingFileHandlerTest extends TestCase ); } + /** + * @dataProvider rotationWhenSimilarFilesExistTests + */ + public function testRotationWhenSimilarFileNamesExist($dateFormat) + { + touch($old1 = __DIR__.'/Fixtures/foo-foo-'.date($dateFormat).'.rot'); + touch($old2 = __DIR__.'/Fixtures/foo-bar-'.date($dateFormat).'.rot'); + + $log = __DIR__.'/Fixtures/foo-'.date($dateFormat).'.rot'; + + $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->setFilenameFormat('{filename}-{date}', $dateFormat); + $handler->handle($this->getRecord()); + $handler->close(); + + $this->assertTrue(file_exists($log)); + } + + public function rotationWhenSimilarFilesExistTests() + { + + return [ + 'Rotation is triggered when the file of the current day is not present but similar exists' + => [RotatingFileHandler::FILE_PER_DAY], + + 'Rotation is triggered when the file of the current month is not present but similar exists' + => [RotatingFileHandler::FILE_PER_MONTH], + + 'Rotation is triggered when the file of the current year is not present but similar exists' + => [RotatingFileHandler::FILE_PER_YEAR], + ]; + } + public function testReuseCurrentFile() { $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot'; From ada5d30511cb9dac9b90f4f501f6dc2a51525f53 Mon Sep 17 00:00:00 2001 From: Minh-Quan TRAN Date: Thu, 17 Aug 2017 17:11:16 +0200 Subject: [PATCH 50/80] If context has exactly 1000 items, do not truncate --- src/Monolog/Formatter/JsonFormatter.php | 5 +-- src/Monolog/Formatter/NormalizerFormatter.php | 3 +- tests/Monolog/Formatter/JsonFormatterTest.php | 36 +++++++++++++++++++ .../Formatter/NormalizerFormatterTest.php | 20 ++++++++++- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index 0782f149..247122a2 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -145,10 +145,11 @@ class JsonFormatter extends NormalizerFormatter $count = 1; foreach ($data as $key => $value) { - if ($count++ >= 1000) { - $normalized['...'] = 'Over 1000 items, aborting normalization'; + if ($count++ > 1000) { + $normalized['...'] = 'Over 1000 items ('.count($data).' total), aborting normalization'; break; } + $normalized[$key] = $this->normalize($value); } diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index d4414882..e6142b63 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -75,10 +75,11 @@ class NormalizerFormatter implements FormatterInterface $count = 1; foreach ($data as $key => $value) { - if ($count++ >= 1000) { + if ($count++ > 1000) { $normalized['...'] = 'Over 1000 items ('.count($data).' total), aborting normalization'; break; } + $normalized[$key] = $this->normalize($value); } diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index c9445f36..24b06cc9 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -180,4 +180,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]['...']); + } } diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index 57bcdf98..44c1e660 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -217,6 +217,24 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $this->assertEquals(@json_encode(array($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(); @@ -231,7 +249,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]['...']); } From 800fe2cc1a461e9262b3982e4b017b37afe19dcc Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 8 Jun 2018 23:09:04 +0200 Subject: [PATCH 51/80] Migrate maxNormalizeDepth/maxNormalizeItemCount props and setters to NormalizerFormatter --- src/Monolog/Formatter/JsonFormatter.php | 28 --------- src/Monolog/Formatter/NormalizerFormatter.php | 36 +++++++++-- tests/Monolog/Formatter/JsonFormatterTest.php | 6 +- .../Formatter/NormalizerFormatterTest.php | 62 +++++++++++++++++++ 4 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index 10a62c19..28086e10 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -27,8 +27,6 @@ class JsonFormatter extends NormalizerFormatter protected $batchMode; protected $appendNewline; - protected $maxNormalizeDepth = 9; - protected $maxNormalizeItemCount = 1000; /** * @var bool @@ -61,32 +59,6 @@ class JsonFormatter extends NormalizerFormatter return $this->appendNewline; } - /** - * The maximum number of normalization levels to go through - */ - public function getMaxNormalizeDepth(): int - { - return $this->maxNormalizeDepth; - } - - public function setMaxNormalizeDepth(int $maxNormalizeDepth): void - { - $this->maxNormalizeDepth = $maxNormalizeDepth; - } - - /** - * The maximum number of items to normalize per level - */ - public function getMaxNormalizeItemCount(): int - { - return $this->maxNormalizeItemCount; - } - - public function setMaxNormalizeItemCount(int $maxNormalizeItemCount): void - { - $this->maxNormalizeItemCount = $maxNormalizeItemCount; - } - /** * {@inheritdoc} */ diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index 857f9a0f..14d5e37e 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -24,6 +24,8 @@ class NormalizerFormatter implements FormatterInterface const SIMPLE_DATE = "Y-m-d\TH:i:sP"; protected $dateFormat; + protected $maxNormalizeDepth = 9; + protected $maxNormalizeItemCount = 1000; /** * @param string $dateFormat The format of the timestamp: one supported by DateTime::format @@ -56,14 +58,40 @@ class NormalizerFormatter implements FormatterInterface return $records; } + /** + * The maximum number of normalization levels to go through + */ + public function getMaxNormalizeDepth(): int + { + return $this->maxNormalizeDepth; + } + + public function setMaxNormalizeDepth(int $maxNormalizeDepth): void + { + $this->maxNormalizeDepth = $maxNormalizeDepth; + } + + /** + * The maximum number of items to normalize per level + */ + public function getMaxNormalizeItemCount(): int + { + return $this->maxNormalizeItemCount; + } + + public function setMaxNormalizeItemCount(int $maxNormalizeItemCount): void + { + $this->maxNormalizeItemCount = $maxNormalizeItemCount; + } + /** * @param mixed $data * @return int|bool|string|null|array */ protected function normalize($data, int $depth = 0) { - if ($depth > 9) { - return 'Over 9 levels deep, aborting normalization'; + if ($depth > $this->maxNormalizeDepth) { + return 'Over ' . $this->maxNormalizeDepth . ' levels deep, aborting normalization'; } if (null === $data || is_scalar($data)) { @@ -84,8 +112,8 @@ class NormalizerFormatter implements FormatterInterface $count = 1; foreach ($data as $key => $value) { - if ($count++ > 1000) { - $normalized['...'] = 'Over 1000 items ('.count($data).' total), aborting normalization'; + if ($count++ > $this->maxNormalizeItemCount) { + $normalized['...'] = 'Over ' . $this->maxNormalizeItemCount . ' items ('.count($data).' total), aborting normalization'; break; } diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index a8698343..eeb6b5bb 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -166,12 +166,12 @@ class JsonFormatterTest extends TestCase } /** - * @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', diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index 1275e254..b1878797 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -289,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 @@ -387,6 +429,26 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase $result['context']['exception']['trace'][0] ); } + + /** + * @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', + ]); + + return $message; + } } class TestFooNorm From f6842ac92dcffe9e5bd3684c3ea3984e23c0e84d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 8 Jun 2018 23:19:28 +0200 Subject: [PATCH 52/80] Avoid breaking the gelf handler when closing it, fixes #1016 --- src/Monolog/Handler/GelfHandler.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Monolog/Handler/GelfHandler.php b/src/Monolog/Handler/GelfHandler.php index d3847d82..71e46693 100644 --- a/src/Monolog/Handler/GelfHandler.php +++ b/src/Monolog/Handler/GelfHandler.php @@ -47,14 +47,6 @@ class GelfHandler extends AbstractProcessingHandler $this->publisher = $publisher; } - /** - * {@inheritdoc} - */ - public function close() - { - $this->publisher = null; - } - /** * {@inheritdoc} */ From 06f7bfb0ee4284e48e227880feeec1d87b50955a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 8 Jun 2018 23:41:14 +0200 Subject: [PATCH 53/80] Fix 5.3 build --- tests/Monolog/Handler/RotatingFileHandlerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Monolog/Handler/RotatingFileHandlerTest.php b/tests/Monolog/Handler/RotatingFileHandlerTest.php index 0f99580c..ba61caa9 100644 --- a/tests/Monolog/Handler/RotatingFileHandlerTest.php +++ b/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -213,7 +213,7 @@ class RotatingFileHandlerTest extends TestCase public function rotationWhenSimilarFilesExistTests() { - return [ + return array( 'Rotation is triggered when the file of the current day is not present but similar exists' => [RotatingFileHandler::FILE_PER_DAY], @@ -222,7 +222,7 @@ class RotatingFileHandlerTest extends TestCase 'Rotation is triggered when the file of the current year is not present but similar exists' => [RotatingFileHandler::FILE_PER_YEAR], - ]; + ); } public function testReuseCurrentFile() From 5de973cd337335c90007ed4038d5775f251e36bf Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 9 Jun 2018 10:23:30 +0200 Subject: [PATCH 54/80] More 5.3 fixes --- tests/Monolog/Handler/RotatingFileHandlerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Monolog/Handler/RotatingFileHandlerTest.php b/tests/Monolog/Handler/RotatingFileHandlerTest.php index ba61caa9..c6f5fac9 100644 --- a/tests/Monolog/Handler/RotatingFileHandlerTest.php +++ b/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -215,13 +215,13 @@ class RotatingFileHandlerTest extends TestCase return array( 'Rotation is triggered when the file of the current day is not present but similar exists' - => [RotatingFileHandler::FILE_PER_DAY], + => array(RotatingFileHandler::FILE_PER_DAY), 'Rotation is triggered when the file of the current month is not present but similar exists' - => [RotatingFileHandler::FILE_PER_MONTH], + => array(RotatingFileHandler::FILE_PER_MONTH), 'Rotation is triggered when the file of the current year is not present but similar exists' - => [RotatingFileHandler::FILE_PER_YEAR], + => array(RotatingFileHandler::FILE_PER_YEAR), ); } From c7b12a7497413e04e5216cd9e21558eda66e2fbf Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 9 Jun 2018 17:02:23 +0200 Subject: [PATCH 55/80] Json formatter should always format context/extra as an object, fixes #1028 --- src/Monolog/Formatter/JsonFormatter.php | 10 +++++++++- tests/Monolog/Formatter/JsonFormatterTest.php | 6 ++++-- tests/Monolog/Handler/LogmaticHandlerTest.php | 4 ++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index 28086e10..e0d5449e 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -64,7 +64,15 @@ class JsonFormatter extends NormalizerFormatter */ public function format(array $record): string { - return $this->toJson($this->normalize($record), true) . ($this->appendNewline ? "\n" : ''); + $normalized = $this->normalize($record); + if (isset($normalized['context']) && $normalized['context'] === []) { + $normalized['context'] = new \stdClass; + } + if (isset($normalized['extra']) && $normalized['extra'] === []) { + $normalized['extra'] = new \stdClass; + } + + return $this->toJson($normalized, true) . ($this->appendNewline ? "\n" : ''); } /** diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index eeb6b5bb..7ccf5bc8 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -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)); @@ -160,7 +162,7 @@ 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 ); } diff --git a/tests/Monolog/Handler/LogmaticHandlerTest.php b/tests/Monolog/Handler/LogmaticHandlerTest.php index bab74ac9..de33c6bb 100644 --- a/tests/Monolog/Handler/LogmaticHandlerTest.php +++ b/tests/Monolog/Handler/LogmaticHandlerTest.php @@ -37,7 +37,7 @@ class LogmaticHandlerTest extends TestCase fseek($this->res, 0); $content = fread($this->res, 1024); - $this->assertRegexp('/testToken {"message":"Critical write test","context":\[\],"level":500,"level_name":"CRITICAL","channel":"test","datetime":"(.*)","extra":\[\],"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); + $this->assertRegexp('/testToken {"message":"Critical write test","context":{},"level":500,"level_name":"CRITICAL","channel":"test","datetime":"(.*)","extra":{},"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); } public function testWriteBatchContent() @@ -53,7 +53,7 @@ class LogmaticHandlerTest extends TestCase fseek($this->res, 0); $content = fread($this->res, 1024); - $this->assertRegexp('/testToken {"message":"test","context":\[\],"level":300,"level_name":"WARNING","channel":"test","datetime":"(.*)","extra":\[\],"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); + $this->assertRegexp('/testToken {"message":"test","context":{},"level":300,"level_name":"WARNING","channel":"test","datetime":"(.*)","extra":{},"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); } private function createHandler() From 120c434db947f91c3844ea9212ce34d08262335a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 11 Jun 2018 17:22:12 +0200 Subject: [PATCH 56/80] Verify handlers types, fixes #1131 --- src/Monolog/Logger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 28e9cf98..5034ead1 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -147,7 +147,7 @@ class Logger implements LoggerInterface public function __construct($name, array $handlers = array(), array $processors = array()) { $this->name = $name; - $this->handlers = $handlers; + $this->setHandlers($handlers); $this->processors = $processors; } From 5bb1c5fb4fe59d4e8558f0c26fdf59bf9b433d1f Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 11 Jun 2018 17:36:34 +0200 Subject: [PATCH 57/80] Check if monolog runs in web context (#1024) * Check if monolog runs in web context --- src/Monolog/Handler/ChromePHPHandler.php | 11 +++++++++++ src/Monolog/Handler/FirePHPHandler.php | 5 ++++- .../Handler/WebRequestRecognizerTrait.php | 16 ++++++++++++++++ tests/Monolog/Handler/ChromePHPHandlerTest.php | 5 +++++ tests/Monolog/Handler/FirePHPHandlerTest.php | 5 +++++ 5 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/Monolog/Handler/WebRequestRecognizerTrait.php diff --git a/src/Monolog/Handler/ChromePHPHandler.php b/src/Monolog/Handler/ChromePHPHandler.php index 9395c2fc..4cd76bf8 100644 --- a/src/Monolog/Handler/ChromePHPHandler.php +++ b/src/Monolog/Handler/ChromePHPHandler.php @@ -24,6 +24,9 @@ use Monolog\Logger; */ class ChromePHPHandler extends AbstractProcessingHandler { + + use WebRequestRecognizerTrait; + /** * Version of the extension */ @@ -75,6 +78,10 @@ class ChromePHPHandler extends AbstractProcessingHandler */ public function handleBatch(array $records) { + if (!$this->isWebRequest()) { + return; + } + $messages = []; foreach ($records as $record) { @@ -108,6 +115,10 @@ class ChromePHPHandler extends AbstractProcessingHandler */ protected function write(array $record) { + if (!$this->isWebRequest()) { + return; + } + self::$json['rows'][] = $record['formatted']; $this->send(); diff --git a/src/Monolog/Handler/FirePHPHandler.php b/src/Monolog/Handler/FirePHPHandler.php index 49f6837d..d92e2db5 100644 --- a/src/Monolog/Handler/FirePHPHandler.php +++ b/src/Monolog/Handler/FirePHPHandler.php @@ -21,6 +21,9 @@ use Monolog\Formatter\FormatterInterface; */ class FirePHPHandler extends AbstractProcessingHandler { + + use WebRequestRecognizerTrait; + /** * WildFire JSON header message format */ @@ -130,7 +133,7 @@ class FirePHPHandler extends AbstractProcessingHandler */ protected function write(array $record) { - if (!self::$sendHeaders) { + if (!self::$sendHeaders || !$this->isWebRequest()) { return; } diff --git a/src/Monolog/Handler/WebRequestRecognizerTrait.php b/src/Monolog/Handler/WebRequestRecognizerTrait.php new file mode 100644 index 00000000..fb137561 --- /dev/null +++ b/src/Monolog/Handler/WebRequestRecognizerTrait.php @@ -0,0 +1,16 @@ +headers; } + + protected function isWebRequest(): bool + { + return true; + } } diff --git a/tests/Monolog/Handler/FirePHPHandlerTest.php b/tests/Monolog/Handler/FirePHPHandlerTest.php index b62e7fd0..07df2fe8 100644 --- a/tests/Monolog/Handler/FirePHPHandlerTest.php +++ b/tests/Monolog/Handler/FirePHPHandlerTest.php @@ -93,4 +93,9 @@ class TestFirePHPHandler extends FirePHPHandler { return $this->headers; } + + protected function isWebRequest(): bool + { + return true; + } } From 6e1793e966a0042367b661010d8b68dabbb5dd45 Mon Sep 17 00:00:00 2001 From: Sergey Zaika Date: Tue, 12 Jun 2018 00:55:44 +0300 Subject: [PATCH 58/80] Getter for SwiftMailerHandler subject formatter --- src/Monolog/Handler/SwiftMailerHandler.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index bcba88e6..ac7b16ff 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; use Swift; @@ -47,6 +48,17 @@ class SwiftMailerHandler extends MailHandler $this->mailer->send($this->buildMessage($content, $records)); } + /** + * Gets the formatter for the Swift_Message subject. + * + * @param string $format The format of the subject + * @return FormatterInterface + */ + protected function getSubjectFormatter($format) + { + return new LineFormatter($format); + } + /** * Creates instance of Swift_Message to be sent * @@ -69,7 +81,7 @@ class SwiftMailerHandler extends MailHandler } if ($records) { - $subjectFormatter = new LineFormatter($message->getSubject()); + $subjectFormatter = $this->getSubjectFormatter($message->getSubject()); $message->setSubject($subjectFormatter->format($this->getHighestRecord($records))); } From c1b610a676db2fe8ca7a6b3f0f046707d7375e6d Mon Sep 17 00:00:00 2001 From: Sergey Zaika Date: Tue, 12 Jun 2018 02:40:52 +0300 Subject: [PATCH 59/80] fix InsightOpsHandlerTest --- tests/Monolog/Handler/InsightOpsHandlerTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/Monolog/Handler/InsightOpsHandlerTest.php b/tests/Monolog/Handler/InsightOpsHandlerTest.php index 97c18b59..a0338b66 100644 --- a/tests/Monolog/Handler/InsightOpsHandlerTest.php +++ b/tests/Monolog/Handler/InsightOpsHandlerTest.php @@ -11,7 +11,7 @@ namespace Monolog\Handler; - use Monolog\TestCase; + use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -38,7 +38,7 @@ class InsightOpsHandlerTest extends TestCase fseek($this->resource, 0); $content = fread($this->resource, 1024); - $this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] test.CRITICAL: Critical write test/', $content); + $this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}\+00:00\] test.CRITICAL: Critical write test/', $content); } public function testWriteBatchContent() @@ -49,7 +49,7 @@ class InsightOpsHandlerTest extends TestCase fseek($this->resource, 0); $content = fread($this->resource, 1024); - $this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] .* \[\] \[\]\n){3}/', $content); + $this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}\+00:00\] .* \[\] \[\]\n){3}/', $content); } private function createHandler() @@ -57,11 +57,11 @@ class InsightOpsHandlerTest extends TestCase $useSSL = extension_loaded('openssl'); $args = array('testToken', 'us', $useSSL, Logger::DEBUG, true); $this->resource = fopen('php://memory', 'a'); - $this->handler = $this->getMock( - '\Monolog\Handler\InsightOpsHandler', - array('fsockopen', 'streamSetTimeout', 'closeSocket'), - $args - ); + $this->handler = $this->getMockBuilder(InsightOpsHandler::class) + ->setMethods(array('fsockopen', 'streamSetTimeout', 'closeSocket')) + ->setConstructorArgs($args) + ->getMock(); + $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); $reflectionProperty->setAccessible(true); From 738decf3a32f5ce1a602fd3eaa5d93d1cd248773 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 17 Jun 2018 15:46:29 +0200 Subject: [PATCH 60/80] Add types back --- src/Monolog/Handler/SwiftMailerHandler.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index 6f84dd32..73ef3cfc 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -52,10 +52,9 @@ class SwiftMailerHandler extends MailHandler /** * Gets the formatter for the Swift_Message subject. * - * @param string $format The format of the subject - * @return FormatterInterface + * @param string $format The format of the subject */ - protected function getSubjectFormatter($format) + protected function getSubjectFormatter(string $format): FormatterInterface { return new LineFormatter($format); } From c2d1d22b710ea91e1454834a12c1ca7d48065763 Mon Sep 17 00:00:00 2001 From: Artur Moczulski Date: Sun, 17 Jun 2018 07:16:39 -0700 Subject: [PATCH 61/80] Sync RollbarHandler with the latest changes rollbar/rollbar package (#1042) * Sync RollbarHandler and RollbarHandlerTest with the latest changes in the rollbar/rollbar package (1.0+) --- composer.json | 3 +- src/Monolog/Handler/RollbarHandler.php | 36 +++++++------------- tests/Monolog/Handler/RollbarHandlerTest.php | 23 ++++++++----- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/composer.json b/composer.json index af3ecc70..bd253ee6 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "php-console/php-console": "^3.1.3", "jakub-onderka/php-parallel-lint": "^0.9", "predis/predis": "^1.1", - "phpspec/prophecy": "^1.6.1" + "phpspec/prophecy": "^1.6.1", + "rollbar/rollbar": "^1.3" }, "suggest": { "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", diff --git a/src/Monolog/Handler/RollbarHandler.php b/src/Monolog/Handler/RollbarHandler.php index 5b6678e5..f330eeaa 100644 --- a/src/Monolog/Handler/RollbarHandler.php +++ b/src/Monolog/Handler/RollbarHandler.php @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use RollbarNotifier; +use Rollbar\RollbarLogger; use Throwable; use Monolog\Logger; @@ -19,7 +19,7 @@ use Monolog\Logger; * Sends errors to Rollbar * * If the context data contains a `payload` key, that is used as an array - * of payload options to RollbarNotifier's report_message/report_exception methods. + * of payload options to RollbarLogger's log method. * * Rollbar's context info will contain the context + extra keys from the log record * merged, and then on top of that a few keys: @@ -34,11 +34,9 @@ use Monolog\Logger; class RollbarHandler extends AbstractProcessingHandler { /** - * Rollbar notifier - * - * @var RollbarNotifier + * @var RollbarLogger */ - protected $rollbarNotifier; + protected $rollbarLogger; protected $levelMap = [ Logger::DEBUG => 'debug', @@ -61,13 +59,13 @@ class RollbarHandler extends AbstractProcessingHandler protected $initialized = false; /** - * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token + * @param RollbarLogger $rollbarLogger RollbarLogger object constructed with valid token * @param int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ - public function __construct(RollbarNotifier $rollbarNotifier, $level = Logger::ERROR, $bubble = true) + public function __construct(RollbarLogger $rollbarLogger, $level = Logger::ERROR, $bubble = true) { - $this->rollbarNotifier = $rollbarNotifier; + $this->rollbarLogger = $rollbarLogger; parent::__construct($level, $bubble); } @@ -84,11 +82,6 @@ class RollbarHandler extends AbstractProcessingHandler } $context = $record['context']; - $payload = []; - if (isset($context['payload'])) { - $payload = $context['payload']; - unset($context['payload']); - } $context = array_merge($context, $record['extra'], [ 'level' => $this->levelMap[$record['level']], 'monolog_level' => $record['level_name'], @@ -97,19 +90,14 @@ class RollbarHandler extends AbstractProcessingHandler ]); if (isset($context['exception']) && $context['exception'] instanceof Throwable) { - $payload['level'] = $context['level']; $exception = $context['exception']; unset($context['exception']); - - $this->rollbarNotifier->report_exception($exception, $context, $payload); + $toLog = $exception; } else { - $this->rollbarNotifier->report_message( - $record['message'], - $context['level'], - $context, - $payload - ); + $toLog = $record['message']; } + + $this->rollbarLogger->log($context['level'], $toLog, $context); $this->hasRecords = true; } @@ -117,7 +105,7 @@ class RollbarHandler extends AbstractProcessingHandler public function flush() { if ($this->hasRecords) { - $this->rollbarNotifier->flush(); + $this->rollbarLogger->flush(); $this->hasRecords = false; } } diff --git a/tests/Monolog/Handler/RollbarHandlerTest.php b/tests/Monolog/Handler/RollbarHandlerTest.php index 89fc9cb9..96d8a30a 100644 --- a/tests/Monolog/Handler/RollbarHandlerTest.php +++ b/tests/Monolog/Handler/RollbarHandlerTest.php @@ -15,6 +15,7 @@ use Exception; use Monolog\Test\TestCase; use Monolog\Logger; use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Rollbar\RollbarLogger; /** * @author Erik Johansson @@ -27,7 +28,7 @@ class RollbarHandlerTest extends TestCase /** * @var MockObject */ - private $rollbarNotifier; + private $rollbarLogger; /** * @var array @@ -38,7 +39,7 @@ class RollbarHandlerTest extends TestCase { parent::setUp(); - $this->setupRollbarNotifierMock(); + $this->setupRollbarLoggerMock(); } /** @@ -54,15 +55,21 @@ class RollbarHandlerTest extends TestCase $this->assertEquals('debug', $this->reportedExceptionArguments['payload']['level']); } - private function setupRollbarNotifierMock() + private function setupRollbarLoggerMock() { - $this->rollbarNotifier = $this->getMockBuilder('RollbarNotifier') - ->setMethods(array('report_message', 'report_exception', 'flush')) + $config = array( + 'access_token' => 'ad865e76e7fb496fab096ac07b1dbabb', + 'environment' => 'test' + ); + + $this->rollbarLogger = $this->getMockBuilder(RollbarLogger::class) + ->setConstructorArgs(array($config)) + ->setMethods(array('log')) ->getMock(); - $this->rollbarNotifier + $this->rollbarLogger ->expects($this->any()) - ->method('report_exception') + ->method('log') ->willReturnCallback(function ($exception, $context, $payload) { $this->reportedExceptionArguments = compact('exception', 'context', 'payload'); }); @@ -70,7 +77,7 @@ class RollbarHandlerTest extends TestCase private function createHandler(): RollbarHandler { - return new RollbarHandler($this->rollbarNotifier, Logger::DEBUG); + return new RollbarHandler($this->rollbarLogger, Logger::DEBUG); } private function createExceptionRecord($level = Logger::DEBUG, $message = 'test', $exception = null): array From 0d993d84d1439466a53c517569174738984cf008 Mon Sep 17 00:00:00 2001 From: Andrew Berry Date: Sun, 17 Jun 2018 11:27:33 -0400 Subject: [PATCH 62/80] Normalization of arrays containing self references (#1050) Backport normalization fix from master to 1.x --- src/Monolog/Formatter/JsonFormatter.php | 8 ++++++-- src/Monolog/Formatter/NormalizerFormatter.php | 8 ++++++-- src/Monolog/Formatter/WildfireFormatter.php | 4 ++-- tests/Monolog/Formatter/NormalizerFormatterTest.php | 9 +++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index 247122a2..b8309b10 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -138,8 +138,12 @@ class JsonFormatter extends NormalizerFormatter * * @return mixed */ - protected function normalize($data) + protected function normalize($data, $depth = 0) { + if ($depth > 9) { + return 'Over 9 levels deep, aborting normalization'; + } + if (is_array($data) || $data instanceof \Traversable) { $normalized = array(); @@ -150,7 +154,7 @@ class JsonFormatter extends NormalizerFormatter break; } - $normalized[$key] = $this->normalize($value); + $normalized[$key] = $this->normalize($value, $depth+1); } return $normalized; diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index e6142b63..91227241 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -55,8 +55,12 @@ class NormalizerFormatter implements FormatterInterface return $records; } - protected function normalize($data) + protected function normalize($data, $depth = 0) { + if ($depth > 9) { + return 'Over 9 levels deep, aborting normalization'; + } + if (null === $data || is_scalar($data)) { if (is_float($data)) { if (is_infinite($data)) { @@ -80,7 +84,7 @@ class NormalizerFormatter implements FormatterInterface break; } - $normalized[$key] = $this->normalize($value); + $normalized[$key] = $this->normalize($value, $depth+1); } return $normalized; diff --git a/src/Monolog/Formatter/WildfireFormatter.php b/src/Monolog/Formatter/WildfireFormatter.php index 654710a8..65dba99c 100644 --- a/src/Monolog/Formatter/WildfireFormatter.php +++ b/src/Monolog/Formatter/WildfireFormatter.php @@ -102,12 +102,12 @@ class WildfireFormatter extends NormalizerFormatter throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter'); } - protected function normalize($data) + protected function normalize($data, $depth = 0) { if (is_object($data) && !$data instanceof \DateTime) { return $data; } - return parent::normalize($data); + return parent::normalize($data, $depth); } } diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index 44c1e660..b4f82897 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -193,6 +193,15 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $this->assertEquals(@json_encode(array($foo, $bar)), $res); } + public function testCanNormalizeReferences() + { + $formatter = new NormalizerFormatter(); + $x = array('foo' => 'bar'); + $y = array('x' => &$x); + $x['y'] = &$y; + $formatter->format($y); + } + public function testIgnoresInvalidTypes() { // set up the recursion From 010cbd650dc80e113d54bf849fa9fcfcb8b68c32 Mon Sep 17 00:00:00 2001 From: Westin Shafer Date: Sun, 17 Jun 2018 09:39:20 -0600 Subject: [PATCH 63/80] Update docs for GelfHandler (#1020) Updated docs to reflect the dependency of package graylog2/gelf-php in order to work --- doc/02-handlers-formatters-processors.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/02-handlers-formatters-processors.md b/doc/02-handlers-formatters-processors.md index 9484c91e..4df87c22 100644 --- a/doc/02-handlers-formatters-processors.md +++ b/doc/02-handlers-formatters-processors.md @@ -48,6 +48,7 @@ - [_AmqpHandler_](../src/Monolog/Handler/AmqpHandler.php): Logs records to an [amqp](http://www.amqp.org/) compatible server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+). - [_GelfHandler_](../src/Monolog/Handler/GelfHandler.php): Logs records to a [Graylog2](http://www.graylog2.org) server. + Requires package [graylog2/gelf-php](https://github.com/bzikarsky/gelf-php). - [_CubeHandler_](../src/Monolog/Handler/CubeHandler.php): Logs records to a [Cube](http://square.github.com/cube/) server. - [_RavenHandler_](../src/Monolog/Handler/RavenHandler.php): Logs records to a [Sentry](http://getsentry.com/) server using [raven](https://packagist.org/packages/raven/raven). From a07a4c37416afc70385000aa64654e8befe474e5 Mon Sep 17 00:00:00 2001 From: Martin Meredith Date: Sun, 17 Jun 2018 16:43:18 +0100 Subject: [PATCH 64/80] Update Docblock to specify allowing string Log Levels (#1068) --- src/Monolog/Handler/AbstractHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Handler/AbstractHandler.php b/src/Monolog/Handler/AbstractHandler.php index 6eaca56b..d4771084 100644 --- a/src/Monolog/Handler/AbstractHandler.php +++ b/src/Monolog/Handler/AbstractHandler.php @@ -24,8 +24,8 @@ abstract class AbstractHandler extends Handler protected $bubble = true; /** - * @param int $level The minimum logging level at which this handler will be triggered - * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|string $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($level = Logger::DEBUG, $bubble = true) { From 00aca28c8bc4e416ddcf76c26059c1676ed33cd2 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 17 Jun 2018 18:03:59 +0200 Subject: [PATCH 65/80] Fix SlackRecord normalization of fields, closes #1078 --- src/Monolog/Handler/Slack/SlackRecord.php | 4 ++-- tests/Monolog/Handler/Slack/SlackRecordTest.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Monolog/Handler/Slack/SlackRecord.php b/src/Monolog/Handler/Slack/SlackRecord.php index 71b42960..e55e0e2e 100755 --- a/src/Monolog/Handler/Slack/SlackRecord.php +++ b/src/Monolog/Handler/Slack/SlackRecord.php @@ -146,7 +146,7 @@ class SlackRecord if ($this->useShortAttachment) { $attachment['fields'][] = $this->generateAttachmentField( - ucfirst($key), + $key, $record[$key] ); } else { @@ -241,7 +241,7 @@ class SlackRecord : $value; return array( - 'title' => $title, + 'title' => ucfirst($title), 'value' => $value, 'short' => false ); diff --git a/tests/Monolog/Handler/Slack/SlackRecordTest.php b/tests/Monolog/Handler/Slack/SlackRecordTest.php index ae42393c..b9de7367 100644 --- a/tests/Monolog/Handler/Slack/SlackRecordTest.php +++ b/tests/Monolog/Handler/Slack/SlackRecordTest.php @@ -320,12 +320,12 @@ class SlackRecordTest extends TestCase 'short' => false, ), array( - 'title' => 'tags', + 'title' => 'Tags', 'value' => sprintf('```%s```', json_encode($extra['tags'])), 'short' => false ), array( - 'title' => 'test', + 'title' => 'Test', 'value' => $context['test'], 'short' => false ) @@ -376,12 +376,12 @@ class SlackRecordTest extends TestCase $expected = array( array( - 'title' => 'info', + 'title' => 'Info', 'value' => sprintf('```%s```', json_encode(array('author' => 'Jordi'), $this->jsonPrettyPrintFlag)), 'short' => false ), array( - 'title' => 'tags', + 'title' => 'Tags', 'value' => sprintf('```%s```', json_encode(array('web'))), 'short' => false ), From e8db808dd3e079c194f6f4dbdb06cf5758b0d0f6 Mon Sep 17 00:00:00 2001 From: Klemen Bratec Date: Mon, 18 Jun 2018 11:31:46 +0200 Subject: [PATCH 66/80] Allow setting stream chunk size in SocketHandler (#1129) --- src/Monolog/Handler/SocketHandler.php | 39 +++++++++++++++++++++ tests/Monolog/Handler/SocketHandlerTest.php | 26 ++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/Monolog/Handler/SocketHandler.php b/src/Monolog/Handler/SocketHandler.php index 79d49ece..db50d97f 100644 --- a/src/Monolog/Handler/SocketHandler.php +++ b/src/Monolog/Handler/SocketHandler.php @@ -27,6 +27,7 @@ class SocketHandler extends AbstractProcessingHandler private $timeout = 0; private $writingTimeout = 10; private $lastSentBytes = null; + private $chunkSize = null; private $persistent = false; private $errno; private $errstr; @@ -127,6 +128,16 @@ class SocketHandler extends AbstractProcessingHandler $this->writingTimeout = (float) $seconds; } + /** + * Set chunk size. Only has effect during connection in the writing cycle. + * + * @param float $bytes + */ + public function setChunkSize($bytes) + { + $this->chunkSize = $bytes; + } + /** * Get current connection string * @@ -177,6 +188,16 @@ class SocketHandler extends AbstractProcessingHandler return $this->writingTimeout; } + /** + * Get current chunk size + * + * @return float + */ + public function getChunkSize() + { + return $this->chunkSize; + } + /** * Check to see if the socket is currently available. * @@ -219,6 +240,16 @@ class SocketHandler extends AbstractProcessingHandler return stream_set_timeout($this->resource, $seconds, $microseconds); } + /** + * Wrapper to allow mocking + * + * @see http://php.net/manual/en/function.stream-set-chunk-size.php + */ + protected function streamSetChunkSize() + { + return stream_set_chunk_size($this->resource, $this->chunkSize); + } + /** * Wrapper to allow mocking */ @@ -268,6 +299,7 @@ class SocketHandler extends AbstractProcessingHandler { $this->createSocketResource(); $this->setSocketTimeout(); + $this->setStreamChunkSize(); } private function createSocketResource() @@ -290,6 +322,13 @@ class SocketHandler extends AbstractProcessingHandler } } + private function setStreamChunkSize() + { + if ($this->chunkSize && !$this->streamSetChunkSize()) { + throw new \UnexpectedValueException("Failed setting chunk size with stream_set_chunk_size()"); + } + } + private function writeToSocket($data) { $length = strlen($data); diff --git a/tests/Monolog/Handler/SocketHandlerTest.php b/tests/Monolog/Handler/SocketHandlerTest.php index 1f9c1f28..1da987c9 100644 --- a/tests/Monolog/Handler/SocketHandlerTest.php +++ b/tests/Monolog/Handler/SocketHandlerTest.php @@ -77,6 +77,13 @@ class SocketHandlerTest extends TestCase $this->assertEquals(10.25, $this->handler->getWritingTimeout()); } + public function testSetChunkSize() + { + $this->createHandler('localhost:1234'); + $this->handler->setChunkSize(1025); + $this->assertEquals(1025, $this->handler->getChunkSize()); + } + public function testSetConnectionString() { $this->createHandler('tcp://localhost:9090'); @@ -120,6 +127,19 @@ class SocketHandlerTest extends TestCase $this->writeRecord('Hello world'); } + /** + * @expectedException UnexpectedValueException + */ + public function testExceptionIsThrownIfCannotSetChunkSize() + { + $this->setMockHandler(array('streamSetChunkSize')); + $this->handler->setChunkSize(8192); + $this->handler->expects($this->once()) + ->method('streamSetChunkSize') + ->will($this->returnValue(false)); + $this->writeRecord('Hello world'); + } + /** * @expectedException RuntimeException */ @@ -304,6 +324,12 @@ class SocketHandlerTest extends TestCase ->will($this->returnValue(true)); } + if (!in_array('streamSetChunkSize', $methods)) { + $this->handler->expects($this->any()) + ->method('streamSetChunkSize') + ->will($this->returnValue(8192)); + } + $this->handler->setFormatter($this->getIdentityFormatter()); } } From 85d49f856817acadbbcdcafb06f290d256e573bd Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Thu, 13 Apr 2017 00:06:26 +0200 Subject: [PATCH 67/80] Better PSR-3 message formatting --- src/Monolog/Processor/PsrLogMessageProcessor.php | 4 +++- tests/Monolog/Processor/PsrLogMessageProcessorTest.php | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Processor/PsrLogMessageProcessor.php b/src/Monolog/Processor/PsrLogMessageProcessor.php index a10cd76c..a9d2e70d 100644 --- a/src/Monolog/Processor/PsrLogMessageProcessor.php +++ b/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -20,7 +20,7 @@ namespace Monolog\Processor; */ class PsrLogMessageProcessor { - const SIMPLE_DATE = "Y-m-d\TH:i:sP"; + const SIMPLE_DATE = "Y-m-d\TH:i:s.uP"; private $dateFormat; @@ -60,6 +60,8 @@ class PsrLogMessageProcessor $replacements[$placeholder] = $val->format($this->dateFormat); } elseif (is_object($val)) { $replacements[$placeholder] = '[object '.get_class($val).']'; + } elseif (is_array($val)) { + $replacements[$placeholder] = 'array'.@json_encode($val); } else { $replacements[$placeholder] = '['.gettype($val).']'; } diff --git a/tests/Monolog/Processor/PsrLogMessageProcessorTest.php b/tests/Monolog/Processor/PsrLogMessageProcessorTest.php index 60fafc64..3b5ec6e9 100644 --- a/tests/Monolog/Processor/PsrLogMessageProcessorTest.php +++ b/tests/Monolog/Processor/PsrLogMessageProcessorTest.php @@ -68,7 +68,11 @@ class PsrLogMessageProcessorTest extends \PHPUnit\Framework\TestCase [false, ''], [$date, $date->format(PsrLogMessageProcessor::SIMPLE_DATE)], [new \stdClass, '[object stdClass]'], - [[], '[array]'], + [[], 'array[]'], + [[], 'array[]'], + [[1, 2, 3], 'array[1,2,3]'], + [['foo' => 'bar'], 'array{"foo":"bar"}'], + [stream_context_create(), '[resource]'], ]; } } From b381a973bcca4a2acb01dbe57e37bf5474fb7768 Mon Sep 17 00:00:00 2001 From: Petter Blomberg Date: Thu, 31 May 2018 15:08:33 +0200 Subject: [PATCH 68/80] Make TestHandler::hasRecord assert context, not only message --- src/Monolog/Handler/TestHandler.php | 18 ++++++--- tests/Monolog/Handler/TestHandlerTest.php | 46 +++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/Monolog/Handler/TestHandler.php b/src/Monolog/Handler/TestHandler.php index e39cfc66..f639594c 100644 --- a/src/Monolog/Handler/TestHandler.php +++ b/src/Monolog/Handler/TestHandler.php @@ -86,12 +86,20 @@ class TestHandler extends AbstractProcessingHandler public function hasRecord($record, $level) { - if (is_array($record)) { - $record = $record['message']; - } - return $this->hasRecordThatPasses(function ($rec) use ($record) { - return $rec['message'] === $record; + if (is_array($record)) { + if ($rec['message'] !== $record['message']) { + return false; + } + if ($rec['context'] !== $record['context']) { + return false; + } + } else { + if ($rec['message'] !== $record) { + return false; + } + } + return true; }, $level); } diff --git a/tests/Monolog/Handler/TestHandlerTest.php b/tests/Monolog/Handler/TestHandlerTest.php index bfb8d3df..c86e935a 100644 --- a/tests/Monolog/Handler/TestHandlerTest.php +++ b/tests/Monolog/Handler/TestHandlerTest.php @@ -54,6 +54,52 @@ class TestHandlerTest extends TestCase $this->assertEquals(array($record), $records); } + public function testHandlerAssertEmptyContext() { + $handler = new TestHandler; + $record = $this->getRecord(Logger::WARNING, 'test', []); + $this->assertFalse($handler->hasWarning([ + 'message' => 'test', + 'context' => [], + ])); + + $handler->handle($record); + + $this->assertTrue($handler->hasWarning([ + 'message' => 'test', + 'context' => [], + ])); + $this->assertFalse($handler->hasWarning([ + 'message' => 'test', + 'context' => [ + 'foo' => 'bar' + ], + ])); + } + + public function testHandlerAssertNonEmptyContext() { + $handler = new TestHandler; + $record = $this->getRecord(Logger::WARNING, 'test', ['foo' => 'bar']); + $this->assertFalse($handler->hasWarning([ + 'message' => 'test', + 'context' => [ + 'foo' => 'bar' + ], + ])); + + $handler->handle($record); + + $this->assertTrue($handler->hasWarning([ + 'message' => 'test', + 'context' => [ + 'foo' => 'bar' + ], + ])); + $this->assertFalse($handler->hasWarning([ + 'message' => 'test', + 'context' => [], + ])); + } + public function methodProvider() { return array( From f753c68a73e4b716f136a305434e076f1971221f Mon Sep 17 00:00:00 2001 From: Petter Blomberg Date: Thu, 31 May 2018 15:34:07 +0200 Subject: [PATCH 69/80] Make context optional in hasRecord to not break backwards compatibility --- src/Monolog/Handler/TestHandler.php | 20 +++++----- tests/Monolog/Handler/TestHandlerTest.php | 46 +++++++++++------------ 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/Monolog/Handler/TestHandler.php b/src/Monolog/Handler/TestHandler.php index f639594c..9fe0e03d 100644 --- a/src/Monolog/Handler/TestHandler.php +++ b/src/Monolog/Handler/TestHandler.php @@ -86,18 +86,16 @@ class TestHandler extends AbstractProcessingHandler public function hasRecord($record, $level) { + if (is_string($record)) { + $record = array('message' => $record); + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { - if (is_array($record)) { - if ($rec['message'] !== $record['message']) { - return false; - } - if ($rec['context'] !== $record['context']) { - return false; - } - } else { - if ($rec['message'] !== $record) { - return false; - } + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; } return true; }, $level); diff --git a/tests/Monolog/Handler/TestHandlerTest.php b/tests/Monolog/Handler/TestHandlerTest.php index c86e935a..a7c4fc98 100644 --- a/tests/Monolog/Handler/TestHandlerTest.php +++ b/tests/Monolog/Handler/TestHandlerTest.php @@ -56,48 +56,48 @@ class TestHandlerTest extends TestCase public function testHandlerAssertEmptyContext() { $handler = new TestHandler; - $record = $this->getRecord(Logger::WARNING, 'test', []); - $this->assertFalse($handler->hasWarning([ + $record = $this->getRecord(Logger::WARNING, 'test', array()); + $this->assertFalse($handler->hasWarning(array( 'message' => 'test', - 'context' => [], - ])); + 'context' => array(), + ))); $handler->handle($record); - $this->assertTrue($handler->hasWarning([ + $this->assertTrue($handler->hasWarning(array( 'message' => 'test', - 'context' => [], - ])); - $this->assertFalse($handler->hasWarning([ + 'context' => array(), + ))); + $this->assertFalse($handler->hasWarning(array( 'message' => 'test', - 'context' => [ + 'context' => array( 'foo' => 'bar' - ], - ])); + ), + ))); } public function testHandlerAssertNonEmptyContext() { $handler = new TestHandler; - $record = $this->getRecord(Logger::WARNING, 'test', ['foo' => 'bar']); - $this->assertFalse($handler->hasWarning([ + $record = $this->getRecord(Logger::WARNING, 'test', array('foo' => 'bar')); + $this->assertFalse($handler->hasWarning(array( 'message' => 'test', - 'context' => [ + 'context' => array( 'foo' => 'bar' - ], - ])); + ), + ))); $handler->handle($record); - $this->assertTrue($handler->hasWarning([ + $this->assertTrue($handler->hasWarning(array( 'message' => 'test', - 'context' => [ + 'context' => array( 'foo' => 'bar' - ], - ])); - $this->assertFalse($handler->hasWarning([ + ), + ))); + $this->assertFalse($handler->hasWarning(array( 'message' => 'test', - 'context' => [], - ])); + 'context' => array(), + ))); } public function methodProvider() From 796f56b6d31fe6e0dd9b4edbfd5bbbea155aaa14 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 15:55:01 +0200 Subject: [PATCH 70/80] Fix test suite --- tests/Monolog/Handler/SocketHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Monolog/Handler/SocketHandlerTest.php b/tests/Monolog/Handler/SocketHandlerTest.php index bc51a338..5f76048c 100644 --- a/tests/Monolog/Handler/SocketHandlerTest.php +++ b/tests/Monolog/Handler/SocketHandlerTest.php @@ -297,7 +297,7 @@ class SocketHandlerTest extends TestCase { $this->res = fopen('php://memory', 'a'); - $defaultMethods = ['fsockopen', 'pfsockopen', 'streamSetTimeout']; + $defaultMethods = ['fsockopen', 'pfsockopen', 'streamSetTimeout', 'streamSetChunkSize']; $newMethods = array_diff($methods, $defaultMethods); $finalMethods = array_merge($defaultMethods, $newMethods); From 57a8a172e50050b4675df7fc10757bd093ccb028 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 16:35:54 +0200 Subject: [PATCH 71/80] Update changelog --- CHANGELOG.md | 20 ++++++++++++++++++++ src/Monolog/Handler/TestHandler.php | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd1142d1..b5079a74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +### 1.24.0 (2018-06-xx) + + * Added ability to customize error handling at the Logger level using Logger::setExceptionHandler + * Added InsightOpsHandler to migrate users of the LogEntriesHandler + * Added protection to NormalizerHandler against circular and very deep structures, it now stops normalizing at a depth of 9 + * Added capture of stack traces to ErrorHandler when logging PHP errors + * Added forwarding of context info to FluentdFormatter + * Added SocketHandler::setChunkSize to override the default chunk size in case you must send large log lines to rsyslog for example + * Added ability to extend/override BrowserConsoleHandler + * Added SlackWebhookHandler::getWebhookUrl and SlackHandler::getToken to enable class extensibility + * Added SwiftMailerHandler::getSubjectFormatter to enable class extensibility + * Dropped official support for HHVM in test builds + * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases + * Fixed normalization of objects in Slack handlers + * Fixed support for PHP7's Throwable in NewRelicHandler + * Fixed race bug when StreamHandler sometimes incorrectly reported it failed to create a directory + * Fixed table row styling issues in HtmlFormatter + * Fixed RavenHandler dropping the message when logging exception + * Fixed WhatFailureGroupHandler skipping processors when using handleBatch + ### 1.23.0 (2017-06-19) * Improved SyslogUdpHandler's support for RFC5424 and added optional `$ident` argument diff --git a/src/Monolog/Handler/TestHandler.php b/src/Monolog/Handler/TestHandler.php index 9fe0e03d..b6b1343b 100644 --- a/src/Monolog/Handler/TestHandler.php +++ b/src/Monolog/Handler/TestHandler.php @@ -84,6 +84,10 @@ class TestHandler extends AbstractProcessingHandler return isset($this->recordsByLevel[$level]); } + /** + * @param string|array $record Either a message string or an array containing message and optionally context keys that will be checked against all records + * @param int $level Logger::LEVEL constant value + */ public function hasRecord($record, $level) { if (is_string($record)) { From bbf9de5c8d29763d64230645b653cc63ef393882 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 16:48:08 +0200 Subject: [PATCH 72/80] Follow useMicroseconds flag when possible --- src/Monolog/Processor/PsrLogMessageProcessor.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Processor/PsrLogMessageProcessor.php b/src/Monolog/Processor/PsrLogMessageProcessor.php index a9d2e70d..f845f883 100644 --- a/src/Monolog/Processor/PsrLogMessageProcessor.php +++ b/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -33,7 +33,7 @@ class PsrLogMessageProcessor */ public function __construct(string $dateFormat = null, bool $removeUsedContextFields = false) { - $this->dateFormat = null === $dateFormat ? static::SIMPLE_DATE : $dateFormat; + $this->dateFormat = $dateFormat; $this->removeUsedContextFields = $removeUsedContextFields; } @@ -57,7 +57,13 @@ class PsrLogMessageProcessor if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) { $replacements[$placeholder] = $val; } elseif ($val instanceof \DateTimeInterface) { - $replacements[$placeholder] = $val->format($this->dateFormat); + if (!$this->dateFormat && $val instanceof \Monolog\DateTimeImmutable) { + // handle monolog dates using __toString if no specific dateFormat was asked for + // so that it follows the useMicroseconds flag + $replacements[$placeholder] = (string) $val; + } else { + $replacements[$placeholder] = $val->format($this->dateFormat ?: static::SIMPLE_DATE); + } } elseif (is_object($val)) { $replacements[$placeholder] = '[object '.get_class($val).']'; } elseif (is_array($val)) { From 8b21ec0780a8f8793e9d6bc6a04fab78c728e642 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 16:49:28 +0200 Subject: [PATCH 73/80] Drop PHP7.0 hacks --- src/Monolog/DateTimeImmutable.php | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/Monolog/DateTimeImmutable.php b/src/Monolog/DateTimeImmutable.php index 4e9f598e..6e7a5fc6 100644 --- a/src/Monolog/DateTimeImmutable.php +++ b/src/Monolog/DateTimeImmutable.php @@ -23,29 +23,9 @@ class DateTimeImmutable extends \DateTimeImmutable implements \JsonSerializable public function __construct($useMicroseconds, \DateTimeZone $timezone = null) { - static $needsMicrosecondsHack = PHP_VERSION_ID < 70100; - $this->useMicroseconds = $useMicroseconds; - $date = 'now'; - if ($needsMicrosecondsHack && $useMicroseconds) { - $timestamp = microtime(true); - - // apply offset of the timezone as microtime() is always UTC - if ($timezone && $timezone->getName() !== 'UTC') { - $timestamp += (new \DateTime('now', $timezone))->getOffset(); - } - - // Circumvent DateTimeImmutable::createFromFormat() which always returns \DateTimeImmutable instead of `static` - // @link https://bugs.php.net/bug.php?id=60302 - // - // So we create a DateTime but then format it so we - // can re-create one using the right class - $dt = self::createFromFormat('U.u', sprintf('%.6F', $timestamp)); - $date = $dt->format('Y-m-d H:i:s.u'); - } - - parent::__construct($date, $timezone); + parent::__construct('now', $timezone); } public function jsonSerialize(): string From 3e92b08956da82867774ca8a8edef2472ab743f9 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 17:21:54 +0200 Subject: [PATCH 74/80] Avoid information leaks through call_user_func arguments, fixes #1138 --- src/Monolog/Formatter/NormalizerFormatter.php | 13 +++++++- .../Formatter/NormalizerFormatterTest.php | 31 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index 91227241..0d96ed09 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -151,9 +151,20 @@ class NormalizerFormatter implements FormatterInterface if (isset($frame['file'])) { $data['trace'][] = $frame['file'].':'.$frame['line']; } elseif (isset($frame['function']) && $frame['function'] === '{closure}') { - // We should again normalize the frames, because it might contain invalid items + // Simplify closures handling $data['trace'][] = $frame['function']; } else { + if (isset($frame['args'])) { + // Make sure that objects present as arguments are not serialized nicely but rather only + // as a class name to avoid any unexpected leak of sensitive information + $frame['args'] = array_map(function ($arg) { + if (is_object($arg) && !($arg instanceof \DateTime || $arg instanceof \DateTimeInterface)) { + return sprintf("[object] (%s)", get_class($arg)); + } + + return $arg; + }, $frame['args']); + } // We should again normalize the frames, because it might contain invalid items $data['trace'][] = $this->toJson($this->normalize($frame), true); } diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index b4f82897..bafd1c74 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -407,6 +407,29 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $result['context']['exception']['trace'][0] ); } + + 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 H:i:s').'"]}', + $result['context']['exception']['trace'][0] + ); + } + + private function throwHelper($arg) + { + throw new \RuntimeException('Thrown'); + } } class TestFooNorm @@ -448,3 +471,11 @@ class TestToStringError throw new \RuntimeException('Could not convert to string'); } } + +class TestInfoLeak +{ + public function __toString() + { + return 'Sensitive information'; + } +} From 7c549e383c302398d6377c4f226d6509f3c4fb28 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 17:31:08 +0200 Subject: [PATCH 75/80] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5079a74..8f70fdb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Added SlackWebhookHandler::getWebhookUrl and SlackHandler::getToken to enable class extensibility * Added SwiftMailerHandler::getSubjectFormatter to enable class extensibility * Dropped official support for HHVM in test builds + * Fixed normalization of exception traces when call_user_func is used to avoid serializing objects and the data they contain * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases * Fixed normalization of objects in Slack handlers * Fixed support for PHP7's Throwable in NewRelicHandler From c04f66ed5464ab03202762526a1941e52425016b Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Mon, 18 Jun 2018 17:41:09 +0200 Subject: [PATCH 76/80] Include stacktraces for "previous" excpetions in LineFormatter --- src/Monolog/Formatter/LineFormatter.php | 20 ++++++++++++------- tests/Monolog/Formatter/LineFormatterTest.php | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Monolog/Formatter/LineFormatter.php b/src/Monolog/Formatter/LineFormatter.php index 9d4ef1d7..6cbdb520 100644 --- a/src/Monolog/Formatter/LineFormatter.php +++ b/src/Monolog/Formatter/LineFormatter.php @@ -126,18 +126,14 @@ class LineFormatter extends NormalizerFormatter protected function normalizeException(\Throwable $e, int $depth = 0): string { - $previousText = ''; + $str = $this->formatException($e); + if ($previous = $e->getPrevious()) { do { - $previousText .= ', '.get_class($previous).'(code: '.$previous->getCode().'): '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine(); + $str .= "\n[previous exception] " . $this->formatException($previous); } while ($previous = $previous->getPrevious()); } - $str = '[object] ('.get_class($e).'(code: '.$e->getCode().'): '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')'; - if ($this->includeStacktraces) { - $str .= "\n[stacktrace]\n".$e->getTraceAsString()."\n"; - } - return $str; } @@ -166,4 +162,14 @@ class LineFormatter extends NormalizerFormatter return str_replace(["\r\n", "\r", "\n"], ' ', $str); } + + private function formatException(\Throwable $e): string + { + $str = '[object] (' . get_class($e) . '(code: ' . $e->getCode() . '): ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine() . ')'; + if ($this->includeStacktraces) { + $str .= "\n[stacktrace]\n" . $e->getTraceAsString() . "\n"; + } + + return $str; + } } diff --git a/tests/Monolog/Formatter/LineFormatterTest.php b/tests/Monolog/Formatter/LineFormatterTest.php index a8b55e44..e19cde1e 100644 --- a/tests/Monolog/Formatter/LineFormatterTest.php +++ b/tests/Monolog/Formatter/LineFormatterTest.php @@ -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() From ee107778211ff0d027a6c15ecb77c4655a5c1b4b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 17:37:57 +0200 Subject: [PATCH 77/80] Fix hipchat dropping messages, fixes #1116 --- CHANGELOG.md | 1 + src/Monolog/Handler/HipChatHandler.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f70fdb7..a69362b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Dropped official support for HHVM in test builds * Fixed normalization of exception traces when call_user_func is used to avoid serializing objects and the data they contain * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases + * Fixed HipChatHandler bug where slack dropped messages randomly * Fixed normalization of objects in Slack handlers * Fixed support for PHP7's Throwable in NewRelicHandler * Fixed race bug when StreamHandler sometimes incorrectly reported it failed to create a directory diff --git a/src/Monolog/Handler/HipChatHandler.php b/src/Monolog/Handler/HipChatHandler.php index 73049f36..73233c95 100644 --- a/src/Monolog/Handler/HipChatHandler.php +++ b/src/Monolog/Handler/HipChatHandler.php @@ -219,6 +219,21 @@ class HipChatHandler extends SocketHandler protected function write(array $record) { parent::write($record); + $this->finalizeWrite(); + } + + /** + * Finalizes the request by reading some bytes and then closing the socket + * + * If we do not read some but close the socket too early, hipchat sometimes + * drops the request entirely. + */ + protected function finalizeWrite() + { + $res = $this->getResource(); + if (is_resource($res)) { + @fread($res, 2048); + } $this->closeSocket(); } From fa9c4ebf3eaa623b14e073ce539107ca5495b542 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 18:27:06 +0200 Subject: [PATCH 78/80] Update requirements in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ba9f6da3..82bd4e7e 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ can also add your own there if you publish one. ### Requirements -- Monolog works with PHP 7.0 or above, use Monolog `^1.0` for PHP 5.3+ support. +- Monolog 2.x works with PHP 7.1 or above, use Monolog `^1.0` for PHP 5.3+ support. ### Submitting bugs and feature requests From 41b8f5ebf4693fe1f3b652c883efc4a96cd99aa8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 18 Jun 2018 18:53:38 +0200 Subject: [PATCH 79/80] CS fixes --- .php_cs | 11 +++++------ src/Monolog/ErrorHandler.php | 2 +- src/Monolog/Handler/AbstractSyslogHandler.php | 4 ++-- src/Monolog/Handler/BrowserConsoleHandler.php | 3 ++- src/Monolog/Handler/ChromePHPHandler.php | 1 - src/Monolog/Handler/CubeHandler.php | 3 ++- src/Monolog/Handler/ElasticSearchHandler.php | 1 + src/Monolog/Handler/ErrorLogHandler.php | 6 ++++-- .../FingersCrossed/ActivationStrategyInterface.php | 2 +- src/Monolog/Handler/FirePHPHandler.php | 1 - src/Monolog/Handler/HandlerInterface.php | 6 +++--- src/Monolog/Handler/InsightOpsHandler.php | 6 +++--- src/Monolog/Handler/RollbarHandler.php | 10 +++++----- src/Monolog/Handler/SlackWebhookHandler.php | 2 +- src/Monolog/Handler/SqsHandler.php | 1 - src/Monolog/Handler/StreamHandler.php | 1 + src/Monolog/Handler/TestHandler.php | 1 + src/Monolog/Handler/WebRequestRecognizerTrait.php | 10 +++++++++- src/Monolog/Logger.php | 8 ++++---- src/Monolog/Processor/HostnameProcessor.php | 2 -- src/Monolog/Processor/IntrospectionProcessor.php | 2 ++ src/Monolog/Processor/PsrLogMessageProcessor.php | 4 ++-- tests/Monolog/Formatter/GelfMessageFormatterTest.php | 2 +- tests/Monolog/Handler/ElasticSearchHandlerTest.php | 1 + tests/Monolog/Handler/FilterHandlerTest.php | 5 ++++- tests/Monolog/Handler/InsightOpsHandlerTest.php | 11 +++++------ tests/Monolog/Handler/RollbarHandlerTest.php | 4 ++-- tests/Monolog/Handler/RotatingFileHandlerTest.php | 5 ++--- tests/Monolog/Handler/TestHandlerTest.php | 12 +++++++----- 29 files changed, 71 insertions(+), 56 deletions(-) diff --git a/.php_cs b/.php_cs index 34eb329f..6fc3ca2e 100644 --- a/.php_cs +++ b/.php_cs @@ -24,14 +24,13 @@ return PhpCsFixer\Config::create() '@PSR2' => true, // some rules disabled as long as 1.x branch is maintained 'binary_operator_spaces' => array( - 'align_double_arrow' => null, - 'align_equals' => null, + 'default' => null, ), - 'blank_line_before_return' => true, - 'cast_spaces' => true, - 'header_comment' => array('header' => $header), + 'blank_line_before_statement' => ['statements' => ['continue', 'declare', 'return', 'throw', 'try']], + 'cast_spaces' => ['space' => 'single'], + 'header_comment' => ['header' => $header], 'include' => true, - 'method_separation' => true, + 'class_attributes_separation' => ['elements' => ['method']], 'no_blank_lines_after_class_opening' => true, 'no_blank_lines_after_phpdoc' => true, 'no_empty_statement' => true, diff --git a/src/Monolog/ErrorHandler.php b/src/Monolog/ErrorHandler.php index 9a1e3004..d32c25d5 100644 --- a/src/Monolog/ErrorHandler.php +++ b/src/Monolog/ErrorHandler.php @@ -105,7 +105,7 @@ class ErrorHandler } /** - * @param string|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling + * @param string|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling * @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done */ public function registerFatalHandler($level = null, int $reservedMemorySize = 20): self diff --git a/src/Monolog/Handler/AbstractSyslogHandler.php b/src/Monolog/Handler/AbstractSyslogHandler.php index 95589e3e..0c692aa9 100644 --- a/src/Monolog/Handler/AbstractSyslogHandler.php +++ b/src/Monolog/Handler/AbstractSyslogHandler.php @@ -55,8 +55,8 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler /** * @param mixed $facility - * @param int $level The minimum logging level at which this handler will be triggered - * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) { diff --git a/src/Monolog/Handler/BrowserConsoleHandler.php b/src/Monolog/Handler/BrowserConsoleHandler.php index 681fe0cf..7774adef 100755 --- a/src/Monolog/Handler/BrowserConsoleHandler.php +++ b/src/Monolog/Handler/BrowserConsoleHandler.php @@ -141,7 +141,8 @@ class BrowserConsoleHandler extends AbstractProcessingHandler if (empty($context) && empty($extra)) { $script[] = static::call_array('log', static::handleStyles($record['formatted'])); } else { - $script = array_merge($script, + $script = array_merge( + $script, [static::call_array('groupCollapsed', static::handleStyles($record['formatted']))], $context, $extra, diff --git a/src/Monolog/Handler/ChromePHPHandler.php b/src/Monolog/Handler/ChromePHPHandler.php index 4cd76bf8..9c1ca523 100644 --- a/src/Monolog/Handler/ChromePHPHandler.php +++ b/src/Monolog/Handler/ChromePHPHandler.php @@ -24,7 +24,6 @@ use Monolog\Logger; */ class ChromePHPHandler extends AbstractProcessingHandler { - use WebRequestRecognizerTrait; /** diff --git a/src/Monolog/Handler/CubeHandler.php b/src/Monolog/Handler/CubeHandler.php index ab6e007e..82b16921 100644 --- a/src/Monolog/Handler/CubeHandler.php +++ b/src/Monolog/Handler/CubeHandler.php @@ -46,7 +46,8 @@ class CubeHandler extends AbstractProcessingHandler if (!in_array($urlInfo['scheme'], $this->acceptedSchemes)) { throw new \UnexpectedValueException( 'Invalid protocol (' . $urlInfo['scheme'] . ').' - . ' Valid options are ' . implode(', ', $this->acceptedSchemes)); + . ' Valid options are ' . implode(', ', $this->acceptedSchemes) + ); } $this->scheme = $urlInfo['scheme']; diff --git a/src/Monolog/Handler/ElasticSearchHandler.php b/src/Monolog/Handler/ElasticSearchHandler.php index 9b9f485f..b7dc5676 100644 --- a/src/Monolog/Handler/ElasticSearchHandler.php +++ b/src/Monolog/Handler/ElasticSearchHandler.php @@ -81,6 +81,7 @@ class ElasticSearchHandler extends AbstractProcessingHandler if ($formatter instanceof ElasticaFormatter) { return parent::setFormatter($formatter); } + throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter'); } diff --git a/src/Monolog/Handler/ErrorLogHandler.php b/src/Monolog/Handler/ErrorLogHandler.php index cc7dbb10..3108aed7 100644 --- a/src/Monolog/Handler/ErrorLogHandler.php +++ b/src/Monolog/Handler/ErrorLogHandler.php @@ -40,6 +40,7 @@ class ErrorLogHandler extends AbstractProcessingHandler if (false === in_array($messageType, self::getAvailableTypes(), true)) { $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true)); + throw new \InvalidArgumentException($message); } @@ -73,9 +74,10 @@ class ErrorLogHandler extends AbstractProcessingHandler { if (!$this->expandNewlines) { error_log((string) $record['formatted'], $this->messageType); + return; - } - + } + $lines = preg_split('{[\r\n]+}', (string) $record['formatted']); foreach ($lines as $line) { error_log($line, $this->messageType); diff --git a/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php index d4a8a51b..b73854ad 100644 --- a/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php +++ b/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php @@ -21,7 +21,7 @@ interface ActivationStrategyInterface /** * Returns whether the given record activates the handler. * - * @param array $record + * @param array $record * @return bool */ public function isHandlerActivated(array $record); diff --git a/src/Monolog/Handler/FirePHPHandler.php b/src/Monolog/Handler/FirePHPHandler.php index d92e2db5..8f5c0c69 100644 --- a/src/Monolog/Handler/FirePHPHandler.php +++ b/src/Monolog/Handler/FirePHPHandler.php @@ -21,7 +21,6 @@ use Monolog\Formatter\FormatterInterface; */ class FirePHPHandler extends AbstractProcessingHandler { - use WebRequestRecognizerTrait; /** diff --git a/src/Monolog/Handler/HandlerInterface.php b/src/Monolog/Handler/HandlerInterface.php index 90e8e16f..8ad7e38f 100644 --- a/src/Monolog/Handler/HandlerInterface.php +++ b/src/Monolog/Handler/HandlerInterface.php @@ -43,9 +43,9 @@ interface HandlerInterface * Unless the bubbling is interrupted (by returning true), the Logger class will keep on * calling further handlers in the stack with a given log record. * - * @param array $record The record to handle - * @return bool true means that this handler handled the record, and that bubbling is not permitted. - * false means the record was either not processed or that this handler allows bubbling. + * @param array $record The record to handle + * @return bool true means that this handler handled the record, and that bubbling is not permitted. + * false means the record was either not processed or that this handler allows bubbling. */ public function handle(array $record): bool; diff --git a/src/Monolog/Handler/InsightOpsHandler.php b/src/Monolog/Handler/InsightOpsHandler.php index 8da3a638..bd6dfe60 100644 --- a/src/Monolog/Handler/InsightOpsHandler.php +++ b/src/Monolog/Handler/InsightOpsHandler.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ - namespace Monolog\Handler; +namespace Monolog\Handler; - use Monolog\Logger; +use Monolog\Logger; -/** + /** * Inspired on LogEntriesHandler. * * @author Robert Kaufmann III diff --git a/src/Monolog/Handler/RollbarHandler.php b/src/Monolog/Handler/RollbarHandler.php index f330eeaa..2f35093c 100644 --- a/src/Monolog/Handler/RollbarHandler.php +++ b/src/Monolog/Handler/RollbarHandler.php @@ -19,7 +19,7 @@ use Monolog\Logger; * Sends errors to Rollbar * * If the context data contains a `payload` key, that is used as an array - * of payload options to RollbarLogger's log method. + * of payload options to RollbarLogger's log method. * * Rollbar's context info will contain the context + extra keys from the log record * merged, and then on top of that a few keys: @@ -59,9 +59,9 @@ class RollbarHandler extends AbstractProcessingHandler protected $initialized = false; /** - * @param RollbarLogger $rollbarLogger RollbarLogger object constructed with valid token - * @param int $level The minimum logging level at which this handler will be triggered - * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param RollbarLogger $rollbarLogger RollbarLogger object constructed with valid token + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(RollbarLogger $rollbarLogger, $level = Logger::ERROR, $bubble = true) { @@ -96,7 +96,7 @@ class RollbarHandler extends AbstractProcessingHandler } else { $toLog = $record['message']; } - + $this->rollbarLogger->log($context['level'], $toLog, $context); $this->hasRecords = true; diff --git a/src/Monolog/Handler/SlackWebhookHandler.php b/src/Monolog/Handler/SlackWebhookHandler.php index 7576cacb..2904db3f 100644 --- a/src/Monolog/Handler/SlackWebhookHandler.php +++ b/src/Monolog/Handler/SlackWebhookHandler.php @@ -90,7 +90,7 @@ class SlackWebhookHandler extends AbstractProcessingHandler CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array('Content-type: application/json'), - CURLOPT_POSTFIELDS => $postString + CURLOPT_POSTFIELDS => $postString, ); if (defined('CURLOPT_SAFE_UPLOAD')) { $options[CURLOPT_SAFE_UPLOAD] = true; diff --git a/src/Monolog/Handler/SqsHandler.php b/src/Monolog/Handler/SqsHandler.php index 3b2a713d..ed595c71 100644 --- a/src/Monolog/Handler/SqsHandler.php +++ b/src/Monolog/Handler/SqsHandler.php @@ -21,7 +21,6 @@ use Monolog\Logger; */ class SqsHandler extends AbstractProcessingHandler { - /** 256 KB in bytes - maximum message size in SQS */ const MAX_MESSAGE_SIZE = 262144; /** 100 KB in bytes - head message size for new error log */ diff --git a/src/Monolog/Handler/StreamHandler.php b/src/Monolog/Handler/StreamHandler.php index 13361c88..6631ef4e 100644 --- a/src/Monolog/Handler/StreamHandler.php +++ b/src/Monolog/Handler/StreamHandler.php @@ -106,6 +106,7 @@ class StreamHandler extends AbstractProcessingHandler restore_error_handler(); if (!is_resource($this->stream)) { $this->stream = null; + throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url)); } } diff --git a/src/Monolog/Handler/TestHandler.php b/src/Monolog/Handler/TestHandler.php index b176721d..55c48334 100644 --- a/src/Monolog/Handler/TestHandler.php +++ b/src/Monolog/Handler/TestHandler.php @@ -101,6 +101,7 @@ class TestHandler extends AbstractProcessingHandler if (isset($record['context']) && $rec['context'] !== $record['context']) { return false; } + return true; }, $level); } diff --git a/src/Monolog/Handler/WebRequestRecognizerTrait.php b/src/Monolog/Handler/WebRequestRecognizerTrait.php index fb137561..c8183528 100644 --- a/src/Monolog/Handler/WebRequestRecognizerTrait.php +++ b/src/Monolog/Handler/WebRequestRecognizerTrait.php @@ -1,10 +1,18 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Monolog\Handler; trait WebRequestRecognizerTrait { - /** * Checks if PHP's serving a web request * @return bool diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 7a2dcf1c..a22bf7ec 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -276,10 +276,10 @@ class Logger implements LoggerInterface /** * Adds a log record. * - * @param int $level The logging level - * @param string $message The log message - * @param array $context The log context - * @return bool Whether the record has been processed + * @param int $level The logging level + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed */ public function addRecord(int $level, string $message, array $context = []): bool { diff --git a/src/Monolog/Processor/HostnameProcessor.php b/src/Monolog/Processor/HostnameProcessor.php index 23ddaf48..fef40849 100644 --- a/src/Monolog/Processor/HostnameProcessor.php +++ b/src/Monolog/Processor/HostnameProcessor.php @@ -11,8 +11,6 @@ namespace Monolog\Processor; -use Monolog\Logger; - /** * Injects value of gethostname in all records */ diff --git a/src/Monolog/Processor/IntrospectionProcessor.php b/src/Monolog/Processor/IntrospectionProcessor.php index e1b5d3a3..5fe5b2aa 100644 --- a/src/Monolog/Processor/IntrospectionProcessor.php +++ b/src/Monolog/Processor/IntrospectionProcessor.php @@ -65,11 +65,13 @@ class IntrospectionProcessor foreach ($this->skipClassesPartials as $part) { if (strpos($trace[$i]['class'], $part) !== false) { $i++; + continue 2; } } } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) { $i++; + continue; } diff --git a/src/Monolog/Processor/PsrLogMessageProcessor.php b/src/Monolog/Processor/PsrLogMessageProcessor.php index f845f883..7311c2be 100644 --- a/src/Monolog/Processor/PsrLogMessageProcessor.php +++ b/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -28,8 +28,8 @@ class PsrLogMessageProcessor private $removeUsedContextFields; /** - * @param string $dateFormat The format of the timestamp: one supported by DateTime::format - * @param bool $removeUsedContextFields If set to true the fields interpolated into message gets unset + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + * @param bool $removeUsedContextFields If set to true the fields interpolated into message gets unset */ public function __construct(string $dateFormat = null, bool $removeUsedContextFields = false) { diff --git a/tests/Monolog/Formatter/GelfMessageFormatterTest.php b/tests/Monolog/Formatter/GelfMessageFormatterTest.php index 39eeaf70..012de3cd 100644 --- a/tests/Monolog/Formatter/GelfMessageFormatterTest.php +++ b/tests/Monolog/Formatter/GelfMessageFormatterTest.php @@ -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(); diff --git a/tests/Monolog/Handler/ElasticSearchHandlerTest.php b/tests/Monolog/Handler/ElasticSearchHandlerTest.php index e0e207db..7c92555a 100644 --- a/tests/Monolog/Handler/ElasticSearchHandlerTest.php +++ b/tests/Monolog/Handler/ElasticSearchHandlerTest.php @@ -183,6 +183,7 @@ class ElasticSearchHandlerTest extends TestCase $client = new Client(); $handler = new ElasticSearchHandler($client, $this->options); + try { $handler->handleBatch([$msg]); } catch (\RuntimeException $e) { diff --git a/tests/Monolog/Handler/FilterHandlerTest.php b/tests/Monolog/Handler/FilterHandlerTest.php index 0e64e769..b0072de0 100644 --- a/tests/Monolog/Handler/FilterHandlerTest.php +++ b/tests/Monolog/Handler/FilterHandlerTest.php @@ -146,7 +146,10 @@ class FilterHandlerTest extends TestCase $handler = new FilterHandler( function ($record, $handler) use ($test) { return $test; - }, Logger::INFO, Logger::NOTICE, false + }, + Logger::INFO, + Logger::NOTICE, + false ); $handler->handle($this->getRecord(Logger::DEBUG)); $handler->handle($this->getRecord(Logger::INFO)); diff --git a/tests/Monolog/Handler/InsightOpsHandlerTest.php b/tests/Monolog/Handler/InsightOpsHandlerTest.php index a0338b66..209858ae 100644 --- a/tests/Monolog/Handler/InsightOpsHandlerTest.php +++ b/tests/Monolog/Handler/InsightOpsHandlerTest.php @@ -1,4 +1,4 @@ - * @author Gabriel Machado */ @@ -62,7 +62,6 @@ class InsightOpsHandlerTest extends TestCase ->setConstructorArgs($args) ->getMock(); - $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($this->handler, 'localhost:1234'); diff --git a/tests/Monolog/Handler/RollbarHandlerTest.php b/tests/Monolog/Handler/RollbarHandlerTest.php index 96d8a30a..67a0eb68 100644 --- a/tests/Monolog/Handler/RollbarHandlerTest.php +++ b/tests/Monolog/Handler/RollbarHandlerTest.php @@ -59,9 +59,9 @@ class RollbarHandlerTest extends TestCase { $config = array( 'access_token' => 'ad865e76e7fb496fab096ac07b1dbabb', - 'environment' => 'test' + 'environment' => 'test', ); - + $this->rollbarLogger = $this->getMockBuilder(RollbarLogger::class) ->setConstructorArgs(array($config)) ->setMethods(array('log')) diff --git a/tests/Monolog/Handler/RotatingFileHandlerTest.php b/tests/Monolog/Handler/RotatingFileHandlerTest.php index 9454b0f5..7d3e8c4f 100644 --- a/tests/Monolog/Handler/RotatingFileHandlerTest.php +++ b/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -102,10 +102,10 @@ class RotatingFileHandlerTest extends TestCase $dayCallback = function ($ago) use ($now) { return $now + 86400 * $ago; }; - $monthCallback = function($ago) { + $monthCallback = function ($ago) { return gmmktime(0, 0, 0, (int) (date('n') + $ago), 1, (int) date('Y')); }; - $yearCallback = function($ago) { + $yearCallback = function ($ago) { return gmmktime(0, 0, 0, 1, 1, (int) (date('Y') + $ago)); }; @@ -216,7 +216,6 @@ class RotatingFileHandlerTest extends TestCase public function rotationWhenSimilarFilesExistTests() { - return array( 'Rotation is triggered when the file of the current day is not present but similar exists' => array(RotatingFileHandler::FILE_PER_DAY), diff --git a/tests/Monolog/Handler/TestHandlerTest.php b/tests/Monolog/Handler/TestHandlerTest.php index 9214983f..cc8e60ff 100644 --- a/tests/Monolog/Handler/TestHandlerTest.php +++ b/tests/Monolog/Handler/TestHandlerTest.php @@ -54,7 +54,8 @@ class TestHandlerTest extends TestCase $this->assertEquals([$record], $records); } - public function testHandlerAssertEmptyContext() { + public function testHandlerAssertEmptyContext() + { $handler = new TestHandler; $record = $this->getRecord(Logger::WARNING, 'test', []); $this->assertFalse($handler->hasWarning([ @@ -71,18 +72,19 @@ class TestHandlerTest extends TestCase $this->assertFalse($handler->hasWarning([ 'message' => 'test', 'context' => [ - 'foo' => 'bar' + 'foo' => 'bar', ], ])); } - public function testHandlerAssertNonEmptyContext() { + public function testHandlerAssertNonEmptyContext() + { $handler = new TestHandler; $record = $this->getRecord(Logger::WARNING, 'test', ['foo' => 'bar']); $this->assertFalse($handler->hasWarning([ 'message' => 'test', 'context' => [ - 'foo' => 'bar' + 'foo' => 'bar', ], ])); @@ -91,7 +93,7 @@ class TestHandlerTest extends TestCase $this->assertTrue($handler->hasWarning([ 'message' => 'test', 'context' => [ - 'foo' => 'bar' + 'foo' => 'bar', ], ])); $this->assertFalse($handler->hasWarning([ From c465e1144536862e03f519cb3d65e924062cabfb Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 19 Jun 2018 09:22:34 +0200 Subject: [PATCH 80/80] Clarify NewRelicHandler requirements, closes #1123 --- src/Monolog/Handler/NewRelicHandler.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Monolog/Handler/NewRelicHandler.php b/src/Monolog/Handler/NewRelicHandler.php index ed2efa27..f911997a 100644 --- a/src/Monolog/Handler/NewRelicHandler.php +++ b/src/Monolog/Handler/NewRelicHandler.php @@ -18,6 +18,8 @@ use Monolog\Formatter\NormalizerFormatter; * Class to record a log on a NewRelic application. * Enabling New Relic High Security mode may prevent capture of useful information. * + * This handler requires a NormalizerFormatter to function and expects an array in $record['formatted'] + * * @see https://docs.newrelic.com/docs/agents/php-agent * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security */