diff options
180 files changed, 3274 insertions, 2622 deletions
diff --git a/.gitattributes b/.gitattributes index 4afe792..77aef9a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ -.gitattributes export-ignore -.gitignore export-ignore -.travis.yml export-ignore +/doc export-ignore +/tests export-ignore +/.* export-ignore +/phpunit.xml.dist @@ -9,7 +9,7 @@ For the full copyright and license information, please view the LICENSE file that was distributed with this source code. EOF; -$finder = Symfony\CS\Finder::create() +$finder = PhpCsFixer\Finder::create() ->files() ->name('*.php') ->exclude('Fixtures') @@ -17,7 +17,7 @@ $finder = Symfony\CS\Finder::create() ->in(__DIR__.'/tests') ; -return Symfony\CS\Config::create() +return PhpCsFixer\Config::create() ->setUsingCache(true) //->setUsingLinter(false) ->setRiskyAllowed(true) @@ -25,19 +25,20 @@ return Symfony\CS\Config::create() '@PSR2' => true, 'binary_operator_spaces' => true, 'blank_line_before_return' => true, + 'cast_spaces' => true, 'header_comment' => array('header' => $header), 'include' => true, - 'long_array_syntax' => true, 'method_separation' => true, 'no_blank_lines_after_class_opening' => true, 'no_blank_lines_after_phpdoc' => true, 'no_blank_lines_between_uses' => true, - 'no_duplicate_semicolons' => true, + 'no_empty_statement' => true, 'no_extra_consecutive_blank_lines' => true, 'no_leading_import_slash' => true, 'no_leading_namespace_whitespace' => true, 'no_trailing_comma_in_singleline_array' => true, 'no_unused_imports' => true, + 'no_whitespace_in_blank_lines' => true, 'object_operator_without_whitespace' => true, 'phpdoc_align' => true, 'phpdoc_indent' => true, @@ -48,12 +49,11 @@ return Symfony\CS\Config::create() 'phpdoc_trim' => true, 'phpdoc_type_to_var' => true, 'psr0' => true, + 'short_array_syntax' => true, 'single_blank_line_before_namespace' => true, - 'spaces_cast' => true, 'standardize_not_equals' => true, 'ternary_operator_spaces' => true, 'trailing_comma_in_multiline_array' => true, - 'whitespacy_lines' => true, )) ->finder($finder) ; diff --git a/.travis.yml b/.travis.yml index de07fa9..0f1111c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,19 +4,14 @@ sudo: false matrix: include: - - php: 5.3 - - php: 5.3 + - php: 7 env: deps=low - - php: 5.4 - - php: 5.5 - - php: 5.6 - php: 7 - - php: hhvm fast_finish: true before_script: - - if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi - - if [ "`phpenv version-name`" != "hhvm" ]; then echo "extension = amqp.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi + - echo "extension = mongodb.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + - echo "extension = amqp.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - if [ "$deps" == "low" ]; then composer update --prefer-source --prefer-lowest --prefer-stable; fi - if [ "$deps" != "low" ]; then composer install --prefer-source; fi diff --git a/README.mdown b/README.mdown index 7d8ade5..c64b25f 100644 --- a/README.mdown +++ b/README.mdown @@ -37,8 +37,8 @@ $log = new Logger('name'); $log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); // add records to the log -$log->addWarning('Foo'); -$log->addError('Bar'); +$log->warning('Foo'); +$log->error('Bar'); ``` ## Documentation @@ -79,6 +79,7 @@ Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/mono - [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog. - [Nette Framework](http://nette.org/en/) can be used with Monolog via [Kdyby/Monolog](https://github.com/Kdyby/Monolog) extension. - [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog. +- [FuelPHP](http://fuelphp.com/) come out of the box with Monolog. ### Author diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 0000000..81b6e90 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,17 @@ +### 2.0.0 + +- The timezone is now set per Logger instance and not statically, either + via ->setTimezone or passed in the constructor. Calls to Logger::setTimezone + should be converted. + +- Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`) + methods as well as `emerg`, `crit`, `err` and `warn`. + +- `HandlerInterface` has been split off and two new interfaces now exist for + more granular controls: `ProcessableHandlerInterface` and + `FormattableHandlerInterface`. Handlers not extending `AbstractHandler` + should make sure to implement the relevant interfaces. + +- `HandlerInterface` now requires the `close` method to be implemented. This + only impacts you if you implement the interface yourself, but you can extend + the new `Monolog\Handler\Handler` base class. diff --git a/composer.json b/composer.json index b488c38..5d32be6 100644 --- a/composer.json +++ b/composer.json @@ -13,12 +13,12 @@ } ], "require": { - "php": ">=5.3.0", - "psr/log": "~1.0" + "php": "^7.0", + "psr/log": "^1.0" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "graylog2/gelf-php": "~1.0", + "phpunit/phpunit": "^5.3", + "graylog2/gelf-php": "^1.4.2", "sentry/sentry": "^0.13", "ruflin/elastica": ">=0.90 <3.0", "doctrine/couchdb": "~1.0@dev", @@ -26,10 +26,8 @@ "php-amqplib/php-amqplib": "~2.4", "swiftmailer/swiftmailer": "~5.3", "php-console/php-console": "^3.1.3", - "phpunit/phpunit-mock-objects": "2.3.0", - "jakub-onderka/php-parallel-lint": "0.9" + "jakub-onderka/php-parallel-lint": "^0.9" }, - "_": "phpunit/phpunit-mock-objects required in 2.3.0 due to https://github.com/sebastianbergmann/phpunit-mock-objects/issues/223 - needs hhvm 3.8+ on travis", "suggest": { "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", "sentry/sentry": "Allow sending log messages to a Sentry server", @@ -37,8 +35,8 @@ "ruflin/elastica": "Allow sending log messages to an Elastic Search server", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", "rollbar/rollbar": "Allow sending log messages to Rollbar", "php-console/php-console": "Allow sending log messages to Google Chrome" diff --git a/doc/02-handlers-formatters-processors.md b/doc/02-handlers-formatters-processors.md index 9170d6d..93dc58d 100644 --- a/doc/02-handlers-formatters-processors.md +++ b/doc/02-handlers-formatters-processors.md @@ -15,69 +15,72 @@ ### Log to files and syslog -- _StreamHandler_: Logs records into any PHP stream, use this for log files. -- _RotatingFileHandler_: Logs records to a file and creates one logfile per day. +- [_StreamHandler_](../src/Monolog/Handler/StreamHandler.php): Logs records into any PHP stream, use this for log files. +- [_RotatingFileHandler_](../src/Monolog/Handler/RotatingFileHandler.php): Logs records to a file and creates one logfile per day. It will also delete files older than `$maxFiles`. You should use [logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile setups though, this is just meant as a quick and dirty solution. -- _SyslogHandler_: Logs records to the syslog. -- _ErrorLogHandler_: Logs records to PHP's +- [_SyslogHandler_](../src/Monolog/Handler/SyslogHandler.php): Logs records to the syslog. +- [_ErrorLogHandler_](../src/Monolog/Handler/ErrorLogHandler.php): Logs records to PHP's [`error_log()`](http://docs.php.net/manual/en/function.error-log.php) function. +- [_ProcessHandler_](../src/Monolog/Handler/ProcessHandler.php): Logs records to the [STDIN](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29) of any process, specified by a command. ### Send alerts and emails -- _NativeMailerHandler_: Sends emails using PHP's +- [_NativeMailerHandler_](../src/Monolog/Handler/NativeMailerHandler.php): Sends emails using PHP's [`mail()`](http://php.net/manual/en/function.mail.php) function. -- _SwiftMailerHandler_: Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance. -- _PushoverHandler_: Sends mobile notifications via the [Pushover](https://www.pushover.net/) API. -- _HipChatHandler_: Logs records to a [HipChat](http://hipchat.com) chat room using its API. -- _FlowdockHandler_: Logs records to a [Flowdock](https://www.flowdock.com/) account. -- _SlackHandler_: Logs records to a [Slack](https://www.slack.com/) account. -- _MandrillHandler_: Sends emails via the Mandrill API using a [`Swift_Message`](http://swiftmailer.org/) instance. -- _FleepHookHandler_: Logs records to a [Fleep](https://fleep.io/) conversation using Webhooks. -- _IFTTTHandler_: Notifies an [IFTTT](https://ifttt.com/maker) trigger with the log channel, level name and message. +- [_SwiftMailerHandler_](../src/Monolog/Handler/SwiftMailerHandler.php): Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance. +- [_PushoverHandler_](../src/Monolog/Handler/PushoverHandler.php): Sends mobile notifications via the [Pushover](https://www.pushover.net/) API. +- [_HipChatHandler_](../src/Monolog/Handler/HipChatHandler.php): Logs records to a [HipChat](http://hipchat.com) chat room using its API. +- [_FlowdockHandler_](../src/Monolog/Handler/FlowdockHandler.php): Logs records to a [Flowdock](https://www.flowdock.com/) account. +- [_SlackHandler_](../src/Monolog/Handler/SlackHandler.php): Logs records to a [Slack](https://www.slack.com/) account. +- [_SendGridHandler_](../src/Monolog/Handler/SendGridHandler.php): Sends emails via the SendGrid API. +- [_MandrillHandler_](../src/Monolog/Handler/MandrillHandler.php): Sends emails via the Mandrill API using a [`Swift_Message`](http://swiftmailer.org/) instance. +- [_FleepHookHandler_](../src/Monolog/Handler/FleepHookHandler.php): Logs records to a [Fleep](https://fleep.io/) conversation using Webhooks. +- [_IFTTTHandler_](../src/Monolog/Handler/IFTTTHandler.php): Notifies an [IFTTT](https://ifttt.com/maker) trigger with the log channel, level name and message. ### Log specific servers and networked logging -- _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this +- [_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_: Logs records to an [amqp](http://www.amqp.org/) compatible +- [_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_: Logs records to a [Graylog2](http://www.graylog2.org) server. -- _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server. -- _RavenHandler_: Logs records to a [Sentry](http://getsentry.com/) server using +- [_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 [raven](https://packagist.org/packages/raven/raven). -- _ZendMonitorHandler_: Logs records to the Zend Monitor present in Zend Server. -- _NewRelicHandler_: Logs records to a [NewRelic](http://newrelic.com/) application. -- _LogglyHandler_: Logs records to a [Loggly](http://www.loggly.com/) account. -- _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. +- [_ZendMonitorHandler_](../src/Monolog/Handler/ZendMonitorHandler.php): Logs records to the Zend Monitor present in Zend Server. +- [_NewRelicHandler_](../src/Monolog/Handler/NewRelicHandler.php): Logs records to a [NewRelic](http://newrelic.com/) application. +- [_LogglyHandler_](../src/Monolog/Handler/LogglyHandler.php): Logs records to a [Loggly](http://www.loggly.com/) account. +- [_RollbarHandler_](../src/Monolog/Handler/RollbarHandler.php): Logs records to a [Rollbar](https://rollbar.com/) account. +- [_SyslogUdpHandler_](../src/Monolog/Handler/SyslogUdpHandler.php): Logs records to a remote [Syslogd](http://www.rsyslog.com/) server. +- [_LogEntriesHandler_](../src/Monolog/Handler/LogEntriesHandler.php): Logs records to a [LogEntries](http://logentries.com/) account. +- [_LogmaticHandler_](../src/Monolog/Handler/LogmaticHandler.php): Logs records to a [Logmatic](http://logmatic.io/) account. ### Logging in development -- _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing +- [_FirePHPHandler_](../src/Monolog/Handler/FirePHPHandler.php): Handler for [FirePHP](http://www.firephp.org/), providing inline `console` messages within [FireBug](http://getfirebug.com/). -- _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing +- [_ChromePHPHandler_](../src/Monolog/Handler/ChromePHPHandler.php): Handler for [ChromePHP](http://www.chromephp.com/), providing inline `console` messages within Chrome. -- _BrowserConsoleHandler_: Handler to send logs to browser's Javascript `console` with +- [_BrowserConsoleHandler_](../src/Monolog/Handler/BrowserConsoleHandler.php): Handler to send logs to browser's Javascript `console` with no browser extension required. Most browsers supporting `console` API are supported. -- _PHPConsoleHandler_: Handler for [PHP Console](https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef), providing +- [_PHPConsoleHandler_](../src/Monolog/Handler/PHPConsoleHandler.php): Handler for [PHP Console](https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef), providing inline `console` and notification popup messages within Chrome. ### Log to databases -- _RedisHandler_: Logs records to a [redis](http://redis.io) server. -- _MongoDBHandler_: Handler to write records in MongoDB via a +- [_RedisHandler_](../src/Monolog/Handler/RedisHandler.php): Logs records to a [redis](http://redis.io) server. +- [_MongoDBHandler_](../src/Monolog/Handler/MongoDBHandler.php): Handler to write records in MongoDB via a [Mongo](http://pecl.php.net/package/mongo) extension connection. -- _CouchDBHandler_: Logs records to a CouchDB server. -- _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM. -- _ElasticSearchHandler_: Logs records to an Elastic Search server. -- _DynamoDbHandler_: Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php). +- [_CouchDBHandler_](../src/Monolog/Handler/CouchDBHandler.php): Logs records to a CouchDB server. +- [_DoctrineCouchDBHandler_](../src/Monolog/Handler/DoctrineCouchDBHandler.php): Logs records to a CouchDB server via the Doctrine CouchDB ODM. +- [_ElasticSearchHandler_](../src/Monolog/Handler/ElasticSearchHandler.php): Logs records to an Elastic Search server. +- [_DynamoDbHandler_](../src/Monolog/Handler/DynamoDbHandler.php): Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php). ### Wrappers / Special Handlers -- _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as +- [_FingersCrossedHandler_](../src/Monolog/Handler/FingersCrossedHandler.php): A very interesting wrapper. It takes a logger as parameter and will accumulate log records of all levels until a record exceeds the defined severity level. At which point it delivers all records, including those of lower severity, to the handler it wraps. This means that @@ -85,7 +88,7 @@ when it happens you will have the full information, including debug and info records. This provides you with all the information you need, but only when you need it. -- _DeduplicationHandler_: Useful if you are sending notifications or emails +- [_DeduplicationHandler_](../src/Monolog/Handler/DeduplicationHandler.php): Useful if you are sending notifications or emails when critical errors occur. It takes a logger as parameter and will accumulate log records of all levels until the end of the request (or `flush()` is called). At that point it delivers all records to the handler @@ -95,56 +98,57 @@ database is unreachable for example all your requests will fail and that can result in a lot of notifications being sent. Adding this handler reduces the amount of notifications to a manageable level. -- _WhatFailureGroupHandler_: This handler extends the _GroupHandler_ ignoring +- [_WhatFailureGroupHandler_](../src/Monolog/Handler/WhatFailureGroupHandler.php): This handler extends the _GroupHandler_ ignoring exceptions raised by each child handler. This allows you to ignore issues where a remote tcp connection may have died but you do not want your entire application to crash and may wish to continue to log to other handlers. -- _BufferHandler_: This handler will buffer all the log records it receives +- [_BufferHandler_](../src/Monolog/Handler/BufferHandler.php): This handler will buffer all the log records it receives until `close()` is called at which point it will call `handleBatch()` on the handler it wraps with all the log messages at once. This is very useful to send an email with all records at once for example instead of having one mail for every log record. -- _GroupHandler_: This handler groups other handlers. Every record received is +- [_GroupHandler_](../src/Monolog/Handler/GroupHandler.php): This handler groups other handlers. Every record received is sent to all the handlers it is configured with. -- _FilterHandler_: This handler only lets records of the given levels through +- [_FilterHandler_](../src/Monolog/Handler/FilterHandler.php): This handler only lets records of the given levels through to the wrapped handler. -- _SamplingHandler_: Wraps around another handler and lets you sample records +- [_SamplingHandler_](../src/Monolog/Handler/SamplingHandler.php): Wraps around another handler and lets you sample records if you only want to store some of them. -- _NullHandler_: Any record it can handle will be thrown away. This can be used +- [_NullHandler_](../src/Monolog/Handler/NullHandler.php): Any record it can handle will be thrown away. This can be used to put on top of an existing handler stack to disable it temporarily. -- _PsrHandler_: Can be used to forward log records to an existing PSR-3 logger -- _TestHandler_: Used for testing, it records everything that is sent to it and +- [_PsrHandler_](../src/Monolog/Handler/PsrHandler.php): Can be used to forward log records to an existing PSR-3 logger +- [_TestHandler_](../src/Monolog/Handler/TestHandler.php): Used for testing, it records everything that is sent to it and has accessors to read out the information. -- _HandlerWrapper_: A simple handler wrapper you can inherit from to create +- [_HandlerWrapper_](../src/Monolog/Handler/HandlerWrapper.php): A simple handler wrapper you can inherit from to create your own wrappers easily. ## Formatters -- _LineFormatter_: Formats a log record into a one-line string. -- _HtmlFormatter_: Used to format log records into a human readable html table, mainly suitable for emails. -- _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded. -- _ScalarFormatter_: Used to format log records into an associative array of scalar values. -- _JsonFormatter_: Encodes a log record into json. -- _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler. -- _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler. -- _GelfMessageFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler. -- _LogstashFormatter_: Used to format log records into [logstash](http://logstash.net/) event json, useful for any handler listed under inputs [here](http://logstash.net/docs/latest). -- _ElasticaFormatter_: Used to format log records into an Elastica\Document object, only useful for the ElasticSearchHandler. -- _LogglyFormatter_: Used to format log records into Loggly messages, only useful for the LogglyHandler. -- _FlowdockFormatter_: Used to format log records into Flowdock messages, only useful for the FlowdockHandler. -- _MongoDBFormatter_: Converts \DateTime instances to \MongoDate and objects recursively to arrays, only useful with the MongoDBHandler. +- [_LineFormatter_](../src/Monolog/Formatter/LineFormatter.php): Formats a log record into a one-line string. +- [_HtmlFormatter_](../src/Monolog/Formatter/HtmlFormatter.php): Used to format log records into a human readable html table, mainly suitable for emails. +- [_NormalizerFormatter_](../src/Monolog/Formatter/NormalizerFormatter.php): Normalizes objects/resources down to strings so a record can easily be serialized/encoded. +- [_ScalarFormatter_](../src/Monolog/Formatter/ScalarFormatter.php): Used to format log records into an associative array of scalar values. +- [_JsonFormatter_](../src/Monolog/Formatter/JsonFormatter.php): Encodes a log record into json. +- [_WildfireFormatter_](../src/Monolog/Formatter/WildfireFormatter.php): Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler. +- [_ChromePHPFormatter_](../src/Monolog/Formatter/ChromePHPFormatter.php): Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler. +- [_GelfMessageFormatter_](../src/Monolog/Formatter/GelfMessageFormatter.php): Used to format log records into Gelf message instances, only useful for the GelfHandler. +- [_LogstashFormatter_](../src/Monolog/Formatter/LogstashFormatter.php): Used to format log records into [logstash](http://logstash.net/) event json, useful for any handler listed under inputs [here](http://logstash.net/docs/latest). +- [_ElasticaFormatter_](../src/Monolog/Formatter/ElasticaFormatter.php): Used to format log records into an Elastica\Document object, only useful for the ElasticSearchHandler. +- [_LogglyFormatter_](../src/Monolog/Formatter/LogglyFormatter.php): Used to format log records into Loggly messages, only useful for the LogglyHandler. +- [_FlowdockFormatter_](../src/Monolog/Formatter/FlowdockFormatter.php): Used to format log records into Flowdock messages, only useful for the FlowdockHandler. +- [_MongoDBFormatter_](../src/Monolog/Formatter/MongoDBFormatter.php): Converts \DateTime instances to \MongoDate and objects recursively to arrays, only useful with the MongoDBHandler. +- [_LogmaticFormatter_](../src/Monolog/Formatter/LogmaticFormatter.php): User to format log records to [Logmatic](http://logmatic.io/) messages, only useful for the LogmaticHandler. ## Processors -- _PsrLogMessageProcessor_: Processes a log record's message according to PSR-3 rules, replacing `{foo}` with the value from `$context['foo']`. -- _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated. -- _WebProcessor_: Adds the current request URI, request method and client IP to a log record. -- _MemoryUsageProcessor_: Adds the current memory usage to a log record. -- _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record. -- _ProcessIdProcessor_: Adds the process id to a log record. -- _UidProcessor_: Adds a unique identifier to a log record. -- _GitProcessor_: Adds the current git branch and commit to a log record. -- _TagProcessor_: Adds an array of predefined tags to a log record. +- [_PsrLogMessageProcessor_](../src/Monolog/Processor/PsrLogMessageProcessor.php): Processes a log record's message according to PSR-3 rules, replacing `{foo}` with the value from `$context['foo']`. +- [_IntrospectionProcessor_](../src/Monolog/Processor/IntrospectionProcessor.php): Adds the line/file/class/method from which the log call originated. +- [_WebProcessor_](../src/Monolog/Processor/WebProcessor.php): Adds the current request URI, request method and client IP to a log record. +- [_MemoryUsageProcessor_](../src/Monolog/Processor/MemoryUsageProcessor.php): Adds the current memory usage to a log record. +- [_MemoryPeakUsageProcessor_](../src/Monolog/Processor/MemoryPeakUsageProcessor.php): Adds the peak memory usage to a log record. +- [_ProcessIdProcessor_](../src/Monolog/Processor/ProcessIdProcessor.php): Adds the process id to a log record. +- [_UidProcessor_](../src/Monolog/Processor/UidProcessor.php): Adds a unique identifier to a log record. +- [_GitProcessor_](../src/Monolog/Processor/GitProcessor.php): Adds the current git branch and commit to a log record. +- [_TagProcessor_](../src/Monolog/Processor/TagProcessor.php): Adds an array of predefined tags to a log record. ## Third Party Packages diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 20d82b6..54da281 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<phpunit bootstrap="vendor/autoload.php" colors="true"> +<phpunit bootstrap="tests/bootstrap.php" colors="true"> <testsuites> <testsuite name="Monolog Test Suite"> <directory>tests/Monolog/</directory> diff --git a/src/Monolog/DateTimeImmutable.php b/src/Monolog/DateTimeImmutable.php new file mode 100644 index 0000000..6ca786c --- /dev/null +++ b/src/Monolog/DateTimeImmutable.php @@ -0,0 +1,52 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +/** + * Overrides default json encoding of date time objects + * + * @author Menno Holtkamp + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +class DateTimeImmutable extends \DateTimeImmutable implements \JsonSerializable +{ + private $useMicroseconds; + + public function __construct($useMicroseconds, \DateTimeZone $timezone = null) + { + $date = 'now'; + if ($useMicroseconds) { + // Circumvent DateTimeImmutable::createFromFormat() which always returns \DateTimeImmutable instead of `static` + // @link https://bugs.php.net/bug.php?id=60302 + $timestamp = microtime(true); + $microseconds = sprintf("%06d", ($timestamp - floor($timestamp)) * 1000000); + $date = date('Y-m-d H:i:s.' . $microseconds, (int) $timestamp); + } + parent::__construct($date, $timezone); + + $this->useMicroseconds = $useMicroseconds; + } + + public function jsonSerialize(): string + { + if ($this->useMicroseconds) { + return $this->format('Y-m-d\TH:i:s.uP'); + } + + return $this->format('Y-m-d\TH:i:sP'); + } + + public function __toString(): string + { + return $this->jsonSerialize(); + } +} diff --git a/src/Monolog/ErrorHandler.php b/src/Monolog/ErrorHandler.php index 715b93a..4038d82 100644 --- a/src/Monolog/ErrorHandler.php +++ b/src/Monolog/ErrorHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,7 +13,6 @@ namespace Monolog; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; -use Monolog\Handler\AbstractHandler; /** * Monolog error handler @@ -29,7 +28,7 @@ class ErrorHandler private $logger; private $previousExceptionHandler; - private $uncaughtExceptionLevel; + private $uncaughtExceptionLevelMap; private $previousErrorHandler; private $errorLevelMap; @@ -37,7 +36,7 @@ class ErrorHandler private $hasFatalErrorHandler; private $fatalLevel; private $reservedMemory; - private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR); + private static $fatalErrors = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR]; public function __construct(LoggerInterface $logger) { @@ -50,19 +49,19 @@ 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 int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling - * @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling + * @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 * @return ErrorHandler */ - public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null) + public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null) { $handler = new static($logger); if ($errorLevelMap !== false) { $handler->registerErrorHandler($errorLevelMap); } - if ($exceptionLevel !== false) { - $handler->registerExceptionHandler($exceptionLevel); + if ($exceptionLevelMap !== false) { + $handler->registerExceptionHandler($exceptionLevelMap); } if ($fatalLevel !== false) { $handler->registerFatalHandler($fatalLevel); @@ -71,18 +70,18 @@ class ErrorHandler return $handler; } - public function registerExceptionHandler($level = null, $callPrevious = true) + public function registerExceptionHandler($levelMap = [], $callPrevious = true) { - $prev = set_exception_handler(array($this, 'handleException')); - $this->uncaughtExceptionLevel = $level; + $prev = set_exception_handler([$this, 'handleException']); + $this->uncaughtExceptionLevelMap = array_replace($this->defaultExceptionLevelMap(), $levelMap); if ($callPrevious && $prev) { $this->previousExceptionHandler = $prev; } } - public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1) + public function registerErrorHandler(array $levelMap = [], $callPrevious = true, $errorTypes = -1) { - $prev = set_error_handler(array($this, 'handleError'), $errorTypes); + $prev = set_error_handler([$this, 'handleError'], $errorTypes); $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap); if ($callPrevious) { $this->previousErrorHandler = $prev ?: true; @@ -91,16 +90,24 @@ class ErrorHandler public function registerFatalHandler($level = null, $reservedMemorySize = 20) { - register_shutdown_function(array($this, 'handleFatalError')); + register_shutdown_function([$this, 'handleFatalError']); $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize); $this->fatalLevel = $level; $this->hasFatalErrorHandler = true; } + protected function defaultExceptionLevelMap() + { + return [ + 'ParseError' => LogLevel::CRITICAL, + 'Throwable' => LogLevel::ERROR, + ]; + } + protected function defaultErrorLevelMap() { - return array( + return [ E_ERROR => LogLevel::CRITICAL, E_WARNING => LogLevel::WARNING, E_PARSE => LogLevel::ALERT, @@ -116,7 +123,7 @@ class ErrorHandler E_RECOVERABLE_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::NOTICE, E_USER_DEPRECATED => LogLevel::NOTICE, - ); + ]; } /** @@ -124,10 +131,18 @@ class ErrorHandler */ public function handleException($e) { + $level = LogLevel::ERROR; + foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) { + if ($e instanceof $class) { + $level = $candidate; + break; + } + } + $this->logger->log( - $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel, + $level, sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), - array('exception' => $e) + ['exception' => $e] ); if ($this->previousExceptionHandler) { @@ -140,7 +155,7 @@ class ErrorHandler /** * @private */ - public function handleError($code, $message, $file = '', $line = 0, $context = array()) + public function handleError($code, $message, $file = '', $line = 0, $context = []) { if (!(error_reporting() & $code)) { return; @@ -149,7 +164,7 @@ class ErrorHandler // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries 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, 'context' => $context)); + $this->logger->log($level, self::codeToString($code).': '.$message, ['code' => $code, 'message' => $message, 'file' => $file, 'line' => $line, 'context' => $context]); } if ($this->previousErrorHandler === true) { @@ -171,14 +186,12 @@ 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']) + ['code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line']] ); if ($this->logger instanceof Logger) { foreach ($this->logger->getHandlers() as $handler) { - if ($handler instanceof AbstractHandler) { - $handler->close(); - } + $handler->close(); } } } diff --git a/src/Monolog/Formatter/ChromePHPFormatter.php b/src/Monolog/Formatter/ChromePHPFormatter.php index 9beda1e..12b0d60 100644 --- a/src/Monolog/Formatter/ChromePHPFormatter.php +++ b/src/Monolog/Formatter/ChromePHPFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -23,7 +23,7 @@ class ChromePHPFormatter implements FormatterInterface /** * Translates Monolog log levels to Wildfire levels. */ - private $logLevels = array( + private $logLevels = [ Logger::DEBUG => 'log', Logger::INFO => 'info', Logger::NOTICE => 'info', @@ -32,7 +32,7 @@ class ChromePHPFormatter implements FormatterInterface Logger::CRITICAL => 'error', Logger::ALERT => 'error', Logger::EMERGENCY => 'error', - ); + ]; /** * {@inheritdoc} @@ -46,7 +46,7 @@ class ChromePHPFormatter implements FormatterInterface unset($record['extra']['file'], $record['extra']['line']); } - $message = array('message' => $record['message']); + $message = ['message' => $record['message']]; if ($record['context']) { $message['context'] = $record['context']; } @@ -57,17 +57,17 @@ class ChromePHPFormatter implements FormatterInterface $message = reset($message); } - return array( + return [ $record['channel'], $message, $backtrace, $this->logLevels[$record['level']], - ); + ]; } public function formatBatch(array $records) { - $formatted = array(); + $formatted = []; foreach ($records as $record) { $formatted[] = $this->format($record); diff --git a/src/Monolog/Formatter/ElasticaFormatter.php b/src/Monolog/Formatter/ElasticaFormatter.php index 4c556cf..e6a5e67 100644 --- a/src/Monolog/Formatter/ElasticaFormatter.php +++ b/src/Monolog/Formatter/ElasticaFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Formatter/FlowdockFormatter.php b/src/Monolog/Formatter/FlowdockFormatter.php index 5094af3..6a33038 100644 --- a/src/Monolog/Formatter/FlowdockFormatter.php +++ b/src/Monolog/Formatter/FlowdockFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -43,11 +43,11 @@ class FlowdockFormatter implements FormatterInterface */ public function format(array $record) { - $tags = array( + $tags = [ '#logs', '#' . strtolower($record['level_name']), '#' . $record['channel'], - ); + ]; foreach ($record['extra'] as $value) { $tags[] = '#' . $value; @@ -60,14 +60,14 @@ class FlowdockFormatter implements FormatterInterface $this->getShortMessage($record['message']) ); - $record['flowdock'] = array( + $record['flowdock'] = [ 'source' => $this->source, 'from_address' => $this->sourceEmail, 'subject' => $subject, 'content' => $record['message'], 'tags' => $tags, 'project' => $this->source, - ); + ]; return $record; } @@ -77,7 +77,7 @@ class FlowdockFormatter implements FormatterInterface */ public function formatBatch(array $records) { - $formatted = array(); + $formatted = []; foreach ($records as $record) { $formatted[] = $this->format($record); diff --git a/src/Monolog/Formatter/FluentdFormatter.php b/src/Monolog/Formatter/FluentdFormatter.php index 02632bb..e2a6658 100644 --- a/src/Monolog/Formatter/FluentdFormatter.php +++ b/src/Monolog/Formatter/FluentdFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -60,17 +60,17 @@ class FluentdFormatter implements FormatterInterface $tag .= '.' . strtolower($record['level_name']); } - $message = array( + $message = [ 'message' => $record['message'], 'extra' => $record['extra'], - ); + ]; if (!$this->levelTag) { $message['level'] = $record['level']; $message['level_name'] = $record['level_name']; } - return json_encode(array($tag, $record['datetime']->getTimestamp(), $message)); + return json_encode([$tag, $record['datetime']->getTimestamp(), $message]); } public function formatBatch(array $records) diff --git a/src/Monolog/Formatter/FormatterInterface.php b/src/Monolog/Formatter/FormatterInterface.php index b5de751..7442134 100644 --- a/src/Monolog/Formatter/FormatterInterface.php +++ b/src/Monolog/Formatter/FormatterInterface.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Formatter/GelfMessageFormatter.php b/src/Monolog/Formatter/GelfMessageFormatter.php index 64e7665..047358a 100644 --- a/src/Monolog/Formatter/GelfMessageFormatter.php +++ b/src/Monolog/Formatter/GelfMessageFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -42,7 +42,7 @@ class GelfMessageFormatter extends NormalizerFormatter /** * Translates Monolog log levels to Graylog2 log priorities. */ - private $logLevels = array( + private $logLevels = [ Logger::DEBUG => 7, Logger::INFO => 6, Logger::NOTICE => 5, @@ -51,7 +51,7 @@ class GelfMessageFormatter extends NormalizerFormatter Logger::CRITICAL => 2, Logger::ALERT => 1, Logger::EMERGENCY => 0, - ); + ]; public function __construct($systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_') { @@ -68,7 +68,12 @@ class GelfMessageFormatter extends NormalizerFormatter */ public function format(array $record) { - $record = parent::format($record); + if (isset($record['context'])) { + $record['context'] = parent::format($record['context']); + } + if (isset($record['extra'])) { + $record['extra'] = parent::format($record['extra']); + } if (!isset($record['datetime'], $record['message'], $record['level'])) { throw new \InvalidArgumentException('The record should at least contain datetime, message and level keys, '.var_export($record, true).' given'); diff --git a/src/Monolog/Formatter/HtmlFormatter.php b/src/Monolog/Formatter/HtmlFormatter.php index 3eec95f..f5f9d94 100644 --- a/src/Monolog/Formatter/HtmlFormatter.php +++ b/src/Monolog/Formatter/HtmlFormatter.php @@ -1,4 +1,5 @@ -<?php +<?php declare(strict_types=1); + /* * This file is part of the Monolog package. * @@ -24,7 +25,7 @@ class HtmlFormatter extends NormalizerFormatter /** * Translates Monolog log levels to html color priorities. */ - protected $logLevels = array( + protected $logLevels = [ Logger::DEBUG => '#cccccc', Logger::INFO => '#468847', Logger::NOTICE => '#3a87ad', @@ -33,7 +34,7 @@ class HtmlFormatter extends NormalizerFormatter Logger::CRITICAL => '#FF7708', Logger::ALERT => '#C12A19', Logger::EMERGENCY => '#000000', - ); + ]; /** * @param string $dateFormat The format of the timestamp: one supported by DateTime::format @@ -87,7 +88,7 @@ class HtmlFormatter extends NormalizerFormatter $output .= '<table cellspacing="1" width="100%" class="monolog-output">'; $output .= $this->addRow('Message', (string) $record['message']); - $output .= $this->addRow('Time', $record['datetime']->format($this->dateFormat)); + $output .= $this->addRow('Time', $this->formatDate($record['datetime'])); $output .= $this->addRow('Channel', $record['channel']); if ($record['context']) { $embeddedTable = '<table cellspacing="1" width="100%">'; @@ -132,10 +133,7 @@ class HtmlFormatter extends NormalizerFormatter } $data = $this->normalize($data); - if (version_compare(PHP_VERSION, '5.4.0', '>=')) { - return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } - return str_replace('\\/', '/', json_encode($data)); + return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } } diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index a985e2a..1a8fe0b 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -135,10 +135,14 @@ 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(); + $normalized = []; $count = 1; foreach ($data as $key => $value) { @@ -146,7 +150,7 @@ class JsonFormatter extends NormalizerFormatter $normalized['...'] = 'Over 1000 items, aborting normalization'; break; } - $normalized[$key] = $this->normalize($value); + $normalized[$key] = $this->normalize($value, $depth + 1); } return $normalized; @@ -163,23 +167,18 @@ class JsonFormatter extends NormalizerFormatter * Normalizes given exception with or without its own stack trace based on * `includeStacktraces` property. * - * @param Exception|Throwable $e + * @param Throwable $e * * @return array */ - protected function normalizeException($e) + protected function normalizeException(\Throwable $e) { - // TODO 2.0 only check for Throwable - if (!$e instanceof Exception && !$e instanceof \Throwable) { - throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($e)); - } - - $data = array( + $data = [ 'class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile().':'.$e->getLine(), - ); + ]; if ($this->includeStacktraces) { $trace = $e->getTrace(); diff --git a/src/Monolog/Formatter/LineFormatter.php b/src/Monolog/Formatter/LineFormatter.php index 0e62aa3..5a65b4c 100644 --- a/src/Monolog/Formatter/LineFormatter.php +++ b/src/Monolog/Formatter/LineFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -119,13 +119,8 @@ class LineFormatter extends NormalizerFormatter return $this->replaceNewlines($this->convertToString($value)); } - protected function normalizeException($e) + protected function normalizeException(\Throwable $e) { - // TODO 2.0 only check for Throwable - if (!$e instanceof \Exception && !$e instanceof \Throwable) { - throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($e)); - } - $previousText = ''; if ($previous = $e->getPrevious()) { do { @@ -151,11 +146,7 @@ class LineFormatter extends NormalizerFormatter return (string) $data; } - if (version_compare(PHP_VERSION, '5.4.0', '>=')) { - return $this->toJson($data, true); - } - - return str_replace('\\/', '/', @json_encode($data)); + return $this->toJson($data, true); } protected function replaceNewlines($str) @@ -164,6 +155,6 @@ class LineFormatter extends NormalizerFormatter return $str; } - return str_replace(array("\r\n", "\r", "\n"), ' ', $str); + return str_replace(["\r\n", "\r", "\n"], ' ', $str); } } diff --git a/src/Monolog/Formatter/LogglyFormatter.php b/src/Monolog/Formatter/LogglyFormatter.php index 401859b..d4190df 100644 --- a/src/Monolog/Formatter/LogglyFormatter.php +++ b/src/Monolog/Formatter/LogglyFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -37,9 +37,9 @@ class LogglyFormatter extends JsonFormatter */ public function format(array $record) { - if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTime)) { + if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTimeInterface)) { $record["timestamp"] = $record["datetime"]->format("Y-m-d\TH:i:s.uO"); - // TODO 2.0 unset the 'datetime' parameter, retained for BC + unset($record["datetime"]); } return parent::format($record); diff --git a/src/Monolog/Formatter/LogmaticFormatter.php b/src/Monolog/Formatter/LogmaticFormatter.php new file mode 100644 index 0000000..2e10312 --- /dev/null +++ b/src/Monolog/Formatter/LogmaticFormatter.php @@ -0,0 +1,68 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Encodes message information into JSON in a format compatible with Logmatic. + * + * @author Julien Breux <julien.breux@gmail.com> + */ +class LogmaticFormatter extends JsonFormatter +{ + /** + * @param string + */ + protected $hostname = ''; + + /** + * @param string + */ + protected $appname = ''; + + /** + * Set hostname + * + * @param string $hostname + */ + public function setHostname(string $hostname) + { + $this->hostname = $hostname; + } + + /** + * Set appname + * + * @param string $appname + */ + public function setAppname(string $appname) + { + $this->appname = $appname; + } + + /** + * Appends the 'hostname' and 'appname' parameter for indexing by Logmatic. + * + * @see http://doc.logmatic.io/docs/basics-to-send-data + * @see \Monolog\Formatter\JsonFormatter::format() + */ + public function format(array $record) + { + if (!empty($this->hostname)) { + $record['hostname'] = $this->hostname; + } + if (!empty($this->appname)) { + $record['appname'] = $this->appname; + } + + return parent::format($record); + } +} diff --git a/src/Monolog/Formatter/LogstashFormatter.php b/src/Monolog/Formatter/LogstashFormatter.php index 8f83bec..31e354c 100644 --- a/src/Monolog/Formatter/LogstashFormatter.php +++ b/src/Monolog/Formatter/LogstashFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -21,9 +21,6 @@ namespace Monolog\Formatter; */ class LogstashFormatter extends NormalizerFormatter { - const V0 = 0; - const V1 = 1; - /** * @var string the name of the system for the Logstash log message, used to fill the @source field */ @@ -45,18 +42,13 @@ class LogstashFormatter extends NormalizerFormatter protected $contextPrefix; /** - * @var int logstash format version to use - */ - protected $version; - - /** * @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 int $version the logstash format version to use, defaults to 0 */ - public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0) + public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_') { // logstash requires a ISO 8601 format date with optional millisecond precision. parent::__construct('Y-m-d\TH:i:s.uP'); @@ -65,7 +57,6 @@ class LogstashFormatter extends NormalizerFormatter $this->applicationName = $applicationName; $this->extraPrefix = $extraPrefix; $this->contextPrefix = $contextPrefix; - $this->version = $version; } /** @@ -75,68 +66,14 @@ class LogstashFormatter extends NormalizerFormatter { $record = parent::format($record); - if ($this->version === self::V1) { - $message = $this->formatV1($record); - } else { - $message = $this->formatV0($record); - } - - return $this->toJson($message) . "\n"; - } - - protected function formatV0(array $record) - { - if (empty($record['datetime'])) { - $record['datetime'] = gmdate('c'); - } - $message = array( - '@timestamp' => $record['datetime'], - '@source' => $this->systemName, - '@fields' => array(), - ); - if (isset($record['message'])) { - $message['@message'] = $record['message']; - } - if (isset($record['channel'])) { - $message['@tags'] = array($record['channel']); - $message['@fields']['channel'] = $record['channel']; - } - if (isset($record['level'])) { - $message['@fields']['level'] = $record['level']; - } - if ($this->applicationName) { - $message['@type'] = $this->applicationName; - } - if (isset($record['extra']['server'])) { - $message['@source_host'] = $record['extra']['server']; - } - if (isset($record['extra']['url'])) { - $message['@source_path'] = $record['extra']['url']; - } - if (!empty($record['extra'])) { - foreach ($record['extra'] as $key => $val) { - $message['@fields'][$this->extraPrefix . $key] = $val; - } - } - if (!empty($record['context'])) { - foreach ($record['context'] as $key => $val) { - $message['@fields'][$this->contextPrefix . $key] = $val; - } - } - - return $message; - } - - protected function formatV1(array $record) - { if (empty($record['datetime'])) { $record['datetime'] = gmdate('c'); } - $message = array( + $message = [ '@timestamp' => $record['datetime'], '@version' => 1, 'host' => $this->systemName, - ); + ]; if (isset($record['message'])) { $message['message'] = $record['message']; } @@ -161,6 +98,6 @@ class LogstashFormatter extends NormalizerFormatter } } - return $message; + return $this->toJson($message) . "\n"; } } diff --git a/src/Monolog/Formatter/MongoDBFormatter.php b/src/Monolog/Formatter/MongoDBFormatter.php index eb067bb..0630f7c 100644 --- a/src/Monolog/Formatter/MongoDBFormatter.php +++ b/src/Monolog/Formatter/MongoDBFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,6 +11,8 @@ namespace Monolog\Formatter; +use MongoDB\BSON\UTCDateTime; + /** * Formats a record for use with the MongoDBHandler. * @@ -55,9 +57,9 @@ class MongoDBFormatter implements FormatterInterface { if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) { foreach ($record as $name => $value) { - if ($value instanceof \DateTime) { + if ($value instanceof \DateTimeInterface) { $record[$name] = $this->formatDate($value, $nestingLevel + 1); - } elseif ($value instanceof \Exception) { + } elseif ($value instanceof \Throwable) { $record[$name] = $this->formatException($value, $nestingLevel + 1); } elseif (is_array($value)) { $record[$name] = $this->formatArray($value, $nestingLevel + 1); @@ -80,14 +82,14 @@ class MongoDBFormatter implements FormatterInterface return $this->formatArray($objectVars, $nestingLevel); } - protected function formatException(\Exception $exception, $nestingLevel) + protected function formatException(\Throwable $exception, $nestingLevel) { - $formattedException = array( + $formattedException = [ 'class' => get_class($exception), 'message' => $exception->getMessage(), 'code' => $exception->getCode(), 'file' => $exception->getFile() . ':' . $exception->getLine(), - ); + ]; if ($this->exceptionTraceAsString === true) { $formattedException['trace'] = $exception->getTraceAsString(); @@ -98,8 +100,8 @@ class MongoDBFormatter implements FormatterInterface return $this->formatArray($formattedException, $nestingLevel); } - protected function formatDate(\DateTime $value, $nestingLevel) + protected function formatDate(\DateTimeInterface $value, $nestingLevel) { - return new \MongoDate($value->getTimestamp()); + return new UTCDateTime((int) ($value->format('U.u') * 1000)); } } diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index 9a4d5d2..fcac4a6 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,8 @@ namespace Monolog\Formatter; -use Exception; +use Throwable; +use Monolog\DateTimeImmutable; /** * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets @@ -20,16 +21,16 @@ use Exception; */ class NormalizerFormatter implements FormatterInterface { - const SIMPLE_DATE = "Y-m-d H:i:s"; + const SIMPLE_DATE = "Y-m-d\TH:i:sP"; protected $dateFormat; /** * @param string $dateFormat The format of the timestamp: one supported by DateTime::format */ - public function __construct($dateFormat = null) + public function __construct(string $dateFormat = null) { - $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE; + $this->dateFormat = null === $dateFormat ? static::SIMPLE_DATE : $dateFormat; if (!function_exists('json_encode')) { throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter'); } @@ -55,8 +56,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)) { @@ -71,7 +76,7 @@ class NormalizerFormatter implements FormatterInterface } if (is_array($data) || $data instanceof \Traversable) { - $normalized = array(); + $normalized = []; $count = 1; foreach ($data as $key => $value) { @@ -79,53 +84,53 @@ class NormalizerFormatter implements FormatterInterface $normalized['...'] = 'Over 1000 items, aborting normalization'; break; } - $normalized[$key] = $this->normalize($value); + $normalized[$key] = $this->normalize($value, $depth + 1); } return $normalized; } - if ($data instanceof \DateTime) { - return $data->format($this->dateFormat); + if ($data instanceof \DateTimeInterface) { + return $this->formatDate($data); } if (is_object($data)) { - // TODO 2.0 only check for Throwable - if ($data instanceof Exception || (PHP_VERSION_ID > 70000 && $data instanceof \Throwable)) { + if ($data instanceof Throwable) { return $this->normalizeException($data); } - // non-serializable objects that implement __toString stringified - if (method_exists($data, '__toString') && !$data instanceof \JsonSerializable) { + if ($data instanceof \JsonSerializable) { + $value = $data->jsonSerialize(); + } elseif (method_exists($data, '__toString')) { $value = $data->__toString(); } else { - // the rest is json-serialized in some way - $value = $this->toJson($data, true); + // the rest is normalized by json encoding and decoding it + $encoded = $this->toJson($data, true); + if ($encoded === false) { + $value = 'JSON_ERROR'; + } else { + $value = json_decode($encoded, true); + } } - return sprintf("[object] (%s: %s)", get_class($data), $value); + return [get_class($data) => $value]; } if (is_resource($data)) { - return sprintf('[resource] (%s)', get_resource_type($data)); + return sprintf('[resource(%s)]', get_resource_type($data)); } return '[unknown('.gettype($data).')]'; } - protected function normalizeException($e) + protected function normalizeException(Throwable $e) { - // TODO 2.0 only check for Throwable - if (!$e instanceof Exception && !$e instanceof \Throwable) { - throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($e)); - } - - $data = array( + $data = [ 'class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile().':'.$e->getLine(), - ); + ]; $trace = $e->getTrace(); foreach ($trace as $frame) { @@ -153,7 +158,7 @@ class NormalizerFormatter implements FormatterInterface * @param mixed $data * @param bool $ignoreErrors * @throws \RuntimeException if encoding fails and errors are not ignored - * @return string + * @return string|bool */ protected function toJson($data, $ignoreErrors = false) { @@ -172,16 +177,12 @@ class NormalizerFormatter implements FormatterInterface } /** - * @param mixed $data - * @return string JSON encoded data or null on failure + * @param mixed $data + * @return string|bool JSON encoded data or false on failure */ private function jsonEncode($data) { - if (version_compare(PHP_VERSION, '5.4.0', '>=')) { - return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } - - return json_encode($data); + return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } /** @@ -197,7 +198,7 @@ class NormalizerFormatter implements FormatterInterface * @throws \RuntimeException if failure can't be corrected * @return string JSON encoded data after error correction */ - private function handleJsonError($code, $data) + private function handleJsonError(int $code, $data): string { if ($code !== JSON_ERROR_UTF8) { $this->throwEncodeError($code, $data); @@ -206,7 +207,7 @@ class NormalizerFormatter implements FormatterInterface if (is_string($data)) { $this->detectAndCleanUtf8($data); } elseif (is_array($data)) { - array_walk_recursive($data, array($this, 'detectAndCleanUtf8')); + array_walk_recursive($data, [$this, 'detectAndCleanUtf8']); } else { $this->throwEncodeError($code, $data); } @@ -227,7 +228,7 @@ class NormalizerFormatter implements FormatterInterface * @param mixed $data data that was meant to be encoded * @throws \RuntimeException */ - private function throwEncodeError($code, $data) + private function throwEncodeError(int $code, $data) { switch ($code) { case JSON_ERROR_DEPTH: @@ -270,14 +271,25 @@ class NormalizerFormatter implements FormatterInterface if (is_string($data) && !preg_match('//u', $data)) { $data = preg_replace_callback( '/[\x80-\xFF]+/', - function ($m) { return utf8_encode($m[0]); }, + function ($m) { + return utf8_encode($m[0]); + }, $data ); $data = str_replace( - array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'), - array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'), + ['¤', '¦', '¨', '´', '¸', '¼', '½', '¾'], + ['€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'], $data ); } } + + protected function formatDate(\DateTimeInterface $date) + { + if ($date instanceof DateTimeImmutable) { + return (string) $date; + } + + return $date->format($this->dateFormat); + } } diff --git a/src/Monolog/Formatter/ScalarFormatter.php b/src/Monolog/Formatter/ScalarFormatter.php index 5d345d5..fcff129 100644 --- a/src/Monolog/Formatter/ScalarFormatter.php +++ b/src/Monolog/Formatter/ScalarFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Formatter/WildfireFormatter.php b/src/Monolog/Formatter/WildfireFormatter.php index 654710a..9c00aa7 100644 --- a/src/Monolog/Formatter/WildfireFormatter.php +++ b/src/Monolog/Formatter/WildfireFormatter.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -27,7 +27,7 @@ class WildfireFormatter extends NormalizerFormatter /** * Translates Monolog log levels to Wildfire levels. */ - private $logLevels = array( + private $logLevels = [ Logger::DEBUG => 'LOG', Logger::INFO => 'INFO', Logger::NOTICE => 'INFO', @@ -36,7 +36,7 @@ class WildfireFormatter extends NormalizerFormatter Logger::CRITICAL => 'ERROR', Logger::ALERT => 'ERROR', Logger::EMERGENCY => 'ERROR', - ); + ]; /** * {@inheritdoc} @@ -55,7 +55,7 @@ class WildfireFormatter extends NormalizerFormatter } $record = $this->normalize($record); - $message = array('message' => $record['message']); + $message = ['message' => $record['message']]; $handleError = false; if ($record['context']) { $message['context'] = $record['context']; @@ -79,15 +79,15 @@ class WildfireFormatter extends NormalizerFormatter } // Create JSON object describing the appearance of the message in the console - $json = $this->toJson(array( - array( + $json = $this->toJson([ + [ 'Type' => $type, 'File' => $file, 'Line' => $line, 'Label' => $label, - ), + ], $message, - ), $handleError); + ], $handleError); // The message itself is a serialization of the above JSON object + it's length return sprintf( @@ -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) { + if (is_object($data) && !$data instanceof \DateTimeInterface) { return $data; } - return parent::normalize($data); + return parent::normalize($data, $depth); } } diff --git a/src/Monolog/Handler/AbstractHandler.php b/src/Monolog/Handler/AbstractHandler.php index 758a425..ea79ec9 100644 --- a/src/Monolog/Handler/AbstractHandler.php +++ b/src/Monolog/Handler/AbstractHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,26 +12,18 @@ namespace Monolog\Handler; use Monolog\Logger; -use Monolog\Formatter\FormatterInterface; -use Monolog\Formatter\LineFormatter; /** - * Base Handler class providing the Handler structure + * Base Handler class providing basic level/bubble support * * @author Jordi Boggiano <j.boggiano@seld.be> */ -abstract class AbstractHandler implements HandlerInterface +abstract class AbstractHandler extends Handler { protected $level = Logger::DEBUG; protected $bubble = true; /** - * @var FormatterInterface - */ - protected $formatter; - 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 */ @@ -44,84 +36,18 @@ abstract class AbstractHandler implements HandlerInterface /** * {@inheritdoc} */ - public function isHandling(array $record) + public function isHandling(array $record): bool { return $record['level'] >= $this->level; } /** - * {@inheritdoc} - */ - public function handleBatch(array $records) - { - foreach ($records as $record) { - $this->handle($record); - } - } - - /** - * Closes the handler. - * - * This will be called automatically when the object is destroyed - */ - public function close() - { - } - - /** - * {@inheritdoc} - */ - public function pushProcessor($callback) - { - if (!is_callable($callback)) { - throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); - } - array_unshift($this->processors, $callback); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function popProcessor() - { - if (!$this->processors) { - throw new \LogicException('You tried to pop from an empty processor stack.'); - } - - return array_shift($this->processors); - } - - /** - * {@inheritdoc} - */ - public function setFormatter(FormatterInterface $formatter) - { - $this->formatter = $formatter; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getFormatter() - { - if (!$this->formatter) { - $this->formatter = $this->getDefaultFormatter(); - } - - return $this->formatter; - } - - /** * Sets minimum logging level at which this handler will be triggered. * * @param int|string $level Level or level name * @return self */ - public function setLevel($level) + public function setLevel($level): self { $this->level = Logger::toMonologLevel($level); @@ -133,7 +59,7 @@ abstract class AbstractHandler implements HandlerInterface * * @return int */ - public function getLevel() + public function getLevel(): int { return $this->level; } @@ -145,7 +71,7 @@ abstract class AbstractHandler implements HandlerInterface * false means that bubbling is not permitted. * @return self */ - public function setBubble($bubble) + public function setBubble(bool $bubble): self { $this->bubble = $bubble; @@ -158,29 +84,8 @@ abstract class AbstractHandler implements HandlerInterface * @return Boolean true means that this handler allows bubbling. * false means that bubbling is not permitted. */ - public function getBubble() + public function getBubble(): bool { return $this->bubble; } - - public function __destruct() - { - try { - $this->close(); - } catch (\Exception $e) { - // do nothing - } catch (\Throwable $e) { - // do nothing - } - } - - /** - * Gets the default formatter. - * - * @return FormatterInterface - */ - protected function getDefaultFormatter() - { - return new LineFormatter(); - } } diff --git a/src/Monolog/Handler/AbstractProcessingHandler.php b/src/Monolog/Handler/AbstractProcessingHandler.php index 6f18f72..654e671 100644 --- a/src/Monolog/Handler/AbstractProcessingHandler.php +++ b/src/Monolog/Handler/AbstractProcessingHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -19,18 +19,23 @@ namespace Monolog\Handler; * @author Jordi Boggiano <j.boggiano@seld.be> * @author Christophe Coevoet <stof@notk.org> */ -abstract class AbstractProcessingHandler extends AbstractHandler +abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { + use ProcessableHandlerTrait; + use FormattableHandlerTrait; + /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; } - $record = $this->processRecord($record); + if ($this->processors) { + $record = $this->processRecord($record); + } $record['formatted'] = $this->getFormatter()->format($record); @@ -46,21 +51,4 @@ abstract class AbstractProcessingHandler extends AbstractHandler * @return void */ abstract protected function write(array $record); - - /** - * Processes a record. - * - * @param array $record - * @return array - */ - protected function processRecord(array $record) - { - if ($this->processors) { - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } - } - - return $record; - } } diff --git a/src/Monolog/Handler/AbstractSyslogHandler.php b/src/Monolog/Handler/AbstractSyslogHandler.php index e2b2832..d6fc41e 100644 --- a/src/Monolog/Handler/AbstractSyslogHandler.php +++ b/src/Monolog/Handler/AbstractSyslogHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; /** @@ -24,7 +25,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler /** * Translates Monolog log levels to syslog log priorities. */ - protected $logLevels = array( + protected $logLevels = [ Logger::DEBUG => LOG_DEBUG, Logger::INFO => LOG_INFO, Logger::NOTICE => LOG_NOTICE, @@ -33,12 +34,12 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler Logger::CRITICAL => LOG_CRIT, Logger::ALERT => LOG_ALERT, Logger::EMERGENCY => LOG_EMERG, - ); + ]; /** * List of valid log facility names. */ - protected $facilities = array( + protected $facilities = [ 'auth' => LOG_AUTH, 'authpriv' => LOG_AUTHPRIV, 'cron' => LOG_CRON, @@ -50,7 +51,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler 'syslog' => LOG_SYSLOG, 'user' => LOG_USER, 'uucp' => LOG_UUCP, - ); + ]; /** * @param mixed $facility @@ -82,7 +83,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler } // convert textual description of facility to syslog constant - if (array_key_exists(strtolower($facility), $this->facilities)) { + if (is_string($facility) && array_key_exists(strtolower($facility), $this->facilities)) { $facility = $this->facilities[strtolower($facility)]; } elseif (!in_array($facility, array_values($this->facilities), true)) { throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); @@ -94,7 +95,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler /** * {@inheritdoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%'); } diff --git a/src/Monolog/Handler/AmqpHandler.php b/src/Monolog/Handler/AmqpHandler.php index 95a91fc..b46435a 100644 --- a/src/Monolog/Handler/AmqpHandler.php +++ b/src/Monolog/Handler/AmqpHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\JsonFormatter; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Channel\AMQPChannel; @@ -31,18 +32,18 @@ class AmqpHandler extends AbstractProcessingHandler /** * @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use - * @param string $exchangeName + * @param string $exchangeName Optional exchange name, for AMQPChannel (PhpAmqpLib) only * @param int $level * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ - public function __construct($exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true) + public function __construct($exchange, $exchangeName = null, $level = Logger::DEBUG, $bubble = true) { - if ($exchange instanceof AMQPExchange) { - $exchange->setName($exchangeName); - } elseif ($exchange instanceof AMQPChannel) { + if ($exchange instanceof AMQPChannel) { $this->exchangeName = $exchangeName; - } else { + } elseif (!$exchange instanceof AMQPExchange) { throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required'); + } elseif ($exchangeName) { + @trigger_error('The $exchangeName parameter can only be passed when using PhpAmqpLib, if using an AMQPExchange instance configure it beforehand', E_USER_DEPRECATED); } $this->exchange = $exchange; @@ -62,10 +63,10 @@ class AmqpHandler extends AbstractProcessingHandler $data, $routingKey, 0, - array( + [ 'delivery_mode' => 2, 'content_type' => 'application/json', - ) + ] ); } else { $this->exchange->basic_publish( @@ -113,12 +114,7 @@ class AmqpHandler extends AbstractProcessingHandler */ private function getRoutingKey(array $record) { - $routingKey = sprintf( - '%s.%s', - // TODO 2.0 remove substr call - substr($record['level_name'], 0, 4), - $record['channel'] - ); + $routingKey = sprintf('%s.%s', $record['level_name'], $record['channel']); return strtolower($routingKey); } @@ -131,17 +127,17 @@ class AmqpHandler extends AbstractProcessingHandler { return new AMQPMessage( (string) $data, - array( + [ 'delivery_mode' => 2, 'content_type' => 'application/json', - ) + ] ); } /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); } diff --git a/src/Monolog/Handler/BrowserConsoleHandler.php b/src/Monolog/Handler/BrowserConsoleHandler.php index b3a21bd..4879d24 100644 --- a/src/Monolog/Handler/BrowserConsoleHandler.php +++ b/src/Monolog/Handler/BrowserConsoleHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; +use Monolog\Formatter\FormatterInterface; /** * Handler sending logs to browser's javascript console with no browser extension required @@ -21,7 +22,7 @@ use Monolog\Formatter\LineFormatter; class BrowserConsoleHandler extends AbstractProcessingHandler { protected static $initialized = false; - protected static $records = array(); + protected static $records = []; /** * {@inheritDoc} @@ -32,7 +33,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler * * You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%'); } @@ -78,7 +79,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler */ public static function reset() { - self::$records = array(); + self::$records = []; } /** @@ -87,7 +88,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler protected function registerShutdownFunction() { if (PHP_SAPI !== 'cli') { - register_shutdown_function(array('Monolog\Handler\BrowserConsoleHandler', 'send')); + register_shutdown_function(['Monolog\Handler\BrowserConsoleHandler', 'send']); } } @@ -132,7 +133,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler private static function generateScript() { - $script = array(); + $script = []; foreach (self::$records as $record) { $context = self::dump('Context', $record['context']); $extra = self::dump('Extra', $record['extra']); @@ -141,10 +142,10 @@ class BrowserConsoleHandler extends AbstractProcessingHandler $script[] = self::call_array('log', self::handleStyles($record['formatted'])); } else { $script = array_merge($script, - array(self::call_array('groupCollapsed', self::handleStyles($record['formatted']))), + [self::call_array('groupCollapsed', self::handleStyles($record['formatted']))], $context, $extra, - array(self::call('groupEnd')) + [self::call('groupEnd')] ); } } @@ -154,7 +155,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler private static function handleStyles($formatted) { - $args = array(self::quote('font-weight: normal')); + $args = [self::quote('font-weight: normal')]; $format = '%c' . $formatted; preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); @@ -173,8 +174,8 @@ class BrowserConsoleHandler extends AbstractProcessingHandler private static function handleCustomStyles($style, $string) { - static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey'); - static $labels = array(); + static $colors = ['blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey']; + static $labels = []; return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function ($m) use ($string, &$colors, &$labels) { if (trim($m[1]) === 'autolabel') { @@ -193,7 +194,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler private static function dump($title, array $dict) { - $script = array(); + $script = []; $dict = array_filter($dict); if (empty($dict)) { return $script; diff --git a/src/Monolog/Handler/BufferHandler.php b/src/Monolog/Handler/BufferHandler.php index 72f8953..5ce6c39 100644 --- a/src/Monolog/Handler/BufferHandler.php +++ b/src/Monolog/Handler/BufferHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -21,13 +21,15 @@ use Monolog\Logger; * * @author Christophe Coevoet <stof@notk.org> */ -class BufferHandler extends AbstractHandler +class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface { + use ProcessableHandlerTrait; + protected $handler; protected $bufferSize = 0; protected $bufferLimit; protected $flushOnOverflow; - protected $buffer = array(); + protected $buffer = []; protected $initialized = false; /** @@ -48,7 +50,7 @@ class BufferHandler extends AbstractHandler /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if ($record['level'] < $this->level) { return false; @@ -56,7 +58,7 @@ class BufferHandler extends AbstractHandler if (!$this->initialized) { // __destructor() doesn't get called on Fatal errors - register_shutdown_function(array($this, 'close')); + register_shutdown_function([$this, 'close']); $this->initialized = true; } @@ -70,9 +72,7 @@ class BufferHandler extends AbstractHandler } if ($this->processors) { - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } + $record = $this->processRecord($record); } $this->buffer[] = $record; @@ -112,6 +112,6 @@ class BufferHandler extends AbstractHandler public function clear() { $this->bufferSize = 0; - $this->buffer = array(); + $this->buffer = []; } } diff --git a/src/Monolog/Handler/ChromePHPHandler.php b/src/Monolog/Handler/ChromePHPHandler.php index b00fa84..31573ad 100644 --- a/src/Monolog/Handler/ChromePHPHandler.php +++ b/src/Monolog/Handler/ChromePHPHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Formatter\ChromePHPFormatter; +use Monolog\Formatter\FormatterInterface; use Monolog\Logger; /** @@ -32,7 +33,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+) */ @@ -49,11 +50,11 @@ class ChromePHPHandler extends AbstractProcessingHandler */ protected static $overflowed = false; - protected static $json = array( + protected static $json = [ 'version' => self::VERSION, - 'columns' => array('label', 'log', 'backtrace', 'type'), - 'rows' => array(), - ); + 'columns' => ['label', 'log', 'backtrace', 'type'], + 'rows' => [], + ]; protected static $sendHeaders = true; @@ -74,7 +75,7 @@ class ChromePHPHandler extends AbstractProcessingHandler */ public function handleBatch(array $records) { - $messages = array(); + $messages = []; foreach ($records as $record) { if ($record['level'] < $this->level) { @@ -93,7 +94,7 @@ class ChromePHPHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new ChromePHPFormatter(); } @@ -139,15 +140,15 @@ class ChromePHPHandler extends AbstractProcessingHandler if (strlen($data) > 240 * 1024) { self::$overflowed = true; - $record = array( + $record = [ 'message' => 'Incomplete logs, chrome header size limit reached', - 'context' => array(), + 'context' => [], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'monolog', - 'datetime' => new \DateTime(), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable(), + 'extra' => [], + ]; self::$json['rows'][count(self::$json['rows']) - 1] = $this->getFormatter()->format($record); $json = @json_encode(self::$json); $data = base64_encode(utf8_encode($json)); diff --git a/src/Monolog/Handler/CouchDBHandler.php b/src/Monolog/Handler/CouchDBHandler.php index cc98697..e0603f3 100644 --- a/src/Monolog/Handler/CouchDBHandler.php +++ b/src/Monolog/Handler/CouchDBHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,6 +11,7 @@ namespace Monolog\Handler; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\JsonFormatter; use Monolog\Logger; @@ -23,15 +24,15 @@ class CouchDBHandler extends AbstractProcessingHandler { private $options; - public function __construct(array $options = array(), $level = Logger::DEBUG, $bubble = true) + public function __construct(array $options = [], $level = Logger::DEBUG, $bubble = true) { - $this->options = array_merge(array( + $this->options = array_merge([ 'host' => 'localhost', 'port' => 5984, 'dbname' => 'logger', 'username' => null, 'password' => null, - ), $options); + ], $options); parent::__construct($level, $bubble); } @@ -47,17 +48,17 @@ class CouchDBHandler extends AbstractProcessingHandler } $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname']; - $context = stream_context_create(array( - 'http' => array( + $context = stream_context_create([ + 'http' => [ 'method' => 'POST', 'content' => $record['formatted'], 'ignore_errors' => true, 'max_redirects' => 0, 'header' => 'Content-type: application/json', - ), - )); + ], + ]); - if (false === @file_get_contents($url, null, $context)) { + if (false === @file_get_contents($url, false, $context)) { throw new \RuntimeException(sprintf('Could not connect to %s', $url)); } } @@ -65,7 +66,7 @@ class CouchDBHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); } diff --git a/src/Monolog/Handler/CubeHandler.php b/src/Monolog/Handler/CubeHandler.php index 96b3ca0..ab6e007 100644 --- a/src/Monolog/Handler/CubeHandler.php +++ b/src/Monolog/Handler/CubeHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -26,7 +26,7 @@ class CubeHandler extends AbstractProcessingHandler private $scheme; private $host; private $port; - private $acceptedSchemes = array('http', 'udp'); + private $acceptedSchemes = ['http', 'udp']; /** * Create a Cube handler @@ -105,7 +105,7 @@ class CubeHandler extends AbstractProcessingHandler { $date = $record['datetime']; - $data = array('time' => $date->format('Y-m-d\TH:i:s.uO')); + $data = ['time' => $date->format('Y-m-d\TH:i:s.uO')]; unset($record['datetime']); if (isset($record['context']['type'])) { @@ -141,10 +141,10 @@ class CubeHandler extends AbstractProcessingHandler } curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']'); - curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array( + curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Content-Length: ' . strlen('['.$data.']'), - )); + ]); Curl\Util::execute($this->httpConnection, 5, false); } diff --git a/src/Monolog/Handler/Curl/Util.php b/src/Monolog/Handler/Curl/Util.php index 48d30b3..b0bec3d 100644 --- a/src/Monolog/Handler/Curl/Util.php +++ b/src/Monolog/Handler/Curl/Util.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,7 +13,7 @@ namespace Monolog\Handler\Curl; class Util { - private static $retriableErrorCodes = array( + private static $retriableErrorCodes = [ CURLE_COULDNT_RESOLVE_HOST, CURLE_COULDNT_CONNECT, CURLE_HTTP_NOT_FOUND, @@ -21,7 +21,7 @@ class Util CURLE_OPERATION_TIMEOUTED, CURLE_HTTP_POST_ERROR, CURLE_SSL_CONNECT_ERROR, - ); + ]; /** * Executes a CURL request with optional retries and exception on failure diff --git a/src/Monolog/Handler/DeduplicationHandler.php b/src/Monolog/Handler/DeduplicationHandler.php index 7778c22..235b3b8 100644 --- a/src/Monolog/Handler/DeduplicationHandler.php +++ b/src/Monolog/Handler/DeduplicationHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -81,7 +81,6 @@ class DeduplicationHandler extends BufferHandler foreach ($this->buffer as $record) { if ($record['level'] >= $this->deduplicationLevel) { - $passthru = $passthru || !$this->isDuplicate($record); if ($passthru) { $this->appendRecord($record); @@ -139,13 +138,13 @@ class DeduplicationHandler extends BufferHandler $handle = fopen($this->deduplicationStore, 'rw+'); flock($handle, LOCK_EX); - $validLogs = array(); + $validLogs = []; $timestampValidity = time() - $this->time; while (!feof($handle)) { $log = fgets($handle); - if (substr($log, 0, 10) >= $timestampValidity) { + if ($log && substr($log, 0, 10) >= $timestampValidity) { $validLogs[] = $log; } } diff --git a/src/Monolog/Handler/DoctrineCouchDBHandler.php b/src/Monolog/Handler/DoctrineCouchDBHandler.php index b91ffec..13a08ee 100644 --- a/src/Monolog/Handler/DoctrineCouchDBHandler.php +++ b/src/Monolog/Handler/DoctrineCouchDBHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,6 +13,7 @@ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\NormalizerFormatter; +use Monolog\Formatter\FormatterInterface; use Doctrine\CouchDB\CouchDBClient; /** @@ -38,7 +39,7 @@ class DoctrineCouchDBHandler extends AbstractProcessingHandler $this->client->postDocument($record['formatted']); } - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter; } diff --git a/src/Monolog/Handler/DynamoDbHandler.php b/src/Monolog/Handler/DynamoDbHandler.php index 7b20830..43d4ddb 100644 --- a/src/Monolog/Handler/DynamoDbHandler.php +++ b/src/Monolog/Handler/DynamoDbHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,6 +13,7 @@ namespace Monolog\Handler; use Aws\Common\Aws; use Aws\DynamoDb\DynamoDbClient; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\ScalarFormatter; use Monolog\Logger; @@ -62,10 +63,10 @@ class DynamoDbHandler extends AbstractProcessingHandler $filtered = $this->filterEmptyFields($record['formatted']); $formatted = $this->client->formatAttributes($filtered); - $this->client->putItem(array( + $this->client->putItem([ 'TableName' => $this->table, 'Item' => $formatted, - )); + ]); } /** @@ -82,7 +83,7 @@ class DynamoDbHandler extends AbstractProcessingHandler /** * {@inheritdoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new ScalarFormatter(self::DATE_FORMAT); } diff --git a/src/Monolog/Handler/ElasticSearchHandler.php b/src/Monolog/Handler/ElasticSearchHandler.php index 8196740..fbb999f 100644 --- a/src/Monolog/Handler/ElasticSearchHandler.php +++ b/src/Monolog/Handler/ElasticSearchHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -43,7 +43,7 @@ class ElasticSearchHandler extends AbstractProcessingHandler /** * @var array Handler config options */ - protected $options = array(); + protected $options = []; /** * @param Client $client Elastica Client object @@ -51,16 +51,16 @@ class ElasticSearchHandler extends AbstractProcessingHandler * @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 */ - public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = true) + public function __construct(Client $client, array $options = [], $level = Logger::DEBUG, $bubble = true) { parent::__construct($level, $bubble); $this->client = $client; $this->options = array_merge( - array( + [ 'index' => 'monolog', // Elastic index name 'type' => 'record', // Elastic document type 'ignore_error' => false, // Suppress Elastica exceptions - ), + ], $options ); } @@ -70,13 +70,13 @@ class ElasticSearchHandler extends AbstractProcessingHandler */ protected function write(array $record) { - $this->bulkSend(array($record['formatted'])); + $this->bulkSend([$record['formatted']]); } /** * {@inheritdoc} */ - public function setFormatter(FormatterInterface $formatter) + public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($formatter instanceof ElasticaFormatter) { return parent::setFormatter($formatter); @@ -96,7 +96,7 @@ class ElasticSearchHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new ElasticaFormatter($this->options['index'], $this->options['type']); } diff --git a/src/Monolog/Handler/ErrorLogHandler.php b/src/Monolog/Handler/ErrorLogHandler.php index 1447a58..b272878 100644 --- a/src/Monolog/Handler/ErrorLogHandler.php +++ b/src/Monolog/Handler/ErrorLogHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; +use Monolog\Formatter\FormatterInterface; use Monolog\Logger; /** @@ -51,16 +52,16 @@ class ErrorLogHandler extends AbstractProcessingHandler */ public static function getAvailableTypes() { - return array( + return [ self::OPERATING_SYSTEM, self::SAPI, - ); + ]; } /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%'); } diff --git a/src/Monolog/Handler/FilterHandler.php b/src/Monolog/Handler/FilterHandler.php index 2a0f7fd..da0634a 100644 --- a/src/Monolog/Handler/FilterHandler.php +++ b/src/Monolog/Handler/FilterHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -21,8 +21,10 @@ use Monolog\Logger; * @author Hennadiy Verkh * @author Jordi Boggiano <j.boggiano@seld.be> */ -class FilterHandler extends AbstractHandler +class FilterHandler extends Handler implements ProcessableHandlerInterface { + use ProcessableHandlerTrait; + /** * Handler or factory callable($record, $this) * @@ -64,7 +66,7 @@ class FilterHandler extends AbstractHandler /** * @return array */ - public function getAcceptedLevels() + public function getAcceptedLevels(): array { return array_flip($this->acceptedLevels); } @@ -90,7 +92,7 @@ class FilterHandler extends AbstractHandler /** * {@inheritdoc} */ - public function isHandling(array $record) + public function isHandling(array $record): bool { return isset($this->acceptedLevels[$record['level']]); } @@ -98,7 +100,7 @@ class FilterHandler extends AbstractHandler /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; @@ -113,9 +115,7 @@ class FilterHandler extends AbstractHandler } if ($this->processors) { - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } + $record = $this->processRecord($record); } $this->handler->handle($record); @@ -128,7 +128,7 @@ class FilterHandler extends AbstractHandler */ public function handleBatch(array $records) { - $filtered = array(); + $filtered = []; foreach ($records as $record) { if ($this->isHandling($record)) { $filtered[] = $record; diff --git a/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php index c3e42ef..f9cab61 100644 --- a/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php +++ b/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php b/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php index 2a2a64d..63a14cb 100644 --- a/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php +++ b/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -42,7 +42,7 @@ class ChannelLevelActivationStrategy implements ActivationStrategyInterface * @param int $defaultActionLevel The default action level to be used if the record's category doesn't match any * @param array $channelToActionLevel An array that maps channel names to action levels. */ - public function __construct($defaultActionLevel, $channelToActionLevel = array()) + public function __construct($defaultActionLevel, $channelToActionLevel = []) { $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel); $this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel); diff --git a/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php b/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php index 6e63085..d0ebd84 100644 --- a/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php +++ b/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Handler/FingersCrossedHandler.php b/src/Monolog/Handler/FingersCrossedHandler.php index d1dcaac..f0151d1 100644 --- a/src/Monolog/Handler/FingersCrossedHandler.php +++ b/src/Monolog/Handler/FingersCrossedHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -27,13 +27,15 @@ use Monolog\Logger; * * @author Jordi Boggiano <j.boggiano@seld.be> */ -class FingersCrossedHandler extends AbstractHandler +class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface { + use ProcessableHandlerTrait; + protected $handler; protected $activationStrategy; protected $buffering = true; protected $bufferSize; - protected $buffer = array(); + protected $buffer = []; protected $stopBuffering; protected $passthruLevel; @@ -74,7 +76,7 @@ class FingersCrossedHandler extends AbstractHandler /** * {@inheritdoc} */ - public function isHandling(array $record) + public function isHandling(array $record): bool { return true; } @@ -96,18 +98,16 @@ class FingersCrossedHandler extends AbstractHandler } } $this->handler->handleBatch($this->buffer); - $this->buffer = array(); + $this->buffer = []; } /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if ($this->processors) { - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } + $record = $this->processRecord($record); } if ($this->buffering) { @@ -137,7 +137,7 @@ class FingersCrossedHandler extends AbstractHandler }); if (count($this->buffer) > 0) { $this->handler->handleBatch($this->buffer); - $this->buffer = array(); + $this->buffer = []; } } } @@ -157,7 +157,7 @@ class FingersCrossedHandler extends AbstractHandler */ public function clear() { - $this->buffer = array(); + $this->buffer = []; $this->reset(); } } diff --git a/src/Monolog/Handler/FirePHPHandler.php b/src/Monolog/Handler/FirePHPHandler.php index fee4795..42c78f6 100644 --- a/src/Monolog/Handler/FirePHPHandler.php +++ b/src/Monolog/Handler/FirePHPHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Formatter\WildfireFormatter; +use Monolog\Formatter\FormatterInterface; /** * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. @@ -64,7 +65,7 @@ class FirePHPHandler extends AbstractProcessingHandler { $header = sprintf('%s-%s', self::HEADER_PREFIX, join('-', $meta)); - return array($header => $message); + return [$header => $message]; } /** @@ -79,7 +80,7 @@ class FirePHPHandler extends AbstractProcessingHandler // Wildfire is extensible to support multiple protocols & plugins in a single request, // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake. return $this->createHeader( - array(1, 1, 1, self::$messageIndex++), + [1, 1, 1, self::$messageIndex++], $record['formatted'] ); } @@ -87,7 +88,7 @@ class FirePHPHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new WildfireFormatter(); } @@ -103,9 +104,9 @@ class FirePHPHandler extends AbstractProcessingHandler { // Initial payload consists of required headers for Wildfire return array_merge( - $this->createHeader(array('Protocol', 1), self::PROTOCOL_URI), - $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI), - $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI) + $this->createHeader(['Protocol', 1], self::PROTOCOL_URI), + $this->createHeader([1, 'Structure', 1], self::STRUCTURE_URI), + $this->createHeader([1, 'Plugin', 1], self::PLUGIN_URI) ); } diff --git a/src/Monolog/Handler/FleepHookHandler.php b/src/Monolog/Handler/FleepHookHandler.php index c43c013..748100b 100644 --- a/src/Monolog/Handler/FleepHookHandler.php +++ b/src/Monolog/Handler/FleepHookHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,6 +11,7 @@ namespace Monolog\Handler; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; use Monolog\Logger; @@ -63,7 +64,7 @@ class FleepHookHandler extends SocketHandler * * @return LineFormatter */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(null, null, true, true); } @@ -117,9 +118,9 @@ class FleepHookHandler extends SocketHandler */ private function buildContent($record) { - $dataArray = array( + $dataArray = [ 'message' => $record['formatted'], - ); + ]; return http_build_query($dataArray); } diff --git a/src/Monolog/Handler/FlowdockHandler.php b/src/Monolog/Handler/FlowdockHandler.php index dd9a361..b3fc9b4 100644 --- a/src/Monolog/Handler/FlowdockHandler.php +++ b/src/Monolog/Handler/FlowdockHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -53,7 +53,7 @@ class FlowdockHandler extends SocketHandler /** * {@inheritdoc} */ - public function setFormatter(FormatterInterface $formatter) + public function setFormatter(FormatterInterface $formatter): HandlerInterface { if (!$formatter instanceof FlowdockFormatter) { throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); @@ -67,7 +67,7 @@ class FlowdockHandler extends SocketHandler * * @return FormatterInterface */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); } diff --git a/src/Monolog/Handler/FormattableHandlerInterface.php b/src/Monolog/Handler/FormattableHandlerInterface.php new file mode 100644 index 0000000..fc1693c --- /dev/null +++ b/src/Monolog/Handler/FormattableHandlerInterface.php @@ -0,0 +1,37 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; + +/** + * Interface to describe loggers that have a formatter + * + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +interface FormattableHandlerInterface +{ + /** + * Sets the formatter. + * + * @param FormatterInterface $formatter + * @return HandlerInterface self + */ + public function setFormatter(FormatterInterface $formatter): HandlerInterface; + + /** + * Gets the formatter. + * + * @return FormatterInterface + */ + public function getFormatter(): FormatterInterface; +} diff --git a/src/Monolog/Handler/FormattableHandlerTrait.php b/src/Monolog/Handler/FormattableHandlerTrait.php new file mode 100644 index 0000000..2b7e56f --- /dev/null +++ b/src/Monolog/Handler/FormattableHandlerTrait.php @@ -0,0 +1,60 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\LineFormatter; + +/** + * Helper trait for implementing FormattableInterface + * + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +trait FormattableHandlerTrait +{ + /** + * @var FormatterInterface + */ + protected $formatter; + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter): HandlerInterface + { + $this->formatter = $formatter; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFormatter(): FormatterInterface + { + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + + return $this->formatter; + } + + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter(): FormatterInterface + { + return new LineFormatter(); + } +} diff --git a/src/Monolog/Handler/GelfHandler.php b/src/Monolog/Handler/GelfHandler.php index d3847d8..4a6c0f8 100644 --- a/src/Monolog/Handler/GelfHandler.php +++ b/src/Monolog/Handler/GelfHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,12 +11,10 @@ namespace Monolog\Handler; -use Gelf\IMessagePublisher; use Gelf\PublisherInterface; -use Gelf\Publisher; -use InvalidArgumentException; use Monolog\Logger; use Monolog\Formatter\GelfMessageFormatter; +use Monolog\Formatter\FormatterInterface; /** * Handler to send messages to a Graylog2 (http://www.graylog2.org) server @@ -32,18 +30,14 @@ class GelfHandler extends AbstractProcessingHandler protected $publisher; /** - * @param PublisherInterface|IMessagePublisher|Publisher $publisher a publisher object - * @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 PublisherInterface $publisher a publisher object + * @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($publisher, $level = Logger::DEBUG, $bubble = true) + public function __construct(PublisherInterface $publisher, $level = Logger::DEBUG, $bubble = true) { parent::__construct($level, $bubble); - if (!$publisher instanceof Publisher && !$publisher instanceof IMessagePublisher && !$publisher instanceof PublisherInterface) { - throw new InvalidArgumentException('Invalid publisher, expected a Gelf\Publisher, Gelf\IMessagePublisher or Gelf\PublisherInterface instance'); - } - $this->publisher = $publisher; } @@ -66,7 +60,7 @@ class GelfHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new GelfMessageFormatter(); } diff --git a/src/Monolog/Handler/GroupHandler.php b/src/Monolog/Handler/GroupHandler.php index 663f5a9..ef1485f 100644 --- a/src/Monolog/Handler/GroupHandler.php +++ b/src/Monolog/Handler/GroupHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -18,8 +18,10 @@ use Monolog\Formatter\FormatterInterface; * * @author Lenar Lõhmus <lenar@city.ee> */ -class GroupHandler extends AbstractHandler +class GroupHandler extends Handler implements ProcessableHandlerInterface { + use ProcessableHandlerTrait; + protected $handlers; /** @@ -41,7 +43,7 @@ class GroupHandler extends AbstractHandler /** * {@inheritdoc} */ - public function isHandling(array $record) + public function isHandling(array $record): bool { foreach ($this->handlers as $handler) { if ($handler->isHandling($record)) { @@ -55,12 +57,10 @@ class GroupHandler extends AbstractHandler /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if ($this->processors) { - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } + $record = $this->processRecord($record); } foreach ($this->handlers as $handler) { @@ -76,7 +76,7 @@ class GroupHandler extends AbstractHandler public function handleBatch(array $records) { if ($this->processors) { - $processed = array(); + $processed = []; foreach ($records as $record) { foreach ($this->processors as $processor) { $processed[] = call_user_func($processor, $record); diff --git a/src/Monolog/Handler/Handler.php b/src/Monolog/Handler/Handler.php new file mode 100644 index 0000000..347e7b7 --- /dev/null +++ b/src/Monolog/Handler/Handler.php @@ -0,0 +1,53 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Base Handler class providing basic close() support as well as handleBatch + * + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +abstract class Handler implements HandlerInterface +{ + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($records as $record) { + $this->handle($record); + } + } + + /** + * {@inheritdoc} + */ + public function close() + { + } + + public function __destruct() + { + try { + $this->close(); + } catch (\Throwable $e) { + // do nothing + } + } + + public function __sleep() + { + $this->close(); + + return array_keys(get_object_vars($this)); + } +} diff --git a/src/Monolog/Handler/HandlerInterface.php b/src/Monolog/Handler/HandlerInterface.php index d920c4b..472fd31 100644 --- a/src/Monolog/Handler/HandlerInterface.php +++ b/src/Monolog/Handler/HandlerInterface.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,8 +11,6 @@ namespace Monolog\Handler; -use Monolog\Formatter\FormatterInterface; - /** * Interface that all Monolog Handlers must implement * @@ -33,7 +31,7 @@ interface HandlerInterface * * @return Boolean */ - public function isHandling(array $record); + public function isHandling(array $record): bool; /** * Handles a record. @@ -49,7 +47,7 @@ interface HandlerInterface * @return Boolean 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); + public function handle(array $record): bool; /** * Handles a set of records at once. @@ -59,32 +57,12 @@ interface HandlerInterface public function handleBatch(array $records); /** - * Adds a processor in the stack. - * - * @param callable $callback - * @return self - */ - public function pushProcessor($callback); - - /** - * Removes the processor on top of the stack and returns it. - * - * @return callable - */ - public function popProcessor(); - - /** - * Sets the formatter. + * Closes the handler. * - * @param FormatterInterface $formatter - * @return self - */ - public function setFormatter(FormatterInterface $formatter); - - /** - * Gets the formatter. + * This will be called automatically when the object is destroyed if you extend Monolog\Handler\Handler * - * @return FormatterInterface + * Implementations have to be idempotent (i.e. it should be possible to call close several times without breakage) + * and ideally handlers should be able to reopen themselves on handle() after they have been closed. */ - public function getFormatter(); + public function close(); } diff --git a/src/Monolog/Handler/HandlerWrapper.php b/src/Monolog/Handler/HandlerWrapper.php index 56bc270..5eacf00 100644 --- a/src/Monolog/Handler/HandlerWrapper.php +++ b/src/Monolog/Handler/HandlerWrapper.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -28,7 +28,7 @@ use Monolog\Formatter\FormatterInterface; * * @author Alexey Karapetov <alexey@karapetov.com> */ -class HandlerWrapper implements HandlerInterface +class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, FormattableHandlerInterface { /** * @var HandlerInterface @@ -47,7 +47,7 @@ class HandlerWrapper implements HandlerInterface /** * {@inheritdoc} */ - public function isHandling(array $record) + public function isHandling(array $record): bool { return $this->handler->isHandling($record); } @@ -55,7 +55,7 @@ class HandlerWrapper implements HandlerInterface /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { return $this->handler->handle($record); } @@ -71,36 +71,58 @@ class HandlerWrapper implements HandlerInterface /** * {@inheritdoc} */ - public function pushProcessor($callback) + public function close() { - $this->handler->pushProcessor($callback); + return $this->handler->close(); + } - return $this; + /** + * {@inheritdoc} + */ + public function pushProcessor(callable $callback): HandlerInterface + { + if ($this->handler instanceof ProcessableHandlerInterface) { + $this->handler->pushProcessor($callback); + + return $this; + } + + throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class); } /** * {@inheritdoc} */ - public function popProcessor() + public function popProcessor(): callable { - return $this->handler->popProcessor(); + if ($this->handler instanceof ProcessableHandlerInterface) { + return $this->handler->popProcessor(); + } + + throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class); } /** * {@inheritdoc} */ - public function setFormatter(FormatterInterface $formatter) + public function setFormatter(FormatterInterface $formatter): HandlerInterface { - $this->handler->setFormatter($formatter); + if ($this->handler instanceof FormattableHandlerInterface) { + $this->handler->setFormatter($formatter); + } - return $this; + throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class); } /** * {@inheritdoc} */ - public function getFormatter() + public function getFormatter(): FormatterInterface { - return $this->handler->getFormatter(); + if ($this->handler instanceof FormattableHandlerInterface) { + return $this->handler->getFormatter($formatter); + } + + throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class); } } diff --git a/src/Monolog/Handler/HipChatHandler.php b/src/Monolog/Handler/HipChatHandler.php index 73049f3..98441f3 100644 --- a/src/Monolog/Handler/HipChatHandler.php +++ b/src/Monolog/Handler/HipChatHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -16,12 +16,13 @@ use Monolog\Logger; /** * Sends notifications through the hipchat api to a hipchat room * + * This handler only supports the API v2 + * * Notes: * API token - HipChat API token * Room - HipChat Room Id or name, where messages are sent * Name - Name used to send the message (from) * notify - Should the message trigger a notification in the clients - * version - The API version to use (HipChatHandler::API_V1 | HipChatHandler::API_V2) * * @author Rafael Dohms <rafael@doh.ms> * @see https://www.hipchat.com/docs/api @@ -29,16 +30,6 @@ use Monolog\Logger; class HipChatHandler extends SocketHandler { /** - * Use API version 1 - */ - const API_V1 = 'v1'; - - /** - * Use API version v2 - */ - const API_V2 = 'v2'; - - /** * The maximum allowed length for the name used in the "from" field. */ const MAXIMUM_NAME_LENGTH = 15; @@ -79,28 +70,18 @@ class HipChatHandler extends SocketHandler private $host; /** - * @var string + * @param string $token HipChat API Token + * @param string $room The room that should be alerted of the message (Id or Name) + * @param string $name Name used in the "from" field. + * @param bool $notify Trigger a notification in clients 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 + * @param bool $useSSL Whether to connect via SSL. + * @param string $format The format of the messages (default to text, can be set to html if you have html in the messages) + * @param string $host The HipChat server hostname. */ - private $version; - - /** - * @param string $token HipChat API Token - * @param string $room The room that should be alerted of the message (Id or Name) - * @param string $name Name used in the "from" field. - * @param bool $notify Trigger a notification in clients 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 - * @param bool $useSSL Whether to connect via SSL. - * @param string $format The format of the messages (default to text, can be set to html if you have html in the messages) - * @param string $host The HipChat server hostname. - * @param string $version The HipChat API version (default HipChatHandler::API_V1) - */ - public function __construct($token, $room, $name = 'Monolog', $notify = false, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $format = 'text', $host = 'api.hipchat.com', $version = self::API_V1) + public function __construct($token, $room, $name = 'Monolog', $notify = false, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $format = 'text', $host = 'api.hipchat.com') { - if ($version == self::API_V1 && !$this->validateStringLength($name, static::MAXIMUM_NAME_LENGTH)) { - throw new \InvalidArgumentException('The supplied name is too long. HipChat\'s v1 API supports names up to 15 UTF-8 characters.'); - } - $connectionString = $useSSL ? 'ssl://'.$host.':443' : $host.':80'; parent::__construct($connectionString, $level, $bubble); @@ -110,7 +91,6 @@ class HipChatHandler extends SocketHandler $this->room = $room; $this->format = $format; $this->host = $host; - $this->version = $version; } /** @@ -134,14 +114,12 @@ class HipChatHandler extends SocketHandler */ private function buildContent($record) { - $dataArray = array( - 'notify' => $this->version == self::API_V1 ? - ($this->notify ? 1 : 0) : - ($this->notify ? 'true' : 'false'), + $dataArray = [ + 'notify' => $this->notify ? 'true' : 'false', 'message' => $record['formatted'], 'message_format' => $this->format, 'color' => $this->getAlertColor($record['level']), - ); + ]; if (!$this->validateStringLength($dataArray['message'], static::MAXIMUM_MESSAGE_LENGTH)) { if (function_exists('mb_substr')) { @@ -151,14 +129,9 @@ class HipChatHandler extends SocketHandler } } - // if we are using the legacy API then we need to send some additional information - if ($this->version == self::API_V1) { - $dataArray['room_id'] = $this->room; - } - // append the sender name if it is set // always append it if we use the v1 api (it is required in v1) - if ($this->version == self::API_V1 || $this->name !== null) { + if ($this->name !== null) { $dataArray['from'] = (string) $this->name; } @@ -173,13 +146,9 @@ class HipChatHandler extends SocketHandler */ private function buildHeader($content) { - if ($this->version == self::API_V1) { - $header = "POST /v1/rooms/message?format=json&auth_token={$this->token} HTTP/1.1\r\n"; - } else { - // needed for rooms with special (spaces, etc) characters in the name - $room = rawurlencode($this->room); - $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n"; - } + // needed for rooms with special (spaces, etc) characters in the name + $room = rawurlencode($this->room); + $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n"; $header .= "Host: {$this->host}\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; @@ -259,9 +228,9 @@ class HipChatHandler extends SocketHandler private function combineRecords($records) { $batchRecord = null; - $batchRecords = array(); - $messages = array(); - $formattedMessages = array(); + $batchRecords = []; + $messages = []; + $formattedMessages = []; $level = 0; $levelName = null; $datetime = null; @@ -283,12 +252,12 @@ class HipChatHandler extends SocketHandler $formattedMessages[] = $this->getFormatter()->format($record); $formattedMessageStr = implode('', $formattedMessages); - $batchRecord = array( + $batchRecord = [ 'message' => $messageStr, 'formatted' => $formattedMessageStr, - 'context' => array(), - 'extra' => array(), - ); + 'context' => [], + 'extra' => [], + ]; if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) { // Pop the last message and implode the remaining messages @@ -298,8 +267,8 @@ class HipChatHandler extends SocketHandler $batchRecord['formatted'] = implode('', $formattedMessages); $batchRecords[] = $batchRecord; - $messages = array($lastMessage); - $formattedMessages = array($lastFormattedMessage); + $messages = [$lastMessage]; + $formattedMessages = [$lastFormattedMessage]; $batchRecord = null; } @@ -313,11 +282,11 @@ class HipChatHandler extends SocketHandler foreach ($batchRecords as &$batchRecord) { $batchRecord = array_merge( $batchRecord, - array( + [ 'level' => $level, 'level_name' => $levelName, 'datetime' => $datetime, - ) + ] ); } diff --git a/src/Monolog/Handler/IFTTTHandler.php b/src/Monolog/Handler/IFTTTHandler.php index d60a3c8..46792ee 100644 --- a/src/Monolog/Handler/IFTTTHandler.php +++ b/src/Monolog/Handler/IFTTTHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -48,11 +48,11 @@ class IFTTTHandler extends AbstractProcessingHandler */ public function write(array $record) { - $postData = array( + $postData = [ "value1" => $record["channel"], "value2" => $record["level_name"], "value3" => $record["message"], - ); + ]; $postString = json_encode($postData); $ch = curl_init(); @@ -60,9 +60,9 @@ class IFTTTHandler extends AbstractProcessingHandler curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postString); - curl_setopt($ch, CURLOPT_HTTPHEADER, array( + curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", - )); + ]); Curl\Util::execute($ch); } diff --git a/src/Monolog/Handler/LogEntriesHandler.php b/src/Monolog/Handler/LogEntriesHandler.php index 494c605..c74b9d2 100644 --- a/src/Monolog/Handler/LogEntriesHandler.php +++ b/src/Monolog/Handler/LogEntriesHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Handler/LogglyHandler.php b/src/Monolog/Handler/LogglyHandler.php index bcd62e1..544e7c7 100644 --- a/src/Monolog/Handler/LogglyHandler.php +++ b/src/Monolog/Handler/LogglyHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LogglyFormatter; /** @@ -29,7 +30,7 @@ class LogglyHandler extends AbstractProcessingHandler protected $token; - protected $tag = array(); + protected $tag = []; public function __construct($token, $level = Logger::DEBUG, $bubble = true) { @@ -44,14 +45,14 @@ class LogglyHandler extends AbstractProcessingHandler public function setTag($tag) { - $tag = !empty($tag) ? $tag : array(); - $this->tag = is_array($tag) ? $tag : array($tag); + $tag = !empty($tag) ? $tag : []; + $this->tag = is_array($tag) ? $tag : [$tag]; } public function addTag($tag) { if (!empty($tag)) { - $tag = is_array($tag) ? $tag : array($tag); + $tag = is_array($tag) ? $tag : [$tag]; $this->tag = array_unique(array_merge($this->tag, $tag)); } } @@ -78,7 +79,7 @@ class LogglyHandler extends AbstractProcessingHandler { $url = sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token); - $headers = array('Content-Type: application/json'); + $headers = ['Content-Type: application/json']; if (!empty($this->tag)) { $headers[] = 'X-LOGGLY-TAG: '.implode(',', $this->tag); @@ -95,7 +96,7 @@ class LogglyHandler extends AbstractProcessingHandler Curl\Util::execute($ch); } - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LogglyFormatter(); } diff --git a/src/Monolog/Handler/LogmaticHandler.php b/src/Monolog/Handler/LogmaticHandler.php new file mode 100644 index 0000000..70c4d6a --- /dev/null +++ b/src/Monolog/Handler/LogmaticHandler.php @@ -0,0 +1,88 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\LogmaticFormatter; + +/** + * @author Julien Breux <julien.breux@gmail.com> + */ +class LogmaticHandler extends SocketHandler +{ + /** + * @var string + */ + protected $logToken; + + /** + * @var string + */ + protected $hostname; + + /** + * @var string + */ + protected $appname; + + /** + * @param string $token Log token supplied by Logmatic. + * @param string $hostname Host name supplied by Logmatic. + * @param string $appname Application name supplied by Logmatic. + * @param bool $useSSL Whether or not SSL encryption should be used. + * @param int|string $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(string $token, string $hostname = '', string $appname = '', bool $useSSL = true, $level = Logger::DEBUG, bool $bubble = true) + { + if ($useSSL && !extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP extension is required to use SSL encrypted connection for LogmaticHandler'); + } + + $endpoint = $useSSL ? 'ssl://api.logmatic.io:10515' : 'api.logmatic.io:10514'; + $endpoint .= '/v1/'; + + parent::__construct($endpoint, $level, $bubble); + + $this->logToken = $token; + $this->hostname = $hostname; + $this->appname = $appname; + } + + /** + * {@inheritdoc} + */ + protected function generateDataStream($record): string + { + return $this->logToken . ' ' . $record['formatted']; + } + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter(): FormatterInterface + { + $formatter = new LogmaticFormatter(); + + if (!empty($this->hostname)) { + $formatter->setHostname($this->hostname); + } + if (!empty($this->appname)) { + $formatter->setAppname($this->appname); + } + + return $formatter; + } +} diff --git a/src/Monolog/Handler/MailHandler.php b/src/Monolog/Handler/MailHandler.php index 9e23283..634fbc1 100644 --- a/src/Monolog/Handler/MailHandler.php +++ b/src/Monolog/Handler/MailHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,6 +11,9 @@ namespace Monolog\Handler; +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\HtmlFormatter; + /** * Base class for all mail handlers * @@ -23,7 +26,7 @@ abstract class MailHandler extends AbstractProcessingHandler */ public function handleBatch(array $records) { - $messages = array(); + $messages = []; foreach ($records as $record) { if ($record['level'] < $this->level) { @@ -43,14 +46,14 @@ abstract class MailHandler extends AbstractProcessingHandler * @param string $content formatted email body to be sent * @param array $records the array of log records that formed this content */ - abstract protected function send($content, array $records); + abstract protected function send(string $content, array $records); /** * {@inheritdoc} */ protected function write(array $record) { - $this->send((string) $record['formatted'], array($record)); + $this->send((string) $record['formatted'], [$record]); } protected function getHighestRecord(array $records) @@ -64,4 +67,19 @@ abstract class MailHandler extends AbstractProcessingHandler return $highestRecord; } + + protected function isHtmlBody($body) + { + return substr($body, 0, 1) === '<'; + } + + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter(): FormatterInterface + { + return new HtmlFormatter(); + } } diff --git a/src/Monolog/Handler/MandrillHandler.php b/src/Monolog/Handler/MandrillHandler.php index ab95924..68ec568 100644 --- a/src/Monolog/Handler/MandrillHandler.php +++ b/src/Monolog/Handler/MandrillHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -48,8 +48,13 @@ class MandrillHandler extends MailHandler */ protected function send($content, array $records) { + $mime = null; + if ($this->isHtmlBody($content)) { + $mime = 'text/html'; + } + $message = clone $this->message; - $message->setBody($content); + $message->setBody($content, $mime); $message->setDate(time()); $ch = curl_init(); @@ -57,11 +62,11 @@ class MandrillHandler extends MailHandler curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array( + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'key' => $this->apiKey, 'raw_message' => (string) $message, 'async' => false, - ))); + ])); Curl\Util::execute($ch); } diff --git a/src/Monolog/Handler/MissingExtensionException.php b/src/Monolog/Handler/MissingExtensionException.php index 4724a7e..1554b34 100644 --- a/src/Monolog/Handler/MissingExtensionException.php +++ b/src/Monolog/Handler/MissingExtensionException.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Handler/MongoDBHandler.php b/src/Monolog/Handler/MongoDBHandler.php index 56fe755..f302d31 100644 --- a/src/Monolog/Handler/MongoDBHandler.php +++ b/src/Monolog/Handler/MongoDBHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,49 +11,75 @@ namespace Monolog\Handler; +use MongoDB\Driver\BulkWrite; +use MongoDB\Driver\Manager; +use MongoDB\Client; use Monolog\Logger; -use Monolog\Formatter\NormalizerFormatter; +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\MongoDBFormatter; /** * Logs to a MongoDB database. * - * usage example: + * Usage example: * - * $log = new Logger('application'); - * $mongodb = new MongoDBHandler(new \Mongo("mongodb://localhost:27017"), "logs", "prod"); + * $log = new \Monolog\Logger('application'); + * $client = new \MongoDB\Client('mongodb://localhost:27017'); + * $mongodb = new \Monolog\Handler\MongoDBHandler($client, 'logs', 'prod'); * $log->pushHandler($mongodb); * - * @author Thomas Tourlourat <thomas@tourlourat.com> + * The above examples uses the MongoDB PHP library's client class; however, the + * MongoDB\Driver\Manager class from ext-mongodb is also supported. */ class MongoDBHandler extends AbstractProcessingHandler { - protected $mongoCollection; + private $collection; + private $manager; + private $namespace; - public function __construct($mongo, $database, $collection, $level = Logger::DEBUG, $bubble = true) + /** + * Constructor. + * + * @param Client|Manager $mongodb MongoDB library or driver client + * @param string $database Database name + * @param string $collection Collection name + * @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 + */ + public function __construct($mongodb, $database, $collection, $level = Logger::DEBUG, $bubble = true) { - if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo || $mongo instanceof \MongoDB\Client)) { - throw new \InvalidArgumentException('MongoClient, Mongo or MongoDB\Client instance required'); + if (!($mongodb instanceof Client || $mongodb instanceof Manager)) { + throw new \InvalidArgumentException('MongoDB\Client or MongoDB\Driver\Manager instance required'); } - $this->mongoCollection = $mongo->selectCollection($database, $collection); + if ($mongodb instanceof Client) { + $this->collection = $mongodb->selectCollection($database, $collection); + } else { + $this->manager = $mongodb; + $this->namespace = $database . '.' . $collection; + } parent::__construct($level, $bubble); } protected function write(array $record) { - if ($this->mongoCollection instanceof \MongoDB\Collection) { - $this->mongoCollection->insertOne($record["formatted"]); - } else { - $this->mongoCollection->save($record["formatted"]); + if (isset($this->collection)) { + $this->collection->insertOne($record['formatted']); + } + + if (isset($this->manager, $this->namespace)) { + $bulk = new BulkWrite; + $bulk->insert($record["formatted"]); + $this->manager->executeBulkWrite($this->namespace, $bulk); } } /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { - return new NormalizerFormatter(); + return new MongoDBFormatter; } } diff --git a/src/Monolog/Handler/NativeMailerHandler.php b/src/Monolog/Handler/NativeMailerHandler.php index d7807fd..b597761 100644 --- a/src/Monolog/Handler/NativeMailerHandler.php +++ b/src/Monolog/Handler/NativeMailerHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -38,13 +38,13 @@ class NativeMailerHandler extends MailHandler * Optional headers for the message * @var array */ - protected $headers = array(); + protected $headers = []; /** * Optional parameters for the message * @var array */ - protected $parameters = array(); + protected $parameters = []; /** * The wordwrap length for the message @@ -56,7 +56,7 @@ class NativeMailerHandler extends MailHandler * The Content-type for the message * @var string */ - protected $contentType = 'text/plain'; + protected $contentType; /** * The encoding for the message @@ -75,7 +75,7 @@ class NativeMailerHandler extends MailHandler public function __construct($to, $subject, $from, $level = Logger::ERROR, $bubble = true, $maxColumnWidth = 70) { parent::__construct($level, $bubble); - $this->to = is_array($to) ? $to : array($to); + $this->to = (array) $to; $this->subject = $subject; $this->addHeader(sprintf('From: %s', $from)); $this->maxColumnWidth = $maxColumnWidth; @@ -115,12 +115,17 @@ class NativeMailerHandler extends MailHandler /** * {@inheritdoc} */ - protected function send($content, array $records) + protected function send(string $content, array $records) { - $content = wordwrap($content, $this->maxColumnWidth); + $contentType = $this->getContentType() ?: ($this->isHtmlBody($content) ? 'text/html' : 'text/plain'); + + if ($contentType !== 'text/html') { + $content = wordwrap($content, $this->maxColumnWidth); + } + $headers = ltrim(implode("\r\n", $this->headers) . "\r\n", "\r\n"); - $headers .= 'Content-type: ' . $this->getContentType() . '; charset=' . $this->getEncoding() . "\r\n"; - if ($this->getContentType() == 'text/html' && false === strpos($headers, 'MIME-Version:')) { + $headers .= 'Content-type: ' . $contentType . '; charset=' . $this->getEncoding() . "\r\n"; + if ($contentType === 'text/html' && false === strpos($headers, 'MIME-Version:')) { $headers .= 'MIME-Version: 1.0' . "\r\n"; } diff --git a/src/Monolog/Handler/NewRelicHandler.php b/src/Monolog/Handler/NewRelicHandler.php index 6718e9e..fb03778 100644 --- a/src/Monolog/Handler/NewRelicHandler.php +++ b/src/Monolog/Handler/NewRelicHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,6 +13,7 @@ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\NormalizerFormatter; +use Monolog\Formatter\FormatterInterface; /** * Class to record a log on a NewRelic application. @@ -195,7 +196,7 @@ class NewRelicHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter(); } diff --git a/src/Monolog/Handler/NullHandler.php b/src/Monolog/Handler/NullHandler.php index 4b84588..93678e8 100644 --- a/src/Monolog/Handler/NullHandler.php +++ b/src/Monolog/Handler/NullHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -21,20 +21,30 @@ use Monolog\Logger; * * @author Jordi Boggiano <j.boggiano@seld.be> */ -class NullHandler extends AbstractHandler +class NullHandler extends Handler { + private $level; + /** * @param int $level The minimum logging level at which this handler will be triggered */ - public function __construct($level = Logger::DEBUG) + public function __construct(int $level = Logger::DEBUG) + { + $this->level = $level; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record): bool { - parent::__construct($level, false); + return $record['level'] >= $this->level; } /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if ($record['level'] < $this->level) { return false; diff --git a/src/Monolog/Handler/PHPConsoleHandler.php b/src/Monolog/Handler/PHPConsoleHandler.php index 1f2076a..7807a6f 100644 --- a/src/Monolog/Handler/PHPConsoleHandler.php +++ b/src/Monolog/Handler/PHPConsoleHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,9 +13,10 @@ namespace Monolog\Handler; use Exception; use Monolog\Formatter\LineFormatter; +use Monolog\Formatter\FormatterInterface; use Monolog\Logger; use PhpConsole\Connector; -use PhpConsole\Handler; +use PhpConsole\Handler as VendorPhpConsoleHandler; use PhpConsole\Helper; /** @@ -39,10 +40,10 @@ use PhpConsole\Helper; */ class PHPConsoleHandler extends AbstractProcessingHandler { - private $options = array( + private $options = [ 'enabled' => true, // bool Is PHP Console server enabled - 'classesPartialsTraceIgnore' => array('Monolog\\'), // array Hide calls of classes started with... - 'debugTagsKeysInContext' => array(0, 'tag'), // bool Is PHP Console server enabled + 'classesPartialsTraceIgnore' => ['Monolog\\'], // array Hide calls of classes started with... + 'debugTagsKeysInContext' => [0, 'tag'], // bool Is PHP Console server enabled 'useOwnErrorsHandler' => false, // bool Enable errors handling 'useOwnExceptionsHandler' => false, // bool Enable exceptions handling 'sourcesBasePath' => null, // string Base path of all project sources to strip in errors source paths @@ -51,7 +52,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler 'headersLimit' => null, // int|null Set headers size limit for your web-server 'password' => null, // string|null Protect PHP Console connection by password 'enableSslOnlyMode' => false, // bool Force connection by SSL for clients with PHP Console installed - 'ipMasks' => array(), // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1') + 'ipMasks' => [], // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1') 'enableEvalListener' => false, // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required) 'dumperDetectCallbacks' => false, // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings 'dumperLevelLimit' => 5, // int Maximum dumped vars array or object nested dump level @@ -60,7 +61,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler 'dumperDumpSizeLimit' => 500000, // int Maximum approximate size of dumped vars result formatted in JSON 'detectDumpTraceAndSource' => false, // bool Autodetect and append trace data to debug 'dataStorage' => null, // PhpConsole\Storage|null Fixes problem with custom $_SESSION handler(see http://goo.gl/Ne8juJ) - ); + ]; /** @var Connector */ private $connector; @@ -72,7 +73,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler * @param bool $bubble * @throws Exception */ - public function __construct(array $options = array(), Connector $connector = null, $level = Logger::DEBUG, $bubble = true) + public function __construct(array $options = [], Connector $connector = null, $level = Logger::DEBUG, $bubble = true) { if (!class_exists('PhpConsole\Connector')) { throw new Exception('PHP Console library not found. See https://github.com/barbushin/php-console#installation'); @@ -107,7 +108,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler if ($this->options['enabled'] && $connector->isActiveClient()) { if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) { - $handler = Handler::getInstance(); + $handler = VendorPhpConsoleHandler::getInstance(); $handler->setHandleErrors($this->options['useOwnErrorsHandler']); $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']); $handler->start(); @@ -157,7 +158,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler return $this->options; } - public function handle(array $record) + public function handle(array $record): bool { if ($this->options['enabled'] && $this->connector->isActiveClient()) { return parent::handle($record); @@ -235,7 +236,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('%message%'); } diff --git a/src/Monolog/Handler/ProcessHandler.php b/src/Monolog/Handler/ProcessHandler.php new file mode 100644 index 0000000..9c135f8 --- /dev/null +++ b/src/Monolog/Handler/ProcessHandler.php @@ -0,0 +1,202 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores to STDIN of any process, specified by a command. + * + * Usage example: + * <pre> + * $log = new Logger('myLogger'); + * $log->pushHandler(new ProcessHandler('/usr/bin/php /var/www/monolog/someScript.php')); + * </pre> + * + * @author Kolja Zuelsdorf <koljaz@web.de> + */ +class ProcessHandler extends AbstractProcessingHandler +{ + /** + * Holds the process to receive data on its STDIN. + * + * @var resource + */ + private $process; + + /** + * @var string + */ + private $command; + + /** + * @var string + */ + private $cwd; + + /** + * @var array + */ + private $pipes = []; + + /** + * @var array + */ + const DESCRIPTOR_SPEC = [ + 0 => ['pipe', 'r'], // STDIN is a pipe that the child will read from + 1 => ['pipe', 'w'], // STDOUT is a pipe that the child will write to + 2 => ['pipe', 'w'], // STDERR is a pipe to catch the any errors + ]; + + /** + * @param int $command Command for the process to start. Absolute paths are recommended, + * especially if you do not use the $cwd parameter. + * @param bool|int $level The minimum logging level at which this handler will be triggered. + * @param bool|true $bubble Whether the messages that are handled can bubble up the stack or not. + * @param string|null $cwd "Current working directory" (CWD) for the process to be executed in. + * @throws \InvalidArgumentException + */ + public function __construct($command, $level = Logger::DEBUG, $bubble = true, $cwd = null) + { + if (empty($command) || is_string($command) === false) { + throw new \InvalidArgumentException('The command argument must be a non-empty string.'); + } + if ($cwd !== null && (empty($cwd) || is_string($cwd) === false)) { + throw new \InvalidArgumentException('The optional CWD argument must be a non-empty string, if any.'); + } + + parent::__construct($level, $bubble); + + $this->command = $command; + $this->cwd = $cwd; + } + + /** + * Writes the record down to the log of the implementing handler + * + * @param array $record + * @throws \UnexpectedValueException + * @return void + */ + protected function write(array $record) + { + $this->ensureProcessIsStarted(); + + $this->writeProcessInput($record['formatted']); + + $errors = $this->readProcessErrors(); + if (empty($errors) === false) { + throw new \UnexpectedValueException(sprintf('Errors while writing to process: %s', $errors)); + } + } + + /** + * Makes sure that the process is actually started, and if not, starts it, + * assigns the stream pipes, and handles startup errors, if any. + * + * @return void + */ + private function ensureProcessIsStarted() + { + if (is_resource($this->process) === false) { + $this->startProcess(); + + $this->handleStartupErrors(); + } + } + + /** + * Starts the actual process and sets all streams to non-blocking. + * + * @return void + */ + private function startProcess() + { + $this->process = proc_open($this->command, self::DESCRIPTOR_SPEC, $this->pipes, $this->cwd); + + foreach ($this->pipes as $pipe) { + stream_set_blocking($pipe, false); + } + } + + /** + * Selects the STDERR stream, handles upcoming startup errors, and throws an exception, if any. + * + * @throws \UnexpectedValueException + * @return void + */ + private function handleStartupErrors() + { + $selected = $this->selectErrorStream(); + if (false === $selected) { + throw new \UnexpectedValueException('Something went wrong while selecting a stream.'); + } + + $errors = $this->readProcessErrors(); + + if (is_resource($this->process) === false || empty($errors) === false) { + throw new \UnexpectedValueException( + sprintf('The process "%s" could not be opened: ' . $errors, $this->command) + ); + } + } + + /** + * Selects the STDERR stream. + * + * @return int|bool + */ + protected function selectErrorStream() + { + $empty = []; + $errorPipes = [$this->pipes[2]]; + + return stream_select($errorPipes, $empty, $empty, 1); + } + + /** + * Reads the errors of the process, if there are any. + * + * @codeCoverageIgnore + * @return string Empty string if there are no errors. + */ + protected function readProcessErrors() + { + return stream_get_contents($this->pipes[2]); + } + + /** + * Writes to the input stream of the opened process. + * + * @codeCoverageIgnore + * @param $string + * @return void + */ + protected function writeProcessInput($string) + { + fwrite($this->pipes[0], (string) $string); + } + + /** + * {@inheritdoc} + */ + public function close() + { + if (is_resource($this->process)) { + foreach ($this->pipes as $pipe) { + fclose($pipe); + } + proc_close($this->process); + $this->process = null; + } + } +} diff --git a/src/Monolog/Handler/ProcessableHandlerInterface.php b/src/Monolog/Handler/ProcessableHandlerInterface.php new file mode 100644 index 0000000..59ec982 --- /dev/null +++ b/src/Monolog/Handler/ProcessableHandlerInterface.php @@ -0,0 +1,36 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Interface to describe loggers that have processors + * + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +interface ProcessableHandlerInterface +{ + /** + * Adds a processor in the stack. + * + * @param callable $callback + * @return HandlerInterface self + */ + public function pushProcessor(callable $callback): HandlerInterface; + + /** + * Removes the processor on top of the stack and returns it. + * + * @throws LogicException In case the processor stack is empty + * @return callable + */ + public function popProcessor(): callable; +} diff --git a/src/Monolog/Handler/ProcessableHandlerTrait.php b/src/Monolog/Handler/ProcessableHandlerTrait.php new file mode 100644 index 0000000..d28d46b --- /dev/null +++ b/src/Monolog/Handler/ProcessableHandlerTrait.php @@ -0,0 +1,65 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Helper trait for implementing ProcessableInterface + * + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +trait ProcessableHandlerTrait +{ + /** + * @var callable[] + */ + protected $processors = []; + + /** + * {@inheritdoc} + */ + public function pushProcessor(callable $callback): HandlerInterface + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + array_unshift($this->processors, $callback); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function popProcessor(): callable + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + + return array_shift($this->processors); + } + + /** + * Processes a record. + * + * @param array $record + * @return array + */ + protected function processRecord(array $record) + { + foreach ($this->processors as $processor) { + $record = $processor($record); + } + + return $record; + } +} diff --git a/src/Monolog/Handler/PsrHandler.php b/src/Monolog/Handler/PsrHandler.php index 1ae8584..415b45f 100644 --- a/src/Monolog/Handler/PsrHandler.php +++ b/src/Monolog/Handler/PsrHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -43,7 +43,7 @@ class PsrHandler extends AbstractHandler /** * {@inheritDoc} */ - public function handle(array $record) + public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; diff --git a/src/Monolog/Handler/PushoverHandler.php b/src/Monolog/Handler/PushoverHandler.php index bba7200..b53ce6c 100644 --- a/src/Monolog/Handler/PushoverHandler.php +++ b/src/Monolog/Handler/PushoverHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -37,7 +37,7 @@ class PushoverHandler extends SocketHandler * @see https://pushover.net/api * @var array */ - private $parameterNames = array( + private $parameterNames = [ 'token' => true, 'user' => true, 'message' => true, @@ -51,18 +51,18 @@ class PushoverHandler extends SocketHandler 'retry' => true, 'expire' => true, 'callback' => true, - ); + ]; /** * Sounds the api supports by default * @see https://pushover.net/api#sounds * @var array */ - private $sounds = array( + private $sounds = [ 'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', 'persistent', 'echo', 'updown', 'none', - ); + ]; /** * @param string $token Pushover api token @@ -110,13 +110,13 @@ class PushoverHandler extends SocketHandler $timestamp = $record['datetime']->getTimestamp(); - $dataArray = array( + $dataArray = [ 'token' => $this->token, 'user' => $this->user, 'message' => $message, 'title' => $this->title, 'timestamp' => $timestamp, - ); + ]; if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) { $dataArray['priority'] = 2; diff --git a/src/Monolog/Handler/RavenHandler.php b/src/Monolog/Handler/RavenHandler.php index 9075827..db64f80 100644 --- a/src/Monolog/Handler/RavenHandler.php +++ b/src/Monolog/Handler/RavenHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -27,7 +27,7 @@ class RavenHandler extends AbstractProcessingHandler /** * Translates Monolog log levels to Raven log levels. */ - private $logLevels = array( + private $logLevels = [ Logger::DEBUG => Raven_Client::DEBUG, Logger::INFO => Raven_Client::INFO, Logger::NOTICE => Raven_Client::INFO, @@ -36,7 +36,7 @@ class RavenHandler extends AbstractProcessingHandler Logger::CRITICAL => Raven_Client::FATAL, Logger::ALERT => Raven_Client::FATAL, Logger::EMERGENCY => Raven_Client::FATAL, - ); + ]; /** * @var string should represent the current version of the calling @@ -92,7 +92,7 @@ class RavenHandler extends AbstractProcessingHandler }); // the other ones are added as a context item - $logs = array(); + $logs = []; foreach ($records as $r) { $logs[] = $this->processRecord($r); } @@ -134,9 +134,9 @@ class RavenHandler extends AbstractProcessingHandler protected function write(array $record) { $previousUserContext = false; - $options = array(); + $options = []; $options['level'] = $this->logLevels[$record['level']]; - $options['tags'] = array(); + $options['tags'] = []; if (!empty($record['extra']['tags'])) { $options['tags'] = array_merge($options['tags'], $record['extra']['tags']); unset($record['extra']['tags']); @@ -156,7 +156,7 @@ class RavenHandler extends AbstractProcessingHandler $options['logger'] = $record['channel']; } foreach ($this->getExtraParameters() as $key) { - foreach (array('extra', 'context') as $source) { + foreach (['extra', 'context'] as $source) { if (!empty($record[$source][$key])) { $options[$key] = $record[$source][$key]; unset($record[$source][$key]); @@ -183,7 +183,7 @@ class RavenHandler extends AbstractProcessingHandler $options['extra']['message'] = $record['formatted']; $this->ravenClient->captureException($record['context']['exception'], $options); } else { - $this->ravenClient->captureMessage($record['formatted'], array(), $options); + $this->ravenClient->captureMessage($record['formatted'], [], $options); } if ($previousUserContext !== false) { @@ -194,7 +194,7 @@ class RavenHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('[%channel%] %message%'); } @@ -216,7 +216,7 @@ class RavenHandler extends AbstractProcessingHandler */ protected function getExtraParameters() { - return array('checksum', 'release'); + return ['checksum', 'release']; } /** diff --git a/src/Monolog/Handler/RedisHandler.php b/src/Monolog/Handler/RedisHandler.php index 590f996..f77d4fd 100644 --- a/src/Monolog/Handler/RedisHandler.php +++ b/src/Monolog/Handler/RedisHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,6 +12,7 @@ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; +use Monolog\Formatter\FormatterInterface; use Monolog\Logger; /** @@ -90,7 +91,7 @@ class RedisHandler extends AbstractProcessingHandler /** * {@inheritDoc} */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(); } diff --git a/src/Monolog/Handler/RollbarHandler.php b/src/Monolog/Handler/RollbarHandler.php index e11d464..0a82faa 100644 --- a/src/Monolog/Handler/RollbarHandler.php +++ b/src/Monolog/Handler/RollbarHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -61,7 +61,7 @@ class RollbarHandler extends AbstractProcessingHandler $exception = $context['exception']; unset($context['exception']); - $payload = array(); + $payload = []; if (isset($context['payload'])) { $payload = $context['payload']; unset($context['payload']); @@ -69,14 +69,14 @@ class RollbarHandler extends AbstractProcessingHandler $this->rollbarNotifier->report_exception($exception, $context, $payload); } else { - $extraData = array( + $extraData = [ 'level' => $record['level'], 'channel' => $record['channel'], 'datetime' => $record['datetime']->format('U'), - ); + ]; $context = $record['context']; - $payload = array(); + $payload = []; if (isset($context['payload'])) { $payload = $context['payload']; unset($context['payload']); diff --git a/src/Monolog/Handler/RotatingFileHandler.php b/src/Monolog/Handler/RotatingFileHandler.php index 101c1dc..39e4393 100644 --- a/src/Monolog/Handler/RotatingFileHandler.php +++ b/src/Monolog/Handler/RotatingFileHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,6 +11,7 @@ namespace Monolog\Handler; +use InvalidArgumentException; use Monolog\Logger; /** @@ -47,7 +48,7 @@ class RotatingFileHandler extends StreamHandler { $this->filename = $filename; $this->maxFiles = (int) $maxFiles; - $this->nextRotation = new \DateTime('tomorrow'); + $this->nextRotation = new \DateTimeImmutable('tomorrow'); $this->filenameFormat = '{filename}-{date}'; $this->dateFormat = 'Y-m-d'; @@ -69,18 +70,16 @@ class RotatingFileHandler extends StreamHandler public function setFilenameFormat($filenameFormat, $dateFormat) { if (!preg_match('{^Y(([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) { - trigger_error( + throw new InvalidArgumentException( 'Invalid date format - format must be one of '. 'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m")'. 'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '. - 'date formats using slashes, underscores and/or dots instead of dashes.', - E_USER_DEPRECATED + 'date formats using slashes, underscores and/or dots instead of dashes.' ); } if (substr_count($filenameFormat, '{date}') === 0) { - trigger_error( - 'Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.', - E_USER_DEPRECATED + throw new InvalidArgumentException( + 'Invalid filename format - format must contain at least `{date}`, because otherwise rotating is impossible.' ); } $this->filenameFormat = $filenameFormat; @@ -114,7 +113,7 @@ class RotatingFileHandler extends StreamHandler { // update filename $this->url = $this->getTimedFilename(); - $this->nextRotation = new \DateTime('tomorrow'); + $this->nextRotation = new \DateTimeImmutable('tomorrow'); // skip GC of old logs if files are unlimited if (0 === $this->maxFiles) { @@ -136,7 +135,8 @@ class RotatingFileHandler extends StreamHandler if (is_writable($file)) { // suppress errors here as unlink() might fail if two processes // are cleaning up/rotating at the same time - set_error_handler(function ($errno, $errstr, $errfile, $errline) {}); + set_error_handler(function ($errno, $errstr, $errfile, $errline) { + }); unlink($file); restore_error_handler(); } @@ -149,8 +149,8 @@ class RotatingFileHandler extends StreamHandler { $fileInfo = pathinfo($this->filename); $timedFilename = str_replace( - array('{filename}', '{date}'), - array($fileInfo['filename'], date($this->dateFormat)), + ['{filename}', '{date}'], + [$fileInfo['filename'], date($this->dateFormat)], $fileInfo['dirname'] . '/' . $this->filenameFormat ); @@ -165,8 +165,8 @@ class RotatingFileHandler extends StreamHandler { $fileInfo = pathinfo($this->filename); $glob = str_replace( - array('{filename}', '{date}'), - array($fileInfo['filename'], '*'), + ['{filename}', '{date}'], + [$fileInfo['filename'], '*'], $fileInfo['dirname'] . '/' . $this->filenameFormat ); if (!empty($fileInfo['extension'])) { diff --git a/src/Monolog/Handler/SamplingHandler.php b/src/Monolog/Handler/SamplingHandler.php index 9509ae3..8a25cbb 100644 --- a/src/Monolog/Handler/SamplingHandler.php +++ b/src/Monolog/Handler/SamplingHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -25,8 +25,10 @@ namespace Monolog\Handler; * @author Bryan Davis <bd808@wikimedia.org> * @author Kunal Mehta <legoktm@gmail.com> */ -class SamplingHandler extends AbstractHandler +class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface { + use ProcessableHandlerTrait; + /** * @var callable|HandlerInterface $handler */ @@ -52,12 +54,12 @@ class SamplingHandler extends AbstractHandler } } - public function isHandling(array $record) + public function isHandling(array $record): bool { return $this->handler->isHandling($record); } - public function handle(array $record) + public function handle(array $record): bool { if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) { // The same logic as in FingersCrossedHandler @@ -69,9 +71,7 @@ class SamplingHandler extends AbstractHandler } if ($this->processors) { - foreach ($this->processors as $processor) { - $record = call_user_func($processor, $record); - } + $record = $this->processRecord($record); } $this->handler->handle($record); diff --git a/src/Monolog/Handler/SendGridHandler.php b/src/Monolog/Handler/SendGridHandler.php new file mode 100644 index 0000000..3a91cb4 --- /dev/null +++ b/src/Monolog/Handler/SendGridHandler.php @@ -0,0 +1,100 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * SendGridrHandler uses the SendGrid API v2 function to send Log emails, more information in https://sendgrid.com/docs/API_Reference/Web_API/mail.html + * + * @author Ricardo Fontanelli <ricardo.fontanelli@hotmail.com> + */ +class SendGridHandler extends MailHandler +{ + /** + * The SendGrid API User + * @var string + */ + protected $apiUser; + + /** + * The SendGrid API Key + * @var string + */ + protected $apiKey; + + /** + * The email addresses to which the message will be sent + * @var string + */ + protected $from; + + /** + * The email addresses to which the message will be sent + * @var array + */ + protected $to; + + /** + * The subject of the email + * @var string + */ + protected $subject; + + /** + * @param string $apiUser The SendGrid API User + * @param string $apiKey The SendGrid API Key + * @param string $from The sender of the email + * @param string|array $to The recipients of the email + * @param string $subject The subject of the mail + * @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(string $apiUser, string $apiKey, string $from, $to, string $subject, int $level = Logger::ERROR, bool $bubble = true) + { + parent::__construct($level, $bubble); + $this->apiUser = $apiUser; + $this->apiKey = $apiKey; + $this->from = $from; + $this->to = (array) $to; + $this->subject = $subject; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $message = []; + $message['api_user'] = $this->apiUser; + $message['api_key'] = $this->apiKey; + $message['from'] = $this->from; + foreach ($this->to as $recipient) { + $message['to[]'] = $recipient; + } + $message['subject'] = $this->subject; + $message['date'] = date('r'); + + if ($this->isHtmlBody($content)) { + $message['html'] = $content; + } else { + $message['text'] = $content; + } + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, 'https://api.sendgrid.com/api/mail.send.json'); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($message)); + Curl\Util::execute($ch, 2); + } +} diff --git a/src/Monolog/Handler/SlackHandler.php b/src/Monolog/Handler/SlackHandler.php index ac2af02..a5db721 100644 --- a/src/Monolog/Handler/SlackHandler.php +++ b/src/Monolog/Handler/SlackHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -92,7 +92,7 @@ class SlackHandler extends SocketHandler $this->token = $token; $this->channel = $channel; $this->username = $username; - $this->iconEmoji = trim($iconEmoji, ':'); + $this->iconEmoji = is_string($iconEmoji) ? trim($iconEmoji, ':') : null; $this->useAttachment = $useAttachment; $this->useShortAttachment = $useShortAttachment; $this->includeContextAndExtra = $includeContextAndExtra; @@ -136,20 +136,20 @@ class SlackHandler extends SocketHandler */ protected function prepareContentData($record) { - $dataArray = array( + $dataArray = [ 'token' => $this->token, 'channel' => $this->channel, 'username' => $this->username, 'text' => '', - 'attachments' => array(), - ); + 'attachments' => [], + ]; if ($this->useAttachment) { - $attachment = array( + $attachment = [ 'fallback' => $record['message'], 'color' => $this->getAttachmentColor($record['level']), - 'fields' => array(), - ); + 'fields' => [], + ]; if ($this->useShortAttachment) { $attachment['title'] = $record['level_name']; @@ -157,54 +157,54 @@ class SlackHandler extends SocketHandler } else { $attachment['title'] = 'Message'; $attachment['text'] = $record['message']; - $attachment['fields'][] = array( + $attachment['fields'][] = [ 'title' => 'Level', 'value' => $record['level_name'], 'short' => true, - ); + ]; } if ($this->includeContextAndExtra) { if (!empty($record['extra'])) { if ($this->useShortAttachment) { - $attachment['fields'][] = array( + $attachment['fields'][] = [ 'title' => "Extra", 'value' => $this->stringify($record['extra']), 'short' => $this->useShortAttachment, - ); + ]; } else { // Add all extra fields as individual fields in attachment foreach ($record['extra'] as $var => $val) { - $attachment['fields'][] = array( + $attachment['fields'][] = [ 'title' => $var, 'value' => $val, 'short' => $this->useShortAttachment, - ); + ]; } } } if (!empty($record['context'])) { if ($this->useShortAttachment) { - $attachment['fields'][] = array( + $attachment['fields'][] = [ 'title' => "Context", 'value' => $this->stringify($record['context']), 'short' => $this->useShortAttachment, - ); + ]; } else { // Add all context fields as individual fields in attachment foreach ($record['context'] as $var => $val) { - $attachment['fields'][] = array( + $attachment['fields'][] = [ 'title' => $var, 'value' => $val, 'short' => $this->useShortAttachment, - ); + ]; } } } } - $dataArray['attachments'] = json_encode(array($attachment)); + $dataArray['attachments'] = json_encode([$attachment]); } else { $dataArray['text'] = $record['message']; } diff --git a/src/Monolog/Handler/SocketHandler.php b/src/Monolog/Handler/SocketHandler.php index 7a61bf4..06a2019 100644 --- a/src/Monolog/Handler/SocketHandler.php +++ b/src/Monolog/Handler/SocketHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -216,7 +216,7 @@ class SocketHandler extends AbstractProcessingHandler $seconds = floor($this->timeout); $microseconds = round(($this->timeout - $seconds) * 1e6); - return stream_set_timeout($this->resource, $seconds, $microseconds); + return stream_set_timeout($this->resource, (int) $seconds, (int) $microseconds); } /** diff --git a/src/Monolog/Handler/StreamHandler.php b/src/Monolog/Handler/StreamHandler.php index b084f1a..4a7433c 100644 --- a/src/Monolog/Handler/StreamHandler.php +++ b/src/Monolog/Handler/StreamHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -96,7 +96,7 @@ class StreamHandler extends AbstractProcessingHandler } $this->createDir(); $this->errorMessage = null; - set_error_handler(array($this, 'customErrorHandler')); + set_error_handler([$this, 'customErrorHandler']); $this->stream = fopen($this->url, 'a'); if ($this->filePermission !== null) { @chmod($this->url, $this->filePermission); @@ -154,7 +154,7 @@ class StreamHandler extends AbstractProcessingHandler $dir = $this->getDirFromStream($this->url); if (null !== $dir && !is_dir($dir)) { $this->errorMessage = null; - set_error_handler(array($this, 'customErrorHandler')); + set_error_handler([$this, 'customErrorHandler']); $status = mkdir($dir, 0777, true); restore_error_handler(); if (false === $status) { diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index aba1396..f4816b5 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Monolog/Handler/SwiftMailerHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,6 +13,7 @@ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\LineFormatter; +use Swift_Message; /** * SwiftMailerHandler uses Swift_Mailer to send the emails @@ -25,12 +26,12 @@ class SwiftMailerHandler extends MailHandler private $messageTemplate; /** - * @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 \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|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(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true) + public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, bool $bubble = true) { parent::__construct($level, $bubble); @@ -41,7 +42,7 @@ class SwiftMailerHandler extends MailHandler /** * {@inheritdoc} */ - protected function send($content, array $records) + protected function send(string $content, array $records) { $this->mailer->send($this->buildMessage($content, $records)); } @@ -49,21 +50,21 @@ class SwiftMailerHandler extends MailHandler /** * Creates instance of Swift_Message to be sent * - * @param string $content formatted email body to be sent - * @param array $records Log records that formed the content - * @return \Swift_Message + * @param string $content formatted email body to be sent + * @param array $records Log records that formed the content + * @return Swift_Message */ - protected function buildMessage($content, array $records) + protected function buildMessage(string $content, array $records): Swift_Message { $message = null; - if ($this->messageTemplate instanceof \Swift_Message) { + if ($this->messageTemplate instanceof Swift_Message) { $message = clone $this->messageTemplate; $message->generateId(); } elseif (is_callable($this->messageTemplate)) { $message = call_user_func($this->messageTemplate, $content, $records); } - if (!$message instanceof \Swift_Message) { + if (!$message instanceof Swift_Message) { throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it'); } @@ -72,23 +73,14 @@ class SwiftMailerHandler extends MailHandler $message->setSubject($subjectFormatter->format($this->getHighestRecord($records))); } - $message->setBody($content); + $mime = null; + if ($this->isHtmlBody($content)) { + $mime = 'text/html'; + } + + $message->setBody($content, $mime); $message->setDate(time()); return $message; } - - /** - * BC getter, to be removed in 2.0 - */ - public function __get($name) - { - if ($name === 'message') { - trigger_error('SwiftMailerHandler->message is deprecated, use ->buildMessage() instead to retrieve the message', E_USER_DEPRECATED); - - return $this->buildMessage(null, array()); - } - - throw new \InvalidArgumentException('Invalid property '.$name); - } } diff --git a/src/Monolog/Handler/SyslogHandler.php b/src/Monolog/Handler/SyslogHandler.php index 376bc3b..863fc56 100644 --- a/src/Monolog/Handler/SyslogHandler.php +++ b/src/Monolog/Handler/SyslogHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Handler/SyslogUdp/UdpSocket.php b/src/Monolog/Handler/SyslogUdp/UdpSocket.php index 3bff085..f54ac4e 100644 --- a/src/Monolog/Handler/SyslogUdp/UdpSocket.php +++ b/src/Monolog/Handler/SyslogUdp/UdpSocket.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Handler/SyslogUdpHandler.php b/src/Monolog/Handler/SyslogUdpHandler.php index b175cc3..4e2335d 100644 --- a/src/Monolog/Handler/SyslogUdpHandler.php +++ b/src/Monolog/Handler/SyslogUdpHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Handler/TestHandler.php b/src/Monolog/Handler/TestHandler.php index 458020b..db63565 100644 --- a/src/Monolog/Handler/TestHandler.php +++ b/src/Monolog/Handler/TestHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -65,8 +65,8 @@ namespace Monolog\Handler; */ class TestHandler extends AbstractProcessingHandler { - protected $records = array(); - protected $recordsByLevel = array(); + protected $records = []; + protected $recordsByLevel = []; public function getRecords() { @@ -75,8 +75,8 @@ class TestHandler extends AbstractProcessingHandler public function clear() { - $this->records = array(); - $this->recordsByLevel = array(); + $this->records = []; + $this->recordsByLevel = []; } protected function hasRecordRecords($level) @@ -112,7 +112,7 @@ class TestHandler extends AbstractProcessingHandler public function hasRecordThatPasses($predicate, $level) { if (!is_callable($predicate)) { - throw new \InvalidArgumentException("Expected a callable for hasRecordThatSucceeds"); + throw new \InvalidArgumentException("Expected a callable for hasRecordThatPasses"); } if (!isset($this->recordsByLevel[$level])) { @@ -145,7 +145,7 @@ class TestHandler extends AbstractProcessingHandler if (method_exists($this, $genericMethod)) { $args[] = $level; - return call_user_func_array(array($this, $genericMethod), $args); + return call_user_func_array([$this, $genericMethod], $args); } } diff --git a/src/Monolog/Handler/WhatFailureGroupHandler.php b/src/Monolog/Handler/WhatFailureGroupHandler.php index 2732ba3..42c2336 100644 --- a/src/Monolog/Handler/WhatFailureGroupHandler.php +++ b/src/Monolog/Handler/WhatFailureGroupHandler.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -22,7 +22,7 @@ class WhatFailureGroupHandler extends GroupHandler /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if ($this->processors) { foreach ($this->processors as $processor) { @@ -33,8 +33,6 @@ class WhatFailureGroupHandler extends GroupHandler foreach ($this->handlers as $handler) { try { $handler->handle($record); - } catch (\Exception $e) { - // What failure? } catch (\Throwable $e) { // What failure? } @@ -51,8 +49,6 @@ class WhatFailureGroupHandler extends GroupHandler foreach ($this->handlers as $handler) { try { $handler->handleBatch($records); - } catch (\Exception $e) { - // What failure? } catch (\Throwable $e) { // What failure? } diff --git a/src/Monolog/Handler/ZendMonitorHandler.php b/src/Monolog/Handler/ZendMonitorHandler.php index f22cf21..c0bceb4 100644 --- a/src/Monolog/Handler/ZendMonitorHandler.php +++ b/src/Monolog/Handler/ZendMonitorHandler.php @@ -1,4 +1,5 @@ -<?php +<?php declare(strict_types=1); + /* * This file is part of the Monolog package. * @@ -10,6 +11,7 @@ namespace Monolog\Handler; +use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\NormalizerFormatter; use Monolog\Logger; @@ -25,7 +27,7 @@ class ZendMonitorHandler extends AbstractProcessingHandler * * @var array */ - protected $levelMap = array( + protected $levelMap = [ Logger::DEBUG => 1, Logger::INFO => 2, Logger::NOTICE => 3, @@ -34,7 +36,7 @@ class ZendMonitorHandler extends AbstractProcessingHandler Logger::CRITICAL => 6, Logger::ALERT => 7, Logger::EMERGENCY => 0, - ); + ]; /** * Construct @@ -78,7 +80,7 @@ class ZendMonitorHandler extends AbstractProcessingHandler /** * {@inheritdoc} */ - public function getDefaultFormatter() + public function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter(); } diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 2fbc02c..8f981e3 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,8 +11,8 @@ namespace Monolog; +use DateTimeZone; use Monolog\Handler\HandlerInterface; -use Monolog\Handler\StreamHandler; use Psr\Log\LoggerInterface; use Psr\Log\InvalidArgumentException; @@ -84,14 +84,16 @@ class Logger implements LoggerInterface * * @var int */ - const API = 1; + const API = 2; /** * Logging levels from syslog protocol defined in RFC 5424 * - * @var array $levels Logging levels + * 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 */ - protected static $levels = array( + protected static $levels = [ self::DEBUG => 'DEBUG', self::INFO => 'INFO', self::NOTICE => 'NOTICE', @@ -100,12 +102,7 @@ class Logger implements LoggerInterface self::CRITICAL => 'CRITICAL', self::ALERT => 'ALERT', self::EMERGENCY => 'EMERGENCY', - ); - - /** - * @var \DateTimeZone - */ - protected static $timezone; + ]; /** * @var string @@ -131,24 +128,31 @@ class Logger implements LoggerInterface /** * @var bool */ - protected $microsecondTimestamps = true; + protected $microsecondTimestamps = false; + + /** + * @var DateTimeZone + */ + protected $timezone; /** * @param string $name The logging channel * @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc. * @param callable[] $processors Optional array of processors + * @param DateTimeZone $timezone Optional timezone, if not provided date_default_timezone_get() will be used */ - public function __construct($name, array $handlers = array(), array $processors = array()) + public function __construct(string $name, array $handlers = [], array $processors = [], DateTimeZone $timezone = null) { $this->name = $name; $this->handlers = $handlers; $this->processors = $processors; + $this->timezone = $timezone ?: new DateTimeZone(date_default_timezone_get() ?: 'UTC'); } /** * @return string */ - public function getName() + public function getName(): string { return $this->name; } @@ -158,7 +162,7 @@ class Logger implements LoggerInterface * * @return static */ - public function withName($name) + public function withName(string $name): self { $new = clone $this; $new->name = $name; @@ -172,7 +176,7 @@ class Logger implements LoggerInterface * @param HandlerInterface $handler * @return $this */ - public function pushHandler(HandlerInterface $handler) + public function pushHandler(HandlerInterface $handler): self { array_unshift($this->handlers, $handler); @@ -184,7 +188,7 @@ class Logger implements LoggerInterface * * @return HandlerInterface */ - public function popHandler() + public function popHandler(): HandlerInterface { if (!$this->handlers) { throw new \LogicException('You tried to pop from an empty handler stack.'); @@ -201,9 +205,9 @@ class Logger implements LoggerInterface * @param HandlerInterface[] $handlers * @return $this */ - public function setHandlers(array $handlers) + public function setHandlers(array $handlers): self { - $this->handlers = array(); + $this->handlers = []; foreach (array_reverse($handlers) as $handler) { $this->pushHandler($handler); } @@ -214,7 +218,7 @@ class Logger implements LoggerInterface /** * @return HandlerInterface[] */ - public function getHandlers() + public function getHandlers(): array { return $this->handlers; } @@ -225,11 +229,8 @@ class Logger implements LoggerInterface * @param callable $callback * @return $this */ - public function pushProcessor($callback) + public function pushProcessor(callable $callback): self { - if (!is_callable($callback)) { - throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); - } array_unshift($this->processors, $callback); return $this; @@ -240,7 +241,7 @@ class Logger implements LoggerInterface * * @return callable */ - public function popProcessor() + public function popProcessor(): callable { if (!$this->processors) { throw new \LogicException('You tried to pop from an empty processor stack.'); @@ -252,7 +253,7 @@ class Logger implements LoggerInterface /** * @return callable[] */ - public function getProcessors() + public function getProcessors(): array { return $this->processors; } @@ -270,9 +271,9 @@ class Logger implements LoggerInterface * * @param bool $micro True to use microtime() to create timestamps */ - public function useMicrosecondTimestamps($micro) + public function useMicrosecondTimestamps(bool $micro) { - $this->microsecondTimestamps = (bool) $micro; + $this->microsecondTimestamps = $micro; } /** @@ -283,19 +284,15 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function addRecord($level, $message, array $context = array()) + public function addRecord(int $level, string $message, array $context = []): bool { - if (!$this->handlers) { - $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG)); - } - $levelName = static::getLevelName($level); // check if any handler will handle this message so we can return early and save cycles $handlerKey = null; reset($this->handlers); while ($handler = current($this->handlers)) { - if ($handler->isHandling(array('level' => $level))) { + if ($handler->isHandling(['level' => $level])) { $handlerKey = key($this->handlers); break; } @@ -307,26 +304,18 @@ class Logger implements LoggerInterface return false; } - if (!static::$timezone) { - static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC'); - } - - if ($this->microsecondTimestamps) { - $ts = \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone); - } else { - $ts = new \DateTime(null, static::$timezone); - } - $ts->setTimezone(static::$timezone); + $dateTime = new DateTimeImmutable($this->microsecondTimestamps, $this->timezone); + $dateTime->setTimezone($this->timezone); - $record = array( - 'message' => (string) $message, + $record = [ + 'message' => $message, 'context' => $context, 'level' => $level, 'level_name' => $levelName, 'channel' => $this->name, - 'datetime' => $ts, - 'extra' => array(), - ); + 'datetime' => $dateTime, + 'extra' => [], + ]; foreach ($this->processors as $processor) { $record = call_user_func($processor, $record); @@ -344,107 +333,11 @@ 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 - */ - public function addDebug($message, array $context = array()) - { - return $this->addRecord(static::DEBUG, $message, $context); - } - - /** - * 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 - */ - public function addInfo($message, array $context = array()) - { - return $this->addRecord(static::INFO, $message, $context); - } - - /** - * 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 - */ - public function addNotice($message, array $context = array()) - { - return $this->addRecord(static::NOTICE, $message, $context); - } - - /** - * 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 - */ - public function addWarning($message, array $context = array()) - { - return $this->addRecord(static::WARNING, $message, $context); - } - - /** - * 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 - */ - public function addError($message, array $context = array()) - { - return $this->addRecord(static::ERROR, $message, $context); - } - - /** - * 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 - */ - public function addCritical($message, array $context = array()) - { - return $this->addRecord(static::CRITICAL, $message, $context); - } - - /** - * 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 - */ - public function addAlert($message, array $context = array()) - { - return $this->addRecord(static::ALERT, $message, $context); - } - - /** - * 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 - */ - public function addEmergency($message, array $context = array()) - { - return $this->addRecord(static::EMERGENCY, $message, $context); - } - - /** * Gets all supported logging levels. * * @return array Assoc array with human-readable level names => level codes. */ - public static function getLevels() + public static function getLevels(): array { return array_flip(static::$levels); } @@ -455,7 +348,7 @@ class Logger implements LoggerInterface * @param int $level * @return string */ - public static function getLevelName($level) + public static function getLevelName(int $level): string { if (!isset(static::$levels[$level])) { throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); @@ -470,10 +363,14 @@ class Logger implements LoggerInterface * @param string|int Level number (monolog) or name (PSR-3) * @return int */ - public static function toMonologLevel($level) + public static function toMonologLevel($level): int { - if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) { - return constant(__CLASS__.'::'.strtoupper($level)); + if (is_string($level)) { + if (defined(__CLASS__.'::'.strtoupper($level))) { + return constant(__CLASS__.'::'.strtoupper($level)); + } + + throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); } return $level; @@ -485,11 +382,11 @@ class Logger implements LoggerInterface * @param int $level * @return Boolean */ - public function isHandling($level) + public function isHandling(int $level): bool { - $record = array( + $record = [ 'level' => $level, - ); + ]; foreach ($this->handlers as $handler) { if ($handler->isHandling($record)) { @@ -510,11 +407,11 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function log($level, $message, array $context = array()) + public function log($level, $message, array $context = []) { $level = static::toMonologLevel($level); - return $this->addRecord($level, $message, $context); + return $this->addRecord($level, (string) $message, $context); } /** @@ -526,9 +423,9 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function debug($message, array $context = array()) + public function debug($message, array $context = []) { - return $this->addRecord(static::DEBUG, $message, $context); + return $this->addRecord(static::DEBUG, (string) $message, $context); } /** @@ -540,9 +437,9 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function info($message, array $context = array()) + public function info($message, array $context = []) { - return $this->addRecord(static::INFO, $message, $context); + return $this->addRecord(static::INFO, (string) $message, $context); } /** @@ -554,23 +451,9 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function notice($message, array $context = array()) - { - return $this->addRecord(static::NOTICE, $message, $context); - } - - /** - * Adds a log record at the WARNING level. - * - * 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 - */ - public function warn($message, array $context = array()) + public function notice($message, array $context = []) { - return $this->addRecord(static::WARNING, $message, $context); + return $this->addRecord(static::NOTICE, (string) $message, $context); } /** @@ -582,23 +465,9 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function warning($message, array $context = array()) - { - return $this->addRecord(static::WARNING, $message, $context); - } - - /** - * Adds a log record at the ERROR level. - * - * 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 - */ - public function err($message, array $context = array()) + public function warning($message, array $context = []) { - return $this->addRecord(static::ERROR, $message, $context); + return $this->addRecord(static::WARNING, (string) $message, $context); } /** @@ -610,9 +479,9 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function error($message, array $context = array()) + public function error($message, array $context = []) { - return $this->addRecord(static::ERROR, $message, $context); + return $this->addRecord(static::ERROR, (string) $message, $context); } /** @@ -624,23 +493,9 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function crit($message, array $context = array()) + public function critical($message, array $context = []) { - return $this->addRecord(static::CRITICAL, $message, $context); - } - - /** - * Adds a log record at the CRITICAL level. - * - * 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 - */ - public function critical($message, array $context = array()) - { - return $this->addRecord(static::CRITICAL, $message, $context); + return $this->addRecord(static::CRITICAL, (string) $message, $context); } /** @@ -652,9 +507,9 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function alert($message, array $context = array()) + public function alert($message, array $context = []) { - return $this->addRecord(static::ALERT, $message, $context); + return $this->addRecord(static::ALERT, (string) $message, $context); } /** @@ -666,34 +521,28 @@ class Logger implements LoggerInterface * @param array $context The log context * @return Boolean Whether the record has been processed */ - public function emerg($message, array $context = array()) + public function emergency($message, array $context = []) { - return $this->addRecord(static::EMERGENCY, $message, $context); + return $this->addRecord(static::EMERGENCY, (string) $message, $context); } /** - * Adds a log record at the EMERGENCY level. - * - * This method allows for compatibility with common interfaces. + * Set the timezone to be used for the timestamp of log records. * - * @param string $message The log message - * @param array $context The log context - * @return Boolean Whether the record has been processed + * @param DateTimeZone $tz Timezone object */ - public function emergency($message, array $context = array()) + public function setTimezone(DateTimeZone $tz) { - return $this->addRecord(static::EMERGENCY, $message, $context); + $this->timezone = $tz; } /** * Set the timezone to be used for the timestamp of log records. * - * This is stored globally for all Logger instances - * - * @param \DateTimeZone $tz Timezone object + * @return DateTimeZone */ - public static function setTimezone(\DateTimeZone $tz) + public function getTimezone(): DateTimeZone { - self::$timezone = $tz; + return $this->timezone; } } diff --git a/src/Monolog/Processor/GitProcessor.php b/src/Monolog/Processor/GitProcessor.php index 1899400..cf16be8 100644 --- a/src/Monolog/Processor/GitProcessor.php +++ b/src/Monolog/Processor/GitProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -53,12 +53,12 @@ class GitProcessor $branches = `git branch -v --no-abbrev`; if (preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) { - return self::$cache = array( + return self::$cache = [ 'branch' => $matches[1], 'commit' => $matches[2], - ); + ]; } - return self::$cache = array(); + return self::$cache = []; } } diff --git a/src/Monolog/Processor/IntrospectionProcessor.php b/src/Monolog/Processor/IntrospectionProcessor.php index 2691630..59e2f48 100644 --- a/src/Monolog/Processor/IntrospectionProcessor.php +++ b/src/Monolog/Processor/IntrospectionProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -32,15 +32,15 @@ class IntrospectionProcessor private $skipStackFramesCount; - private $skipFunctions = array( + private $skipFunctions = [ 'call_user_func', 'call_user_func_array', - ); + ]; - public function __construct($level = Logger::DEBUG, array $skipClassesPartials = array(), $skipStackFramesCount = 0) + public function __construct($level = Logger::DEBUG, array $skipClassesPartials = [], $skipStackFramesCount = 0) { $this->level = Logger::toMonologLevel($level); - $this->skipClassesPartials = array_merge(array('Monolog\\'), $skipClassesPartials); + $this->skipClassesPartials = array_merge(['Monolog\\'], $skipClassesPartials); $this->skipStackFramesCount = $skipStackFramesCount; } @@ -85,12 +85,12 @@ class IntrospectionProcessor // we should have the call source now $record['extra'] = array_merge( $record['extra'], - array( + [ 'file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null, 'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null, 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null, 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null, - ) + ] ); return $record; diff --git a/src/Monolog/Processor/MemoryPeakUsageProcessor.php b/src/Monolog/Processor/MemoryPeakUsageProcessor.php index 0543e92..b8fd91c 100644 --- a/src/Monolog/Processor/MemoryPeakUsageProcessor.php +++ b/src/Monolog/Processor/MemoryPeakUsageProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Processor/MemoryProcessor.php b/src/Monolog/Processor/MemoryProcessor.php index 85f9dc5..460caa6 100644 --- a/src/Monolog/Processor/MemoryProcessor.php +++ b/src/Monolog/Processor/MemoryProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Processor/MemoryUsageProcessor.php b/src/Monolog/Processor/MemoryUsageProcessor.php index 2783d65..cb6b2ea 100644 --- a/src/Monolog/Processor/MemoryUsageProcessor.php +++ b/src/Monolog/Processor/MemoryUsageProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Processor/ProcessIdProcessor.php b/src/Monolog/Processor/ProcessIdProcessor.php index 9d3f559..7ddafea 100644 --- a/src/Monolog/Processor/ProcessIdProcessor.php +++ b/src/Monolog/Processor/ProcessIdProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Processor/PsrLogMessageProcessor.php b/src/Monolog/Processor/PsrLogMessageProcessor.php index c2686ce..e1a42cd 100644 --- a/src/Monolog/Processor/PsrLogMessageProcessor.php +++ b/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -30,7 +30,7 @@ class PsrLogMessageProcessor return $record; } - $replacements = array(); + $replacements = []; foreach ($record['context'] as $key => $val) { if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) { $replacements['{'.$key.'}'] = $val; diff --git a/src/Monolog/Processor/TagProcessor.php b/src/Monolog/Processor/TagProcessor.php index 7e2df2a..19458e2 100644 --- a/src/Monolog/Processor/TagProcessor.php +++ b/src/Monolog/Processor/TagProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -20,17 +20,17 @@ class TagProcessor { private $tags; - public function __construct(array $tags = array()) + public function __construct(array $tags = []) { $this->setTags($tags); } - public function addTags(array $tags = array()) + public function addTags(array $tags = []) { $this->tags = array_merge($this->tags, $tags); } - public function setTags(array $tags = array()) + public function setTags(array $tags = []) { $this->tags = $tags; } diff --git a/src/Monolog/Processor/UidProcessor.php b/src/Monolog/Processor/UidProcessor.php index 812707c..891e9df 100644 --- a/src/Monolog/Processor/UidProcessor.php +++ b/src/Monolog/Processor/UidProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/src/Monolog/Processor/WebProcessor.php b/src/Monolog/Processor/WebProcessor.php index ea1d897..91abeec 100644 --- a/src/Monolog/Processor/WebProcessor.php +++ b/src/Monolog/Processor/WebProcessor.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -30,13 +30,13 @@ class WebProcessor * * @var array */ - protected $extraFields = array( + protected $extraFields = [ 'url' => 'REQUEST_URI', 'ip' => 'REMOTE_ADDR', 'http_method' => 'REQUEST_METHOD', 'server' => 'SERVER_NAME', 'referrer' => 'HTTP_REFERER', - ); + ]; /** * @param array|\ArrayAccess $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data diff --git a/src/Monolog/Registry.php b/src/Monolog/Registry.php index 159b751..64612c8 100644 --- a/src/Monolog/Registry.php +++ b/src/Monolog/Registry.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -42,7 +42,7 @@ class Registry * * @var Logger[] */ - private static $loggers = array(); + private static $loggers = []; /** * Adds new logging channel to the registry @@ -100,7 +100,7 @@ class Registry */ public static function clear() { - self::$loggers = array(); + self::$loggers = []; } /** diff --git a/tests/Monolog/TestCase.php b/src/Monolog/Test/TestCase.php index 4eb7b4c..7cb7fbf 100644 --- a/tests/Monolog/TestCase.php +++ b/src/Monolog/Test/TestCase.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -9,24 +9,32 @@ * file that was distributed with this source code. */ -namespace Monolog; +namespace Monolog\Test; +use Monolog\Logger; +use Monolog\DateTimeImmutable; + +/** + * Lets you easily generate log records and a dummy formatter for testing purposes + * * + * @author Jordi Boggiano <j.boggiano@seld.be> + */ class TestCase extends \PHPUnit_Framework_TestCase { /** * @return array Record */ - protected function getRecord($level = Logger::WARNING, $message = 'test', $context = array()) + protected function getRecord($level = Logger::WARNING, $message = 'test', $context = []) { - return array( + return [ 'message' => $message, 'context' => $context, 'level' => $level, 'level_name' => Logger::getLevelName($level), 'channel' => 'test', - 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true))), - 'extra' => array(), - ); + 'datetime' => new DateTimeImmutable(true), + 'extra' => [], + ]; } /** @@ -34,13 +42,13 @@ class TestCase extends \PHPUnit_Framework_TestCase */ protected function getMultipleRecords() { - return array( + return [ $this->getRecord(Logger::DEBUG, 'debug message 1'), $this->getRecord(Logger::DEBUG, 'debug message 2'), $this->getRecord(Logger::INFO, 'information'), $this->getRecord(Logger::WARNING, 'warning'), $this->getRecord(Logger::ERROR, 'error'), - ); + ]; } /** @@ -51,7 +59,9 @@ class TestCase extends \PHPUnit_Framework_TestCase $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); $formatter->expects($this->any()) ->method('format') - ->will($this->returnCallback(function ($record) { return $record['message']; })); + ->will($this->returnCallback(function ($record) { + return $record['message']; + })); return $formatter; } diff --git a/tests/Monolog/ErrorHandlerTest.php b/tests/Monolog/ErrorHandlerTest.php index a9a3f30..7b3ba82 100644 --- a/tests/Monolog/ErrorHandlerTest.php +++ b/tests/Monolog/ErrorHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -17,10 +17,10 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase { public function testHandleError() { - $logger = new Logger('test', array($handler = new TestHandler)); + $logger = new Logger('test', [$handler = new TestHandler]); $errHandler = new ErrorHandler($logger); - $errHandler->registerErrorHandler(array(E_USER_NOTICE => Logger::EMERGENCY), false); + $errHandler->registerErrorHandler([E_USER_NOTICE => Logger::EMERGENCY], false); trigger_error('Foo', E_USER_ERROR); $this->assertCount(1, $handler->getRecords()); $this->assertTrue($handler->hasErrorRecords()); @@ -28,4 +28,38 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase $this->assertCount(2, $handler->getRecords()); $this->assertTrue($handler->hasEmergencyRecords()); } + + public function testHandleException() + { + $logger = new Logger('test', [$handler = new TestHandler]); + $errHandler = new ErrorHandler($logger); + + $errHandler->registerExceptionHandler(['Monolog\CustomTestException' => Logger::ALERT, 'Throwable' => Logger::WARNING], false); + + try { + throw new CustomCustomException(); + $this->assertCount(1, $handler->getRecords()); + $this->assertTrue($handler->hasAlertRecords()); + } catch (\Throwable $e) { + } + try { + throw new CustomTestException(); + $this->assertCount(2, $handler->getRecords()); + $this->assertTrue($handler->hasAlertRecords()); + } catch (\Throwable $e) { + } + try { + throw new RuntimeException(); + $this->assertCount(3, $handler->getRecords()); + $this->assertTrue($handler->hasWarningRecords()); + } catch (\Throwable $e) { + } + } +} + +class CustomTestException extends \Exception +{ +} +class CustomCustomException extends CustomTestException +{ } diff --git a/tests/Monolog/Formatter/ChromePHPFormatterTest.php b/tests/Monolog/Formatter/ChromePHPFormatterTest.php index 71c4204..08a8e1b 100644 --- a/tests/Monolog/Formatter/ChromePHPFormatterTest.php +++ b/tests/Monolog/Formatter/ChromePHPFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -21,29 +21,29 @@ class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase public function testDefaultFormat() { $formatter = new ChromePHPFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('ip' => '127.0.0.1'), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['ip' => '127.0.0.1'], 'message' => 'log', - ); + ]; $message = $formatter->format($record); $this->assertEquals( - array( + [ 'meh', - array( + [ 'message' => 'log', - 'context' => array('from' => 'logger'), - 'extra' => array('ip' => '127.0.0.1'), - ), + 'context' => ['from' => 'logger'], + 'extra' => ['ip' => '127.0.0.1'], + ], 'unknown', 'error', - ), + ], $message ); } @@ -54,29 +54,29 @@ class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithFileAndLine() { $formatter = new ChromePHPFormatter(); - $record = array( + $record = [ 'level' => Logger::CRITICAL, 'level_name' => 'CRITICAL', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['ip' => '127.0.0.1', 'file' => 'test', 'line' => 14], 'message' => 'log', - ); + ]; $message = $formatter->format($record); $this->assertEquals( - array( + [ 'meh', - array( + [ 'message' => 'log', - 'context' => array('from' => 'logger'), - 'extra' => array('ip' => '127.0.0.1'), - ), + 'context' => ['from' => 'logger'], + 'extra' => ['ip' => '127.0.0.1'], + ], 'test : 14', 'error', - ), + ], $message ); } @@ -87,25 +87,25 @@ class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithoutContext() { $formatter = new ChromePHPFormatter(); - $record = array( + $record = [ 'level' => Logger::DEBUG, 'level_name' => 'DEBUG', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; $message = $formatter->format($record); $this->assertEquals( - array( + [ 'meh', 'log', 'unknown', 'log', - ), + ], $message ); } @@ -116,42 +116,42 @@ class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase public function testBatchFormatThrowException() { $formatter = new ChromePHPFormatter(); - $records = array( - array( + $records = [ + [ 'level' => Logger::INFO, 'level_name' => 'INFO', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ), - array( + ], + [ 'level' => Logger::WARNING, 'level_name' => 'WARNING', 'channel' => 'foo', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log2', - ), - ); + ], + ]; $this->assertEquals( - array( - array( + [ + [ 'meh', 'log', 'unknown', 'info', - ), - array( + ], + [ 'foo', 'log2', 'unknown', 'warn', - ), - ), + ], + ], $formatter->formatBatch($records) ); } diff --git a/tests/Monolog/Formatter/ElasticaFormatterTest.php b/tests/Monolog/Formatter/ElasticaFormatterTest.php index 90cc48d..8e88e69 100644 --- a/tests/Monolog/Formatter/ElasticaFormatterTest.php +++ b/tests/Monolog/Formatter/ElasticaFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -30,24 +30,24 @@ class ElasticaFormatterTest extends \PHPUnit_Framework_TestCase public function testFormat() { // test log message - $msg = array( + $msg = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => ['foo' => 7, 'bar', 'class' => new \stdClass], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; // expected values $expected = $msg; $expected['datetime'] = '1970-01-01T00:00:00.000000+00:00'; - $expected['context'] = array( - 'class' => '[object] (stdClass: {})', + $expected['context'] = [ + 'class' => ['stdClass' => []], 'foo' => 7, 0 => 'bar', - ); + ]; // format log message $formatter = new ElasticaFormatter('my_index', 'doc_type'); diff --git a/tests/Monolog/Formatter/FlowdockFormatterTest.php b/tests/Monolog/Formatter/FlowdockFormatterTest.php index 1b2fd97..f922d53 100644 --- a/tests/Monolog/Formatter/FlowdockFormatterTest.php +++ b/tests/Monolog/Formatter/FlowdockFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Formatter; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; class FlowdockFormatterTest extends TestCase { @@ -24,14 +24,14 @@ class FlowdockFormatterTest extends TestCase $formatter = new FlowdockFormatter('test_source', 'source@test.com'); $record = $this->getRecord(); - $expected = array( + $expected = [ 'source' => 'test_source', 'from_address' => 'source@test.com', 'subject' => 'in test_source: WARNING - test', 'content' => 'test', - 'tags' => array('#logs', '#warning', '#test'), + 'tags' => ['#logs', '#warning', '#test'], 'project' => 'test_source', - ); + ]; $formatted = $formatter->format($record); $this->assertEquals($expected, $formatted['flowdock']); @@ -43,10 +43,10 @@ class FlowdockFormatterTest extends TestCase public function testFormatBatch() { $formatter = new FlowdockFormatter('test_source', 'source@test.com'); - $records = array( + $records = [ $this->getRecord(Logger::WARNING), $this->getRecord(Logger::DEBUG), - ); + ]; $formatted = $formatter->formatBatch($records); $this->assertArrayHasKey('flowdock', $formatted[0]); diff --git a/tests/Monolog/Formatter/FluentdFormatterTest.php b/tests/Monolog/Formatter/FluentdFormatterTest.php index 622b2ba..0be8d8f 100644 --- a/tests/Monolog/Formatter/FluentdFormatterTest.php +++ b/tests/Monolog/Formatter/FluentdFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Formatter; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; class FluentdFormatterTest extends TestCase { @@ -36,7 +36,7 @@ class FluentdFormatterTest extends TestCase public function testFormat() { $record = $this->getRecord(Logger::WARNING); - $record['datetime'] = new \DateTime("@0"); + $record['datetime'] = new \DateTimeImmutable("@0"); $formatter = new FluentdFormatter(); $this->assertEquals( @@ -51,7 +51,7 @@ class FluentdFormatterTest extends TestCase public function testFormatWithTag() { $record = $this->getRecord(Logger::ERROR); - $record['datetime'] = new \DateTime("@0"); + $record['datetime'] = new \DateTimeImmutable("@0"); $formatter = new FluentdFormatter(true); $this->assertEquals( diff --git a/tests/Monolog/Formatter/GelfMessageFormatterTest.php b/tests/Monolog/Formatter/GelfMessageFormatterTest.php index e6bd309..897aa81 100644 --- a/tests/Monolog/Formatter/GelfMessageFormatterTest.php +++ b/tests/Monolog/Formatter/GelfMessageFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -28,15 +28,15 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase public function testDefaultFormatter() { $formatter = new GelfMessageFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; $message = $formatter->format($record); @@ -63,15 +63,15 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithFileAndLine() { $formatter = new GelfMessageFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('file' => 'test', 'line' => 14), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['file' => 'test', 'line' => 14], 'message' => 'log', - ); + ]; $message = $formatter->format($record); @@ -87,10 +87,10 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatInvalidFails() { $formatter = new GelfMessageFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', - ); + ]; $formatter->format($record); } @@ -101,15 +101,15 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithContext() { $formatter = new GelfMessageFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['key' => 'pair'], 'message' => 'log', - ); + ]; $message = $formatter->format($record); @@ -138,19 +138,19 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithContextContainingException() { $formatter = new GelfMessageFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger', 'exception' => array( + 'context' => ['from' => 'logger', 'exception' => [ 'class' => '\Exception', 'file' => '/some/file/in/dir.php:56', - 'trace' => array('/some/file/1.php:23', '/some/file/2.php:3'), - )), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'trace' => ['/some/file/1.php:23', '/some/file/2.php:3'], + ]], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; $message = $formatter->format($record); @@ -166,15 +166,15 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithExtra() { $formatter = new GelfMessageFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['key' => 'pair'], 'message' => 'log', - ); + ]; $message = $formatter->format($record); @@ -200,15 +200,15 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithLargeData() { $formatter = new GelfMessageFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('exception' => str_repeat(' ', 32767)), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => str_repeat(' ', 32767)), - 'message' => 'log' - ); + 'context' => ['exception' => str_repeat(' ', 32767)], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['key' => str_repeat(' ', 32767)], + 'message' => 'log', + ]; $message = $formatter->format($record); $messageArray = $message->toArray(); @@ -216,7 +216,7 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase $length = 200; foreach ($messageArray as $key => $value) { - if (!in_array($key, array('level', 'timestamp'))) { + if (!in_array($key, ['level', 'timestamp']) && is_string($value)) { $length += strlen($value); } } diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index df7e35d..392647f 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Formatter; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; class JsonFormatterTest extends TestCase { @@ -42,7 +42,7 @@ class JsonFormatterTest extends TestCase $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); $record = $this->getRecord(); - $this->assertEquals(json_encode($record), $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)); } /** @@ -52,10 +52,10 @@ class JsonFormatterTest extends TestCase public function testFormatBatch() { $formatter = new JsonFormatter(); - $records = array( + $records = [ $this->getRecord(Logger::WARNING), $this->getRecord(Logger::DEBUG), - ); + ]; $this->assertEquals(json_encode($records), $formatter->formatBatch($records)); } @@ -66,10 +66,10 @@ class JsonFormatterTest extends TestCase public function testFormatBatchNewlines() { $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES); - $records = $expected = array( + $records = $expected = [ $this->getRecord(Logger::WARNING), $this->getRecord(Logger::DEBUG), - ); + ]; array_walk($expected, function (&$value, $key) { $value = json_encode($value); }); @@ -80,35 +80,35 @@ class JsonFormatterTest extends TestCase { $formatter = new JsonFormatter(); $exception = new \RuntimeException('Foo'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'CRITICAL', 'channel' => 'core', - 'context' => array('exception' => $exception), - 'datetime' => new \DateTime(), - 'extra' => array(), + 'context' => ['exception' => $exception], + 'datetime' => new \DateTimeImmutable(), + 'extra' => [], 'message' => 'foobar', - )); + ]); if (version_compare(PHP_VERSION, '5.4.0', '>=')) { $path = substr(json_encode($exception->getFile(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), 1, -1); } else { $path = substr(json_encode($exception->getFile()), 1, -1); } - $this->assertEquals('{"level_name":"CRITICAL","channel":"core","context":{"exception":{"class":"RuntimeException","message":"'.$exception->getMessage().'","code":'.$exception->getCode().',"file":"'.$path.':'.$exception->getLine().'"}},"datetime":'.json_encode(new \DateTime()).',"extra":[],"message":"foobar"}'."\n", $message); + $this->assertEquals('{"level_name":"CRITICAL","channel":"core","context":{"exception":{"class":"RuntimeException","message":"'.$exception->getMessage().'","code":'.$exception->getCode().',"file":"'.$path.':'.$exception->getLine().'"}},"datetime":'.json_encode(new \DateTimeImmutable()).',"extra":[],"message":"foobar"}'."\n", $message); } public function testDefFormatWithPreviousException() { $formatter = new JsonFormatter(); $exception = new \RuntimeException('Foo', 0, new \LogicException('Wut?')); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'CRITICAL', 'channel' => 'core', - 'context' => array('exception' => $exception), - 'datetime' => new \DateTime(), - 'extra' => array(), + 'context' => ['exception' => $exception], + 'datetime' => new \DateTimeImmutable(), + 'extra' => [], 'message' => 'foobar', - )); + ]); if (version_compare(PHP_VERSION, '5.4.0', '>=')) { $pathPrevious = substr(json_encode($exception->getPrevious()->getFile(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), 1, -1); @@ -117,6 +117,6 @@ class JsonFormatterTest extends TestCase $pathPrevious = substr(json_encode($exception->getPrevious()->getFile()), 1, -1); $pathException = substr(json_encode($exception->getFile()), 1, -1); } - $this->assertEquals('{"level_name":"CRITICAL","channel":"core","context":{"exception":{"class":"RuntimeException","message":"'.$exception->getMessage().'","code":'.$exception->getCode().',"file":"'.$pathException.':'.$exception->getLine().'","previous":{"class":"LogicException","message":"'.$exception->getPrevious()->getMessage().'","code":'.$exception->getPrevious()->getCode().',"file":"'.$pathPrevious.':'.$exception->getPrevious()->getLine().'"}}},"datetime":'.json_encode(new \DateTime()).',"extra":[],"message":"foobar"}'."\n", $message); + $this->assertEquals('{"level_name":"CRITICAL","channel":"core","context":{"exception":{"class":"RuntimeException","message":"'.$exception->getMessage().'","code":'.$exception->getCode().',"file":"'.$pathException.':'.$exception->getLine().'","previous":{"class":"LogicException","message":"'.$exception->getPrevious()->getMessage().'","code":'.$exception->getPrevious()->getCode().',"file":"'.$pathPrevious.':'.$exception->getPrevious()->getLine().'"}}},"datetime":'.json_encode(new \DateTimeImmutable()).',"extra":[],"message":"foobar"}'."\n", $message); } } diff --git a/tests/Monolog/Formatter/LineFormatterTest.php b/tests/Monolog/Formatter/LineFormatterTest.php index 310d93c..cbbbc66 100644 --- a/tests/Monolog/Formatter/LineFormatterTest.php +++ b/tests/Monolog/Formatter/LineFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -19,118 +19,118 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase public function testDefFormatWithString() { $formatter = new LineFormatter(null, 'Y-m-d'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'WARNING', 'channel' => 'log', - 'context' => array(), + 'context' => [], 'message' => 'foo', - 'datetime' => new \DateTime, - 'extra' => array(), - )); + 'datetime' => new \DateTimeImmutable, + 'extra' => [], + ]); $this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message); } public function testDefFormatWithArrayContext() { $formatter = new LineFormatter(null, 'Y-m-d'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'ERROR', 'channel' => 'meh', 'message' => 'foo', - 'datetime' => new \DateTime, - 'extra' => array(), - 'context' => array( + 'datetime' => new \DateTimeImmutable, + 'extra' => [], + 'context' => [ 'foo' => 'bar', 'baz' => 'qux', 'bool' => false, 'null' => null, - ), - )); + ], + ]); $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foo {"foo":"bar","baz":"qux","bool":false,"null":null} []'."\n", $message); } public function testDefFormatExtras() { $formatter = new LineFormatter(null, 'Y-m-d'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array('ip' => '127.0.0.1'), + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => ['ip' => '127.0.0.1'], 'message' => 'log', - )); + ]); $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] {"ip":"127.0.0.1"}'."\n", $message); } public function testFormatExtras() { $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra.file% %extra%\n", 'Y-m-d'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array('ip' => '127.0.0.1', 'file' => 'test'), + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => ['ip' => '127.0.0.1', 'file' => 'test'], 'message' => 'log', - )); + ]); $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] test {"ip":"127.0.0.1"}'."\n", $message); } public function testContextAndExtraOptionallyNotShownIfEmpty() { $formatter = new LineFormatter(null, 'Y-m-d', false, true); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => [], 'message' => 'log', - )); + ]); $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log '."\n", $message); } public function testContextAndExtraReplacement() { $formatter = new LineFormatter('%context.foo% => %extra.foo%'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('foo' => 'bar'), - 'datetime' => new \DateTime, - 'extra' => array('foo' => 'xbar'), + 'context' => ['foo' => 'bar'], + 'datetime' => new \DateTimeImmutable, + 'extra' => ['foo' => 'xbar'], 'message' => 'log', - )); + ]); $this->assertEquals('bar => xbar', $message); } public function testDefFormatWithObject() { $formatter = new LineFormatter(null, 'Y-m-d'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')), + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => ['foo' => new TestFoo, 'bar' => new TestBar, 'baz' => [], 'res' => fopen('php://memory', 'rb')], 'message' => 'foobar', - )); + ]); - $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: bar)","baz":[],"res":"[resource] (stream)"}'."\n", $message); + $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":{"Monolog\\\\Formatter\\\\TestFoo":{"foo":"fooValue"}},"bar":{"Monolog\\\\Formatter\\\\TestBar":"bar"},"baz":[],"res":"[resource(stream)]"}'."\n", $message); } public function testDefFormatWithException() { $formatter = new LineFormatter(null, 'Y-m-d'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'CRITICAL', 'channel' => 'core', - 'context' => array('exception' => new \RuntimeException('Foo')), - 'datetime' => new \DateTime, - 'extra' => array(), + 'context' => ['exception' => new \RuntimeException('Foo')], + 'datetime' => new \DateTimeImmutable, + 'extra' => [], 'message' => 'foobar', - )); + ]); $path = str_replace('\\/', '/', json_encode(__FILE__)); @@ -141,14 +141,14 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase { $formatter = new LineFormatter(null, 'Y-m-d'); $previous = new \LogicException('Wut?'); - $message = $formatter->format(array( + $message = $formatter->format([ 'level_name' => 'CRITICAL', 'channel' => 'core', - 'context' => array('exception' => new \RuntimeException('Foo', 0, $previous)), - 'datetime' => new \DateTime, - 'extra' => array(), + 'context' => ['exception' => new \RuntimeException('Foo', 0, $previous)], + 'datetime' => new \DateTimeImmutable, + 'extra' => [], 'message' => 'foobar', - )); + ]); $path = str_replace('\\/', '/', json_encode(__FILE__)); @@ -158,24 +158,24 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase public function testBatchFormat() { $formatter = new LineFormatter(null, 'Y-m-d'); - $message = $formatter->formatBatch(array( - array( + $message = $formatter->formatBatch([ + [ 'level_name' => 'CRITICAL', 'channel' => 'test', 'message' => 'bar', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array(), - ), - array( + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => [], + ], + [ 'level_name' => 'WARNING', 'channel' => 'log', 'message' => 'foo', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array(), - ), - )); + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => [], + ], + ]); $this->assertEquals('['.date('Y-m-d').'] test.CRITICAL: bar [] []'."\n".'['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message); } @@ -183,11 +183,11 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase { $formatter = new LineFormatter(null, 'Y-m-d'); $message = $formatter->format( - array( + [ 'message' => "foo\nbar", - 'context' => array(), - 'extra' => array(), - ) + 'context' => [], + 'extra' => [], + ] ); $this->assertRegExp('/foo bar/', $message); @@ -197,11 +197,11 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase { $formatter = new LineFormatter(null, 'Y-m-d', true); $message = $formatter->format( - array( + [ 'message' => "foo\nbar", - 'context' => array(), - 'extra' => array(), - ) + 'context' => [], + 'extra' => [], + ] ); $this->assertRegExp('/foo\nbar/', $message); @@ -210,7 +210,7 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase class TestFoo { - public $foo = 'foo'; + public $foo = 'fooValue'; } class TestBar diff --git a/tests/Monolog/Formatter/LogglyFormatterTest.php b/tests/Monolog/Formatter/LogglyFormatterTest.php index 6d59b3f..2eff4ac 100644 --- a/tests/Monolog/Formatter/LogglyFormatterTest.php +++ b/tests/Monolog/Formatter/LogglyFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Formatter; -use Monolog\TestCase; +use Monolog\Test\TestCase; class LogglyFormatterTest extends TestCase { @@ -34,7 +34,8 @@ class LogglyFormatterTest extends TestCase $formatter = new LogglyFormatter(); $record = $this->getRecord(); $formatted_decoded = json_decode($formatter->format($record), true); + $this->assertArrayNotHasKey("datetime", $formatted_decoded); $this->assertArrayHasKey("timestamp", $formatted_decoded); - $this->assertEquals(new \DateTime($formatted_decoded["timestamp"]), $record["datetime"]); + $this->assertEquals($record["datetime"]->format('Y-m-d\TH:i:s.uO'), $formatted_decoded["timestamp"]); } } diff --git a/tests/Monolog/Formatter/LogmaticFormatterTest.php b/tests/Monolog/Formatter/LogmaticFormatterTest.php new file mode 100644 index 0000000..d27670f --- /dev/null +++ b/tests/Monolog/Formatter/LogmaticFormatterTest.php @@ -0,0 +1,36 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Test\TestCase; + +/** + * @author Julien Breux <julien.breux@gmail.com> + */ +class LogmaticFormatterTest extends TestCase +{ + /** + * @covers Monolog\Formatter\LogmaticFormatter::format + */ + public function testFormat() + { + $formatter = new LogmaticFormatter(); + $formatter->setHostname('testHostname'); + $formatter->setAppname('testAppname'); + $record = $this->getRecord(); + $formatted_decoded = json_decode($formatter->format($record), true); + $this->assertArrayHasKey('hostname', $formatted_decoded); + $this->assertArrayHasKey('appname', $formatted_decoded); + $this->assertEquals('testHostname', $formatted_decoded['hostname']); + $this->assertEquals('testAppname', $formatted_decoded['appname']); + } +} diff --git a/tests/Monolog/Formatter/LogstashFormatterTest.php b/tests/Monolog/Formatter/LogstashFormatterTest.php index 9f6b1cc..57d6759 100644 --- a/tests/Monolog/Formatter/LogstashFormatterTest.php +++ b/tests/Monolog/Formatter/LogstashFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -25,158 +25,18 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase /** * @covers Monolog\Formatter\LogstashFormatter::format */ - public function testDefaultFormatter() - { - $formatter = new LogstashFormatter('test', 'hostname'); - $record = array( - 'level' => Logger::ERROR, - 'level_name' => 'ERROR', - 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), - 'message' => 'log', - ); - - $message = json_decode($formatter->format($record), true); - - $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']); - $this->assertEquals('log', $message['@message']); - $this->assertEquals('meh', $message['@fields']['channel']); - $this->assertContains('meh', $message['@tags']); - $this->assertEquals(Logger::ERROR, $message['@fields']['level']); - $this->assertEquals('test', $message['@type']); - $this->assertEquals('hostname', $message['@source']); - - $formatter = new LogstashFormatter('mysystem'); - - $message = json_decode($formatter->format($record), true); - - $this->assertEquals('mysystem', $message['@type']); - } - - /** - * @covers Monolog\Formatter\LogstashFormatter::format - */ - public function testFormatWithFileAndLine() - { - $formatter = new LogstashFormatter('test'); - $record = array( - 'level' => Logger::ERROR, - 'level_name' => 'ERROR', - 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('file' => 'test', 'line' => 14), - 'message' => 'log', - ); - - $message = json_decode($formatter->format($record), true); - - $this->assertEquals('test', $message['@fields']['file']); - $this->assertEquals(14, $message['@fields']['line']); - } - - /** - * @covers Monolog\Formatter\LogstashFormatter::format - */ - public function testFormatWithContext() - { - $formatter = new LogstashFormatter('test'); - $record = array( - 'level' => Logger::ERROR, - 'level_name' => 'ERROR', - 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), - 'message' => 'log', - ); - - $message = json_decode($formatter->format($record), true); - - $message_array = $message['@fields']; - - $this->assertArrayHasKey('ctxt_from', $message_array); - $this->assertEquals('logger', $message_array['ctxt_from']); - - // Test with extraPrefix - $formatter = new LogstashFormatter('test', null, null, 'CTX'); - $message = json_decode($formatter->format($record), true); - - $message_array = $message['@fields']; - - $this->assertArrayHasKey('CTXfrom', $message_array); - $this->assertEquals('logger', $message_array['CTXfrom']); - } - - /** - * @covers Monolog\Formatter\LogstashFormatter::format - */ - public function testFormatWithExtra() - { - $formatter = new LogstashFormatter('test'); - $record = array( - 'level' => Logger::ERROR, - 'level_name' => 'ERROR', - 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), - 'message' => 'log', - ); - - $message = json_decode($formatter->format($record), true); - - $message_array = $message['@fields']; - - $this->assertArrayHasKey('key', $message_array); - $this->assertEquals('pair', $message_array['key']); - - // Test with extraPrefix - $formatter = new LogstashFormatter('test', null, 'EXT'); - $message = json_decode($formatter->format($record), true); - - $message_array = $message['@fields']; - - $this->assertArrayHasKey('EXTkey', $message_array); - $this->assertEquals('pair', $message_array['EXTkey']); - } - - public function testFormatWithApplicationName() - { - $formatter = new LogstashFormatter('app', 'test'); - $record = array( - 'level' => Logger::ERROR, - 'level_name' => 'ERROR', - 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), - 'message' => 'log', - ); - - $message = json_decode($formatter->format($record), true); - - $this->assertArrayHasKey('@type', $message); - $this->assertEquals('app', $message['@type']); - } - - /** - * @covers Monolog\Formatter\LogstashFormatter::format - */ public function testDefaultFormatterV1() { - $formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_', LogstashFormatter::V1); - $record = array( + $formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_'); + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; $message = json_decode($formatter->format($record), true); @@ -188,7 +48,7 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase $this->assertEquals('test', $message['type']); $this->assertEquals('hostname', $message['host']); - $formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_', LogstashFormatter::V1); + $formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_'); $message = json_decode($formatter->format($record), true); @@ -200,16 +60,16 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase */ public function testFormatWithFileAndLineV1() { - $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1); - $record = array( + $formatter = new LogstashFormatter('test', null, null, 'ctxt_'); + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('file' => 'test', 'line' => 14), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['file' => 'test', 'line' => 14], 'message' => 'log', - ); + ]; $message = json_decode($formatter->format($record), true); @@ -222,16 +82,16 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase */ public function testFormatWithContextV1() { - $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1); - $record = array( + $formatter = new LogstashFormatter('test', null, null, 'ctxt_'); + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['key' => 'pair'], 'message' => 'log', - ); + ]; $message = json_decode($formatter->format($record), true); @@ -239,7 +99,7 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase $this->assertEquals('logger', $message['ctxt_from']); // Test with extraPrefix - $formatter = new LogstashFormatter('test', null, null, 'CTX', LogstashFormatter::V1); + $formatter = new LogstashFormatter('test', null, null, 'CTX'); $message = json_decode($formatter->format($record), true); $this->assertArrayHasKey('CTXfrom', $message); @@ -251,16 +111,16 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase */ public function testFormatWithExtraV1() { - $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1); - $record = array( + $formatter = new LogstashFormatter('test', null, null, 'ctxt_'); + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['key' => 'pair'], 'message' => 'log', - ); + ]; $message = json_decode($formatter->format($record), true); @@ -268,7 +128,7 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase $this->assertEquals('pair', $message['key']); // Test with extraPrefix - $formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_', LogstashFormatter::V1); + $formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_'); $message = json_decode($formatter->format($record), true); $this->assertArrayHasKey('EXTkey', $message); @@ -277,16 +137,16 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithApplicationNameV1() { - $formatter = new LogstashFormatter('app', 'test', null, 'ctxt_', LogstashFormatter::V1); - $record = array( + $formatter = new LogstashFormatter('app', 'test', null, 'ctxt_'); + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('key' => 'pair'), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['key' => 'pair'], 'message' => 'log', - ); + ]; $message = json_decode($formatter->format($record), true); @@ -296,38 +156,27 @@ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithLatin9Data() { - if (version_compare(PHP_VERSION, '5.5.0', '<')) { - // Ignore the warning that will be emitted by PHP <5.5.0 - \PHPUnit_Framework_Error_Warning::$enabled = false; - } $formatter = new LogstashFormatter('test', 'hostname'); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => '¯\_(ツ)_/¯', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array( + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [ 'user_agent' => "\xD6WN; FBCR/OrangeEspa\xF1a; Vers\xE3o/4.0; F\xE4rist", - ), + ], 'message' => 'log', - ); + ]; $message = json_decode($formatter->format($record), true); $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']); - $this->assertEquals('log', $message['@message']); - $this->assertEquals('¯\_(ツ)_/¯', $message['@fields']['channel']); - $this->assertContains('¯\_(ツ)_/¯', $message['@tags']); - $this->assertEquals(Logger::ERROR, $message['@fields']['level']); - $this->assertEquals('test', $message['@type']); - $this->assertEquals('hostname', $message['@source']); - if (version_compare(PHP_VERSION, '5.5.0', '>=')) { - $this->assertEquals('ÖWN; FBCR/OrangeEspaña; Versão/4.0; Färist', $message['@fields']['user_agent']); - } else { - // PHP <5.5 does not return false for an element encoding failure, - // instead it emits a warning (possibly) and nulls the value. - $this->assertEquals(null, $message['@fields']['user_agent']); - } + $this->assertEquals('log', $message['message']); + $this->assertEquals('¯\_(ツ)_/¯', $message['channel']); + $this->assertEquals('ERROR', $message['level']); + $this->assertEquals('test', $message['type']); + $this->assertEquals('hostname', $message['host']); + $this->assertEquals('ÖWN; FBCR/OrangeEspaña; Versão/4.0; Färist', $message['user_agent']); } } diff --git a/tests/Monolog/Formatter/MongoDBFormatterTest.php b/tests/Monolog/Formatter/MongoDBFormatterTest.php index 52e699e..2933497 100644 --- a/tests/Monolog/Formatter/MongoDBFormatterTest.php +++ b/tests/Monolog/Formatter/MongoDBFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -20,17 +20,17 @@ class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase { public function setUp() { - if (!class_exists('MongoDate')) { - $this->markTestSkipped('mongo extension not installed'); + if (!class_exists('MongoDB\BSON\UTCDateTime')) { + $this->markTestSkipped('ext-mongodb not installed'); } } public function constructArgumentProvider() { - return array( - array(1, true, 1, true), - array(0, false, 0, false), - ); + return [ + [1, true, 1, true], + [0, false, 0, false], + ]; } /** @@ -56,28 +56,28 @@ class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase public function testSimpleFormat() { - $record = array( + $record = [ 'message' => 'some log message', - 'context' => array(), + 'context' => [], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'test', - 'datetime' => new \DateTime('2014-02-01 00:00:00'), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'), + 'extra' => [], + ]; $formatter = new MongoDBFormatter(); $formattedRecord = $formatter->format($record); $this->assertCount(7, $formattedRecord); $this->assertEquals('some log message', $formattedRecord['message']); - $this->assertEquals(array(), $formattedRecord['context']); + $this->assertEquals([], $formattedRecord['context']); $this->assertEquals(Logger::WARNING, $formattedRecord['level']); $this->assertEquals(Logger::getLevelName(Logger::WARNING), $formattedRecord['level_name']); $this->assertEquals('test', $formattedRecord['channel']); - $this->assertInstanceOf('\MongoDate', $formattedRecord['datetime']); - $this->assertEquals('0.00000000 1391212800', $formattedRecord['datetime']->__toString()); - $this->assertEquals(array(), $formattedRecord['extra']); + $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $formattedRecord['datetime']); + $this->assertEquals('1453410690123', $formattedRecord['datetime']->__toString()); + $this->assertEquals([], $formattedRecord['extra']); } public function testRecursiveFormat() @@ -86,34 +86,35 @@ class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase $someObject->foo = 'something'; $someObject->bar = 'stuff'; - $record = array( + $record = [ 'message' => 'some log message', - 'context' => array( - 'stuff' => new \DateTime('2014-02-01 02:31:33'), + 'context' => [ + 'stuff' => new \DateTimeImmutable('1969-01-21T21:11:30.123456+00:00'), 'some_object' => $someObject, 'context_string' => 'some string', 'context_int' => 123456, 'except' => new \Exception('exception message', 987), - ), + ], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'test', - 'datetime' => new \DateTime('2014-02-01 00:00:00'), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'), + 'extra' => [], + ]; $formatter = new MongoDBFormatter(); $formattedRecord = $formatter->format($record); $this->assertCount(5, $formattedRecord['context']); - $this->assertInstanceOf('\MongoDate', $formattedRecord['context']['stuff']); - $this->assertEquals('0.00000000 1391221893', $formattedRecord['context']['stuff']->__toString()); + $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $formattedRecord['context']['stuff']); + $this->assertEquals('-29731710123', $formattedRecord['context']['stuff']->__toString()); + $this->assertEquals( - array( + [ 'foo' => 'something', 'bar' => 'stuff', 'class' => 'stdClass', - ), + ], $formattedRecord['context']['some_object'] ); $this->assertEquals('some string', $formattedRecord['context']['context_string']); @@ -130,75 +131,75 @@ class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatDepthArray() { - $record = array( + $record = [ 'message' => 'some log message', - 'context' => array( - 'nest2' => array( + 'context' => [ + 'nest2' => [ 'property' => 'anything', - 'nest3' => array( + 'nest3' => [ 'nest4' => 'value', 'property' => 'nothing', - ), - ), - ), + ], + ], + ], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'test', - 'datetime' => new \DateTime('2014-02-01 00:00:00'), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'), + 'extra' => [], + ]; $formatter = new MongoDBFormatter(2); $formattedResult = $formatter->format($record); $this->assertEquals( - array( - 'nest2' => array( + [ + 'nest2' => [ 'property' => 'anything', 'nest3' => '[...]', - ), - ), + ], + ], $formattedResult['context'] ); } public function testFormatDepthArrayInfiniteNesting() { - $record = array( + $record = [ 'message' => 'some log message', - 'context' => array( - 'nest2' => array( + 'context' => [ + 'nest2' => [ 'property' => 'something', - 'nest3' => array( + 'nest3' => [ 'property' => 'anything', - 'nest4' => array( + 'nest4' => [ 'property' => 'nothing', - ), - ), - ), - ), + ], + ], + ], + ], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'test', - 'datetime' => new \DateTime('2014-02-01 00:00:00'), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'), + 'extra' => [], + ]; $formatter = new MongoDBFormatter(0); $formattedResult = $formatter->format($record); $this->assertEquals( - array( - 'nest2' => array( + [ + 'nest2' => [ 'property' => 'something', - 'nest3' => array( + 'nest3' => [ 'property' => 'anything', - 'nest4' => array( + 'nest4' => [ 'property' => 'nothing', - ), - ), - ), - ), + ], + ], + ], + ], $formattedResult['context'] ); } @@ -211,46 +212,46 @@ class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase $someObject->nest3->property = 'nothing'; $someObject->nest3->nest4 = 'invisible'; - $record = array( + $record = [ 'message' => 'some log message', - 'context' => array( + 'context' => [ 'nest2' => $someObject, - ), + ], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'test', - 'datetime' => new \DateTime('2014-02-01 00:00:00'), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'), + 'extra' => [], + ]; $formatter = new MongoDBFormatter(2, true); $formattedResult = $formatter->format($record); $this->assertEquals( - array( - 'nest2' => array( + [ + 'nest2' => [ 'property' => 'anything', 'nest3' => '[...]', 'class' => 'stdClass', - ), - ), + ], + ], $formattedResult['context'] ); } public function testFormatDepthException() { - $record = array( + $record = [ 'message' => 'some log message', - 'context' => array( + 'context' => [ 'nest2' => new \Exception('exception message', 987), - ), + ], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'test', - 'datetime' => new \DateTime('2014-02-01 00:00:00'), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable('2016-01-21T21:11:30.123456+00:00'), + 'extra' => [], + ]; $formatter = new MongoDBFormatter(2, false); $formattedRecord = $formatter->format($record); diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index 83adb7e..2b2d7c7 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -26,40 +26,40 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase public function testFormat() { $formatter = new NormalizerFormatter('Y-m-d'); - $formatted = $formatter->format(array( + $formatted = $formatter->format([ 'level_name' => 'ERROR', 'channel' => 'meh', 'message' => 'foo', - 'datetime' => new \DateTime, - 'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')), - 'context' => array( + 'datetime' => new \DateTimeImmutable, + 'extra' => ['foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => [], 'res' => fopen('php://memory', 'rb')], + 'context' => [ 'foo' => 'bar', 'baz' => 'qux', 'inf' => INF, '-inf' => -INF, 'nan' => acos(4), - ), - )); + ], + ]); - $this->assertEquals(array( + $this->assertEquals([ 'level_name' => 'ERROR', 'channel' => 'meh', 'message' => 'foo', 'datetime' => date('Y-m-d'), - 'extra' => array( - 'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})', - 'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: bar)', - 'baz' => array(), - 'res' => '[resource] (stream)', - ), - 'context' => array( + 'extra' => [ + 'foo' => ['Monolog\\Formatter\\TestFooNorm' => ["foo" => "fooValue"]], + 'bar' => ['Monolog\\Formatter\\TestBarNorm' => 'bar'], + 'baz' => [], + 'res' => '[resource(stream)]', + ], + 'context' => [ 'foo' => 'bar', 'baz' => 'qux', 'inf' => 'INF', '-inf' => '-INF', 'nan' => 'NaN', - ), - ), $formatted); + ], + ], $formatted); } public function testFormatExceptions() @@ -67,72 +67,72 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $formatter = new NormalizerFormatter('Y-m-d'); $e = new \LogicException('bar'); $e2 = new \RuntimeException('foo', 0, $e); - $formatted = $formatter->format(array( + $formatted = $formatter->format([ 'exception' => $e2, - )); + ]); $this->assertGreaterThan(5, count($formatted['exception']['trace'])); $this->assertTrue(isset($formatted['exception']['previous'])); unset($formatted['exception']['trace'], $formatted['exception']['previous']); - $this->assertEquals(array( - 'exception' => array( + $this->assertEquals([ + 'exception' => [ 'class' => get_class($e2), 'message' => $e2->getMessage(), 'code' => $e2->getCode(), 'file' => $e2->getFile().':'.$e2->getLine(), - ), - ), $formatted); + ], + ], $formatted); } public function testFormatToStringExceptionHandle() { $formatter = new NormalizerFormatter('Y-m-d'); $this->setExpectedException('RuntimeException', 'Could not convert to string'); - $formatter->format(array( + $formatter->format([ 'myObject' => new TestToStringError(), - )); + ]); } public function testBatchFormat() { $formatter = new NormalizerFormatter('Y-m-d'); - $formatted = $formatter->formatBatch(array( - array( + $formatted = $formatter->formatBatch([ + [ 'level_name' => 'CRITICAL', 'channel' => 'test', 'message' => 'bar', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array(), - ), - array( + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => [], + ], + [ 'level_name' => 'WARNING', 'channel' => 'log', 'message' => 'foo', - 'context' => array(), - 'datetime' => new \DateTime, - 'extra' => array(), - ), - )); - $this->assertEquals(array( - array( + 'context' => [], + 'datetime' => new \DateTimeImmutable, + 'extra' => [], + ], + ]); + $this->assertEquals([ + [ 'level_name' => 'CRITICAL', 'channel' => 'test', 'message' => 'bar', - 'context' => array(), + 'context' => [], 'datetime' => date('Y-m-d'), - 'extra' => array(), - ), - array( + 'extra' => [], + ], + [ 'level_name' => 'WARNING', 'channel' => 'log', 'message' => 'foo', - 'context' => array(), + 'context' => [], 'datetime' => date('Y-m-d'), - 'extra' => array(), - ), - ), $formatted); + 'extra' => [], + ], + ], $formatted); } /** @@ -159,11 +159,20 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); - $res = $reflMethod->invoke($formatter, array($foo, $bar), true); + $res = $reflMethod->invoke($formatter, [$foo, $bar], true); restore_error_handler(); - $this->assertEquals(@json_encode(array($foo, $bar)), $res); + $this->assertEquals(@json_encode([$foo, $bar]), $res); + } + + public function testCanNormalizeReferences() + { + $formatter = new NormalizerFormatter(); + $x = ['foo' => 'bar']; + $y = ['x' => &$x]; + $x['y'] = &$y; + $formatter->format($y); } public function testIgnoresInvalidTypes() @@ -183,11 +192,11 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); - $res = $reflMethod->invoke($formatter, array($resource), true); + $res = $reflMethod->invoke($formatter, [$resource], true); restore_error_handler(); - $this->assertEquals(@json_encode(array($resource)), $res); + $this->assertEquals(@json_encode([$resource]), $res); } /** @@ -195,10 +204,6 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase */ public function testThrowsOnInvalidEncoding() { - if (version_compare(PHP_VERSION, '5.5.0', '<')) { - // Ignore the warning that will be emitted by PHP <5.5.0 - \PHPUnit_Framework_Error_Warning::$enabled = false; - } $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); @@ -206,31 +211,18 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase // send an invalid unicode sequence as a object that can't be cleaned $record = new \stdClass; $record->message = "\xB1\x31"; - $res = $reflMethod->invoke($formatter, $record); - if (PHP_VERSION_ID < 50500 && $res === '{"message":null}') { - throw new \RuntimeException('PHP 5.3/5.4 throw a warning and null the value instead of returning false entirely'); - } + $reflMethod->invoke($formatter, $record); } public function testConvertsInvalidEncodingAsLatin9() { - if (version_compare(PHP_VERSION, '5.5.0', '<')) { - // Ignore the warning that will be emitted by PHP <5.5.0 - \PHPUnit_Framework_Error_Warning::$enabled = false; - } $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); - $res = $reflMethod->invoke($formatter, array('message' => "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE")); + $res = $reflMethod->invoke($formatter, ['message' => "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE"]); - if (version_compare(PHP_VERSION, '5.5.0', '>=')) { - $this->assertSame('{"message":"€ŠšŽžŒœŸ"}', $res); - } else { - // PHP <5.5 does not return false for an element encoding failure, - // instead it emits a warning (possibly) and nulls the value. - $this->assertSame('{"message":null}', $res); - } + $this->assertSame('{"message":"€ŠšŽžŒœŸ"}', $res); } /** @@ -250,19 +242,19 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase { $obj = new \stdClass; - return array( - 'null' => array(null, null), - 'int' => array(123, 123), - 'float' => array(123.45, 123.45), - 'bool false' => array(false, false), - 'bool true' => array(true, true), - 'ascii string' => array('abcdef', 'abcdef'), - 'latin9 string' => array("\xB1\x31\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xFF", '±1€ŠšŽžŒœŸÿ'), - 'unicode string' => array('¤¦¨´¸¼½¾€ŠšŽžŒœŸ', '¤¦¨´¸¼½¾€ŠšŽžŒœŸ'), - 'empty array' => array(array(), array()), - 'array' => array(array('abcdef'), array('abcdef')), - 'object' => array($obj, $obj), - ); + return [ + 'null' => [null, null], + 'int' => [123, 123], + 'float' => [123.45, 123.45], + 'bool false' => [false, false], + 'bool true' => [true, true], + 'ascii string' => ['abcdef', 'abcdef'], + 'latin9 string' => ["\xB1\x31\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xFF", '±1€ŠšŽžŒœŸÿ'], + 'unicode string' => ['¤¦¨´¸¼½¾€ŠšŽžŒœŸ', '¤¦¨´¸¼½¾€ŠšŽžŒœŸ'], + 'empty array' => [[], []], + 'array' => [['abcdef'], ['abcdef']], + 'object' => [$obj, $obj], + ]; } /** @@ -282,26 +274,22 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase public function providesHandleJsonErrorFailure() { - return array( - 'depth' => array(JSON_ERROR_DEPTH, 'Maximum stack depth exceeded'), - 'state' => array(JSON_ERROR_STATE_MISMATCH, 'Underflow or the modes mismatch'), - 'ctrl' => array(JSON_ERROR_CTRL_CHAR, 'Unexpected control character found'), - 'default' => array(-1, 'Unknown error'), - ); + return [ + 'depth' => [JSON_ERROR_DEPTH, 'Maximum stack depth exceeded'], + 'state' => [JSON_ERROR_STATE_MISMATCH, 'Underflow or the modes mismatch'], + 'ctrl' => [JSON_ERROR_CTRL_CHAR, 'Unexpected control character found'], + 'default' => [-1, 'Unknown error'], + ]; } + // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered + // and no file or line are included in the trace because it's treated as internal function public function testExceptionTraceWithArgs() { if (defined('HHVM_VERSION')) { $this->markTestSkipped('Not supported in HHVM since it detects errors differently'); } - // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered - // and no file or line are included in the trace because it's treated as internal function - set_error_handler(function ($errno, $errstr, $errfile, $errline) { - throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); - }); - try { // This will contain $resource and $wrappedResource as arguments in the trace item $resource = fopen('php://memory', 'rw+'); @@ -309,25 +297,24 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $wrappedResource = new TestFooNorm; $wrappedResource->foo = $resource; // Just do something stupid with a resource/wrapped resource as argument - array_keys($wrappedResource); - } catch (\Exception $e) { - restore_error_handler(); + $arr = [$wrappedResource, $resource]; + // modifying the array inside throws a "usort(): Array was modified by the user comparison function" + usort($arr, function ($a, $b) { + throw new \ErrorException('Foo'); + }); + } catch (\Throwable $e) { } $formatter = new NormalizerFormatter(); - $record = array('context' => array('exception' => $e)); + $record = ['context' => ['exception' => $e]]; $result = $formatter->format($record); $this->assertRegExp( - '%"resource":"\[resource\] \(stream\)"%', + '%\[resource\(stream\)\]%', $result['context']['exception']['trace'][0] ); - if (version_compare(PHP_VERSION, '5.5.0', '>=')) { - $pattern = '%"wrappedResource":"\[object\] \(Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm: \)"%'; - } else { - $pattern = '%\\\\"foo\\\\":null%'; - } + $pattern = '%\[\{"Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm":"JSON_ERROR"\}%'; // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4 $this->assertRegExp( @@ -339,7 +326,7 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase class TestFooNorm { - public $foo = 'foo'; + public $foo = 'fooValue'; } class TestBarNorm diff --git a/tests/Monolog/Formatter/ScalarFormatterTest.php b/tests/Monolog/Formatter/ScalarFormatterTest.php index b1c8fd4..ea488e5 100644 --- a/tests/Monolog/Formatter/ScalarFormatterTest.php +++ b/tests/Monolog/Formatter/ScalarFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,6 +11,8 @@ namespace Monolog\Formatter; +use Monolog\DateTimeImmutable; + class ScalarFormatterTest extends \PHPUnit_Framework_TestCase { private $formatter; @@ -22,7 +24,7 @@ class ScalarFormatterTest extends \PHPUnit_Framework_TestCase public function buildTrace(\Exception $e) { - $data = array(); + $data = []; $trace = $e->getTrace(); foreach ($trace as $frame) { if (isset($frame['file'])) { @@ -37,74 +39,70 @@ class ScalarFormatterTest extends \PHPUnit_Framework_TestCase public function encodeJson($data) { - if (version_compare(PHP_VERSION, '5.4.0', '>=')) { - return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } - - return json_encode($data); + return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } public function testFormat() { $exception = new \Exception('foo'); - $formatted = $this->formatter->format(array( + $formatted = $this->formatter->format([ 'foo' => 'string', 'bar' => 1, 'baz' => false, - 'bam' => array(1, 2, 3), - 'bat' => array('foo' => 'bar'), - 'bap' => \DateTime::createFromFormat(\DateTime::ISO8601, '1970-01-01T00:00:00+0000'), + 'bam' => [1, 2, 3], + 'bat' => ['foo' => 'bar'], + 'bap' => $dt = new DateTimeImmutable(true), 'ban' => $exception, - )); + ]); - $this->assertSame(array( + $this->assertSame([ 'foo' => 'string', 'bar' => 1, 'baz' => false, - 'bam' => $this->encodeJson(array(1, 2, 3)), - 'bat' => $this->encodeJson(array('foo' => 'bar')), - 'bap' => '1970-01-01 00:00:00', - 'ban' => $this->encodeJson(array( + 'bam' => $this->encodeJson([1, 2, 3]), + 'bat' => $this->encodeJson(['foo' => 'bar']), + 'bap' => (string) $dt, + 'ban' => $this->encodeJson([ 'class' => get_class($exception), 'message' => $exception->getMessage(), 'code' => $exception->getCode(), 'file' => $exception->getFile() . ':' . $exception->getLine(), 'trace' => $this->buildTrace($exception), - )), - ), $formatted); + ]), + ], $formatted); } public function testFormatWithErrorContext() { - $context = array('file' => 'foo', 'line' => 1); - $formatted = $this->formatter->format(array( + $context = ['file' => 'foo', 'line' => 1]; + $formatted = $this->formatter->format([ 'context' => $context, - )); + ]); - $this->assertSame(array( + $this->assertSame([ 'context' => $this->encodeJson($context), - ), $formatted); + ], $formatted); } public function testFormatWithExceptionContext() { $exception = new \Exception('foo'); - $formatted = $this->formatter->format(array( - 'context' => array( + $formatted = $this->formatter->format([ + 'context' => [ 'exception' => $exception, - ), - )); + ], + ]); - $this->assertSame(array( - 'context' => $this->encodeJson(array( - 'exception' => array( + $this->assertSame([ + 'context' => $this->encodeJson([ + 'exception' => [ 'class' => get_class($exception), 'message' => $exception->getMessage(), 'code' => $exception->getCode(), 'file' => $exception->getFile() . ':' . $exception->getLine(), 'trace' => $this->buildTrace($exception), - ), - )), - ), $formatted); + ], + ]), + ], $formatted); } } diff --git a/tests/Monolog/Formatter/WildfireFormatterTest.php b/tests/Monolog/Formatter/WildfireFormatterTest.php index 52f15a3..40ee82c 100644 --- a/tests/Monolog/Formatter/WildfireFormatterTest.php +++ b/tests/Monolog/Formatter/WildfireFormatterTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -21,15 +21,15 @@ class WildfireFormatterTest extends \PHPUnit_Framework_TestCase public function testDefaultFormat() { $wildfire = new WildfireFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('ip' => '127.0.0.1'), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['ip' => '127.0.0.1'], 'message' => 'log', - ); + ]; $message = $wildfire->format($record); @@ -46,15 +46,15 @@ class WildfireFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithFileAndLine() { $wildfire = new WildfireFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('from' => 'logger'), - 'datetime' => new \DateTime("@0"), - 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14), + 'context' => ['from' => 'logger'], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => ['ip' => '127.0.0.1', 'file' => 'test', 'line' => 14], 'message' => 'log', - ); + ]; $message = $wildfire->format($record); @@ -71,15 +71,15 @@ class WildfireFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatWithoutContext() { $wildfire = new WildfireFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; $message = $wildfire->format($record); @@ -96,17 +96,17 @@ class WildfireFormatterTest extends \PHPUnit_Framework_TestCase public function testBatchFormatThrowException() { $wildfire = new WildfireFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array(), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; - $wildfire->formatBatch(array($record)); + $wildfire->formatBatch([$record]); } /** @@ -115,22 +115,22 @@ class WildfireFormatterTest extends \PHPUnit_Framework_TestCase public function testTableFormat() { $wildfire = new WildfireFormatter(); - $record = array( + $record = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'table-channel', - 'context' => array( - WildfireFormatter::TABLE => array( - array('col1', 'col2', 'col3'), - array('val1', 'val2', 'val3'), - array('foo1', 'foo2', 'foo3'), - array('bar1', 'bar2', 'bar3'), - ), - ), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => [ + WildfireFormatter::TABLE => [ + ['col1', 'col2', 'col3'], + ['val1', 'val2', 'val3'], + ['foo1', 'foo2', 'foo3'], + ['bar1', 'bar2', 'bar3'], + ], + ], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'table-message', - ); + ]; $message = $wildfire->format($record); diff --git a/tests/Monolog/Handler/AbstractHandlerTest.php b/tests/Monolog/Handler/AbstractHandlerTest.php index 568eb9d..b7451a7 100644 --- a/tests/Monolog/Handler/AbstractHandlerTest.php +++ b/tests/Monolog/Handler/AbstractHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,10 +11,8 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; -use Monolog\Formatter\LineFormatter; -use Monolog\Processor\WebProcessor; class AbstractHandlerTest extends TestCase { @@ -24,21 +22,17 @@ class AbstractHandlerTest extends TestCase * @covers Monolog\Handler\AbstractHandler::setLevel * @covers Monolog\Handler\AbstractHandler::getBubble * @covers Monolog\Handler\AbstractHandler::setBubble - * @covers Monolog\Handler\AbstractHandler::getFormatter - * @covers Monolog\Handler\AbstractHandler::setFormatter */ public function testConstructAndGetSet() { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false)); + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', [Logger::WARNING, false]); $this->assertEquals(Logger::WARNING, $handler->getLevel()); $this->assertEquals(false, $handler->getBubble()); $handler->setLevel(Logger::ERROR); $handler->setBubble(true); - $handler->setFormatter($formatter = new LineFormatter); $this->assertEquals(Logger::ERROR, $handler->getLevel()); $this->assertEquals(true, $handler->getBubble()); - $this->assertSame($formatter, $handler->getFormatter()); } /** @@ -49,7 +43,7 @@ class AbstractHandlerTest extends TestCase $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); $handler->expects($this->exactly(2)) ->method('handle'); - $handler->handleBatch(array($this->getRecord(), $this->getRecord())); + $handler->handleBatch([$this->getRecord(), $this->getRecord()]); } /** @@ -57,7 +51,7 @@ class AbstractHandlerTest extends TestCase */ public function testIsHandling() { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false)); + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', [Logger::WARNING, false]); $this->assertTrue($handler->isHandling($this->getRecord())); $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG))); } @@ -67,49 +61,9 @@ class AbstractHandlerTest extends TestCase */ public function testHandlesPsrStyleLevels() { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array('warning', false)); + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', ['warning', false]); $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG))); $handler->setLevel('debug'); $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG))); } - - /** - * @covers Monolog\Handler\AbstractHandler::getFormatter - * @covers Monolog\Handler\AbstractHandler::getDefaultFormatter - */ - public function testGetFormatterInitializesDefault() - { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); - $this->assertInstanceOf('Monolog\Formatter\LineFormatter', $handler->getFormatter()); - } - - /** - * @covers Monolog\Handler\AbstractHandler::pushProcessor - * @covers Monolog\Handler\AbstractHandler::popProcessor - * @expectedException LogicException - */ - public function testPushPopProcessor() - { - $logger = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); - $processor1 = new WebProcessor; - $processor2 = new WebProcessor; - - $logger->pushProcessor($processor1); - $logger->pushProcessor($processor2); - - $this->assertEquals($processor2, $logger->popProcessor()); - $this->assertEquals($processor1, $logger->popProcessor()); - $logger->popProcessor(); - } - - /** - * @covers Monolog\Handler\AbstractHandler::pushProcessor - * @expectedException InvalidArgumentException - */ - public function testPushProcessorWithNonCallable() - { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); - - $handler->pushProcessor(new \stdClass()); - } } diff --git a/tests/Monolog/Handler/AbstractProcessingHandlerTest.php b/tests/Monolog/Handler/AbstractProcessingHandlerTest.php index 24d4f63..58d0920 100644 --- a/tests/Monolog/Handler/AbstractProcessingHandlerTest.php +++ b/tests/Monolog/Handler/AbstractProcessingHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,18 +11,30 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Monolog\Processor\WebProcessor; +use Monolog\Formatter\LineFormatter; class AbstractProcessingHandlerTest extends TestCase { /** + * @covers Monolog\Handler\FormattableHandlerTrait::getFormatter + * @covers Monolog\Handler\FormattableHandlerTrait::setFormatter + */ + public function testConstructAndGetSet() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', [Logger::WARNING, false]); + $handler->setFormatter($formatter = new LineFormatter); + $this->assertSame($formatter, $handler->getFormatter()); + } + + /** * @covers Monolog\Handler\AbstractProcessingHandler::handle */ public function testHandleLowerLevelMessage() { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, true)); + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', [Logger::WARNING, true]); $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG))); } @@ -31,7 +43,7 @@ class AbstractProcessingHandlerTest extends TestCase */ public function testHandleBubbling() { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, true)); + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', [Logger::DEBUG, true]); $this->assertFalse($handler->handle($this->getRecord())); } @@ -40,7 +52,7 @@ class AbstractProcessingHandlerTest extends TestCase */ public function testHandleNotBubbling() { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, false)); + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', [Logger::DEBUG, false]); $this->assertTrue($handler->handle($this->getRecord())); } @@ -49,7 +61,7 @@ class AbstractProcessingHandlerTest extends TestCase */ public function testHandleIsFalseWhenNotHandled() { - $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, false)); + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', [Logger::WARNING, false]); $this->assertTrue($handler->handle($this->getRecord())); $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG))); } @@ -60,13 +72,13 @@ class AbstractProcessingHandlerTest extends TestCase public function testProcessRecord() { $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler'); - $handler->pushProcessor(new WebProcessor(array( + $handler->pushProcessor(new WebProcessor([ 'REQUEST_URI' => '', 'REQUEST_METHOD' => '', 'REMOTE_ADDR' => '', 'SERVER_NAME' => '', 'UNIQUE_ID' => '', - ))); + ])); $handledRecord = null; $handler->expects($this->once()) ->method('write') @@ -77,4 +89,44 @@ class AbstractProcessingHandlerTest extends TestCase $handler->handle($this->getRecord()); $this->assertEquals(6, count($handledRecord['extra'])); } + + /** + * @covers Monolog\Handler\ProcessableHandlerTrait::pushProcessor + * @covers Monolog\Handler\ProcessableHandlerTrait::popProcessor + * @expectedException LogicException + */ + public function testPushPopProcessor() + { + $logger = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler'); + $processor1 = new WebProcessor; + $processor2 = new WebProcessor; + + $logger->pushProcessor($processor1); + $logger->pushProcessor($processor2); + + $this->assertEquals($processor2, $logger->popProcessor()); + $this->assertEquals($processor1, $logger->popProcessor()); + $logger->popProcessor(); + } + + /** + * @covers Monolog\Handler\ProcessableHandlerTrait::pushProcessor + * @expectedException TypeError + */ + public function testPushProcessorWithNonCallable() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler'); + + $handler->pushProcessor(new \stdClass()); + } + + /** + * @covers Monolog\Handler\FormattableHandlerTrait::getFormatter + * @covers Monolog\Handler\FormattableHandlerTrait::getDefaultFormatter + */ + public function testGetFormatterInitializesDefault() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler'); + $this->assertInstanceOf(LineFormatter::class, $handler->getFormatter()); + } } diff --git a/tests/Monolog/Handler/AmqpHandlerTest.php b/tests/Monolog/Handler/AmqpHandlerTest.php index 8e0e723..414e64b 100644 --- a/tests/Monolog/Handler/AmqpHandlerTest.php +++ b/tests/Monolog/Handler/AmqpHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Connection\AMQPConnection; @@ -31,43 +31,39 @@ class AmqpHandlerTest extends TestCase $this->markTestSkipped("Please update AMQP to version >= 1.0"); } - $messages = array(); + $messages = []; - $exchange = $this->getMock('AMQPExchange', array('publish', 'setName'), array(), '', false); - $exchange->expects($this->once()) - ->method('setName') - ->with('log') - ; + $exchange = $this->getMock('AMQPExchange', ['publish', 'setName'], [], '', false); $exchange->expects($this->any()) ->method('publish') - ->will($this->returnCallback(function ($message, $routing_key, $flags = 0, $attributes = array()) use (&$messages) { - $messages[] = array($message, $routing_key, $flags, $attributes); + ->will($this->returnCallback(function ($message, $routing_key, $flags = 0, $attributes = []) use (&$messages) { + $messages[] = [$message, $routing_key, $flags, $attributes]; })) ; - $handler = new AmqpHandler($exchange, 'log'); + $handler = new AmqpHandler($exchange); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); - $expected = array( - array( + $expected = [ + [ 'message' => 'test', - 'context' => array( - 'data' => array(), + 'context' => [ + 'data' => [], 'foo' => 34, - ), + ], 'level' => 300, 'level_name' => 'WARNING', 'channel' => 'test', - 'extra' => array(), - ), - 'warn.test', + 'extra' => [], + ], + 'warning.test', 0, - array( + [ 'delivery_mode' => 2, 'content_type' => 'application/json', - ), - ); + ], + ]; $handler->handle($record); @@ -83,43 +79,43 @@ class AmqpHandlerTest extends TestCase $this->markTestSkipped("php-amqplib not installed"); } - $messages = array(); + $messages = []; - $exchange = $this->getMock('PhpAmqpLib\Channel\AMQPChannel', array('basic_publish', '__destruct'), array(), '', false); + $exchange = $this->getMock('PhpAmqpLib\Channel\AMQPChannel', ['basic_publish', '__destruct'], [], '', false); $exchange->expects($this->any()) ->method('basic_publish') ->will($this->returnCallback(function (AMQPMessage $msg, $exchange = "", $routing_key = "", $mandatory = false, $immediate = false, $ticket = null) use (&$messages) { - $messages[] = array($msg, $exchange, $routing_key, $mandatory, $immediate, $ticket); + $messages[] = [$msg, $exchange, $routing_key, $mandatory, $immediate, $ticket]; })) ; $handler = new AmqpHandler($exchange, 'log'); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); - $expected = array( - array( + $expected = [ + [ 'message' => 'test', - 'context' => array( - 'data' => array(), + 'context' => [ + 'data' => [], 'foo' => 34, - ), + ], 'level' => 300, 'level_name' => 'WARNING', 'channel' => 'test', - 'extra' => array(), - ), + 'extra' => [], + ], 'log', - 'warn.test', + 'warning.test', false, false, null, - array( + [ 'delivery_mode' => 2, 'content_type' => 'application/json', - ), - ); + ], + ]; $handler->handle($record); diff --git a/tests/Monolog/Handler/BrowserConsoleHandlerTest.php b/tests/Monolog/Handler/BrowserConsoleHandlerTest.php index ffb1d74..048ee1c 100644 --- a/tests/Monolog/Handler/BrowserConsoleHandlerTest.php +++ b/tests/Monolog/Handler/BrowserConsoleHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -89,7 +89,7 @@ EOF; $handler = new BrowserConsoleHandler(); $handler->setFormatter($this->getIdentityFormatter()); - $handler->handle($this->getRecord(Logger::DEBUG, 'test', array('foo' => 'bar'))); + $handler->handle($this->getRecord(Logger::DEBUG, 'test', ['foo' => 'bar'])); $expected = <<<EOF (function (c) {if (c && c.groupCollapsed) { diff --git a/tests/Monolog/Handler/BufferHandlerTest.php b/tests/Monolog/Handler/BufferHandlerTest.php index da8b3c3..f1338b4 100644 --- a/tests/Monolog/Handler/BufferHandlerTest.php +++ b/tests/Monolog/Handler/BufferHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class BufferHandlerTest extends TestCase @@ -47,7 +47,7 @@ class BufferHandlerTest extends TestCase $handler->handle($this->getRecord(Logger::WARNING)); $handler->handle($this->getRecord(Logger::DEBUG)); $this->shutdownCheckHandler = $test; - register_shutdown_function(array($this, 'checkPropagation')); + register_shutdown_function([$this, 'checkPropagation']); } public function checkPropagation() diff --git a/tests/Monolog/Handler/ChromePHPHandlerTest.php b/tests/Monolog/Handler/ChromePHPHandlerTest.php index ef3cd1c..c79818c 100644 --- a/tests/Monolog/Handler/ChromePHPHandlerTest.php +++ b/tests/Monolog/Handler/ChromePHPHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -32,17 +32,17 @@ class ChromePHPHandlerTest extends TestCase $handler->handle($this->getRecord(Logger::DEBUG)); $handler->handle($this->getRecord(Logger::WARNING)); - $expected = array( - 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array( + $expected = [ + 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode([ 'version' => ChromePHPHandler::VERSION, - 'columns' => array('label', 'log', 'backtrace', 'type'), - 'rows' => array( + 'columns' => ['label', 'log', 'backtrace', 'type'], + 'rows' => [ 'test', 'test', - ), + ], 'request_uri' => '', - )))), - ); + ]))), + ]; $this->assertEquals($expected, $handler->getHeaders()); } @@ -56,33 +56,33 @@ class ChromePHPHandlerTest extends TestCase // overflow chrome headers limit $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 100 * 1024))); - $expected = array( - 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array( + $expected = [ + 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode([ 'version' => ChromePHPHandler::VERSION, - 'columns' => array('label', 'log', 'backtrace', 'type'), - 'rows' => array( - array( + 'columns' => ['label', 'log', 'backtrace', 'type'], + 'rows' => [ + [ 'test', 'test', 'unknown', 'log', - ), - array( + ], + [ 'test', str_repeat('a', 150 * 1024), 'unknown', 'warn', - ), - array( + ], + [ 'monolog', 'Incomplete logs, chrome header size limit reached', 'unknown', 'warn', - ), - ), + ], + ], 'request_uri' => '', - )))), - ); + ]))), + ]; $this->assertEquals($expected, $handler->getHeaders()); } @@ -99,19 +99,19 @@ class ChromePHPHandlerTest extends TestCase $handler2->handle($this->getRecord(Logger::DEBUG)); $handler2->handle($this->getRecord(Logger::WARNING)); - $expected = array( - 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array( + $expected = [ + 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode([ 'version' => ChromePHPHandler::VERSION, - 'columns' => array('label', 'log', 'backtrace', 'type'), - 'rows' => array( + 'columns' => ['label', 'log', 'backtrace', 'type'], + 'rows' => [ 'test', 'test', 'test', 'test', - ), + ], 'request_uri' => '', - )))), - ); + ]))), + ]; $this->assertEquals($expected, $handler2->getHeaders()); } @@ -119,14 +119,14 @@ class ChromePHPHandlerTest extends TestCase class TestChromePHPHandler extends ChromePHPHandler { - protected $headers = array(); + protected $headers = []; public static function reset() { self::$initialized = false; self::$overflowed = false; self::$sendHeaders = true; - self::$json['rows'] = array(); + self::$json['rows'] = []; } protected function sendHeader($header, $content) diff --git a/tests/Monolog/Handler/CouchDBHandlerTest.php b/tests/Monolog/Handler/CouchDBHandlerTest.php index 9fc4b38..f89a130 100644 --- a/tests/Monolog/Handler/CouchDBHandlerTest.php +++ b/tests/Monolog/Handler/CouchDBHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,14 +11,14 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class CouchDBHandlerTest extends TestCase { public function testHandle() { - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); $handler = new CouchDBHandler(); diff --git a/tests/Monolog/Handler/DeduplicationHandlerTest.php b/tests/Monolog/Handler/DeduplicationHandlerTest.php index e2aff86..491fd85 100644 --- a/tests/Monolog/Handler/DeduplicationHandlerTest.php +++ b/tests/Monolog/Handler/DeduplicationHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class DeduplicationHandlerTest extends TestCase @@ -88,10 +88,10 @@ class DeduplicationHandlerTest extends TestCase $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0); $record = $this->getRecord(Logger::ERROR); - $record['datetime']->modify('+62seconds'); + $record['datetime'] = $record['datetime']->modify('+62seconds'); $handler->handle($record); $record = $this->getRecord(Logger::CRITICAL); - $record['datetime']->modify('+62seconds'); + $record['datetime'] = $record['datetime']->modify('+62seconds'); $handler->handle($record); $handler->flush(); @@ -115,13 +115,13 @@ class DeduplicationHandlerTest extends TestCase // handle two records from yesterday, and one recent $record = $this->getRecord(Logger::ERROR); - $record['datetime']->modify('-1day -10seconds'); + $record['datetime'] = $record['datetime']->modify('-1day -10seconds'); $handler->handle($record); $record2 = $this->getRecord(Logger::CRITICAL); - $record2['datetime']->modify('-1day -10seconds'); + $record2['datetime'] = $record2['datetime']->modify('-1day -10seconds'); $handler->handle($record2); $record3 = $this->getRecord(Logger::CRITICAL); - $record3['datetime']->modify('-30seconds'); + $record3['datetime'] = $record3['datetime']->modify('-30seconds'); $handler->handle($record3); // log is written as none of them are duplicate diff --git a/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php b/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php index d67da90..f72f323 100644 --- a/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php +++ b/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class DoctrineCouchDBHandlerTest extends TestCase @@ -26,21 +26,21 @@ class DoctrineCouchDBHandlerTest extends TestCase public function testHandle() { $client = $this->getMockBuilder('Doctrine\\CouchDB\\CouchDBClient') - ->setMethods(array('postDocument')) + ->setMethods(['postDocument']) ->disableOriginalConstructor() ->getMock(); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); - $expected = array( + $expected = [ 'message' => 'test', - 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34), + 'context' => ['data' => ['stdClass' => []], 'foo' => 34], 'level' => Logger::WARNING, 'level_name' => 'WARNING', 'channel' => 'test', - 'datetime' => $record['datetime']->format('Y-m-d H:i:s'), - 'extra' => array(), - ); + 'datetime' => (string) $record['datetime'], + 'extra' => [], + ]; $client->expects($this->once()) ->method('postDocument') diff --git a/tests/Monolog/Handler/DynamoDbHandlerTest.php b/tests/Monolog/Handler/DynamoDbHandlerTest.php index f3a6968..652dc96 100644 --- a/tests/Monolog/Handler/DynamoDbHandlerTest.php +++ b/tests/Monolog/Handler/DynamoDbHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; class DynamoDbHandlerTest extends TestCase { @@ -24,7 +24,7 @@ class DynamoDbHandlerTest extends TestCase } $this->client = $this->getMockBuilder('Aws\DynamoDb\DynamoDbClient') - ->setMethods(array('formatAttributes', '__call')) + ->setMethods(['formatAttributes', '__call']) ->disableOriginalConstructor()->getMock(); } @@ -48,7 +48,7 @@ class DynamoDbHandlerTest extends TestCase { $record = $this->getRecord(); $formatter = $this->getMock('Monolog\Formatter\FormatterInterface'); - $formatted = array('foo' => 1, 'bar' => 2); + $formatted = ['foo' => 1, 'bar' => 2]; $handler = new DynamoDbHandler($this->client, 'foo'); $handler->setFormatter($formatter); @@ -65,10 +65,10 @@ class DynamoDbHandlerTest extends TestCase $this->client ->expects($this->once()) ->method('__call') - ->with('putItem', array(array( + ->with('putItem', [[ 'TableName' => 'foo', 'Item' => $formatted, - ))); + ]]); $handler->handle($record); } diff --git a/tests/Monolog/Handler/ElasticSearchHandlerTest.php b/tests/Monolog/Handler/ElasticSearchHandlerTest.php index 1687074..c92a72b 100644 --- a/tests/Monolog/Handler/ElasticSearchHandlerTest.php +++ b/tests/Monolog/Handler/ElasticSearchHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,7 +13,7 @@ namespace Monolog\Handler; use Monolog\Formatter\ElasticaFormatter; use Monolog\Formatter\NormalizerFormatter; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Elastica\Client; use Elastica\Request; @@ -29,10 +29,10 @@ class ElasticSearchHandlerTest extends TestCase /** * @var array Default handler options */ - protected $options = array( + protected $options = [ 'index' => 'my_index', 'type' => 'doc_type', - ); + ]; public function setUp() { @@ -43,7 +43,7 @@ class ElasticSearchHandlerTest extends TestCase // base mock Elastica Client object $this->client = $this->getMockBuilder('Elastica\Client') - ->setMethods(array('addDocuments')) + ->setMethods(['addDocuments']) ->disableOriginalConstructor() ->getMock(); } @@ -57,19 +57,19 @@ class ElasticSearchHandlerTest extends TestCase public function testHandle() { // log message - $msg = array( + $msg = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => ['foo' => 7, 'bar', 'class' => new \stdClass], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; // format expected result $formatter = new ElasticaFormatter($this->options['index'], $this->options['type']); - $expected = array($formatter->format($msg)); + $expected = [$formatter->format($msg)]; // setup ES client mock $this->client->expects($this->any()) @@ -79,7 +79,7 @@ class ElasticSearchHandlerTest extends TestCase // perform tests $handler = new ElasticSearchHandler($this->client, $this->options); $handler->handle($msg); - $handler->handleBatch(array($msg)); + $handler->handleBatch([$msg]); } /** @@ -113,11 +113,11 @@ class ElasticSearchHandlerTest extends TestCase */ public function testOptions() { - $expected = array( + $expected = [ 'index' => $this->options['index'], 'type' => $this->options['type'], 'ignore_error' => false, - ); + ]; $handler = new ElasticSearchHandler($this->client, $this->options); $this->assertEquals($expected, $handler->getOptions()); } @@ -128,9 +128,9 @@ class ElasticSearchHandlerTest extends TestCase */ public function testConnectionErrors($ignore, $expectedError) { - $clientOpts = array('host' => '127.0.0.1', 'port' => 1); + $clientOpts = ['host' => '127.0.0.1', 'port' => 1]; $client = new Client($clientOpts); - $handlerOpts = array('ignore_error' => $ignore); + $handlerOpts = ['ignore_error' => $ignore]; $handler = new ElasticSearchHandler($client, $handlerOpts); if ($expectedError) { @@ -146,10 +146,10 @@ class ElasticSearchHandlerTest extends TestCase */ public function providerTestConnectionErrors() { - return array( - array(false, array('RuntimeException', 'Error sending messages to Elasticsearch')), - array(true, false), - ); + return [ + [false, ['RuntimeException', 'Error sending messages to Elasticsearch']], + [true, false], + ]; } /** @@ -162,28 +162,28 @@ class ElasticSearchHandlerTest extends TestCase */ public function testHandleIntegration() { - $msg = array( + $msg = [ 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass), - 'datetime' => new \DateTime("@0"), - 'extra' => array(), + 'context' => ['foo' => 7, 'bar', 'class' => new \stdClass], + 'datetime' => new \DateTimeImmutable("@0"), + 'extra' => [], 'message' => 'log', - ); + ]; $expected = $msg; $expected['datetime'] = $msg['datetime']->format(\DateTime::ISO8601); - $expected['context'] = array( + $expected['context'] = [ 'class' => '[object] (stdClass: {})', 'foo' => 7, 0 => 'bar', - ); + ]; $client = new Client(); $handler = new ElasticSearchHandler($client, $this->options); try { - $handler->handleBatch(array($msg)); + $handler->handleBatch([$msg]); } catch (\RuntimeException $e) { $this->markTestSkipped("Cannot connect to Elastic Search server on localhost"); } @@ -234,6 +234,6 @@ class ElasticSearchHandlerTest extends TestCase return $data['_source']; } - return array(); + return []; } } diff --git a/tests/Monolog/Handler/ErrorLogHandlerTest.php b/tests/Monolog/Handler/ErrorLogHandlerTest.php index 99785cb..d230fb1 100644 --- a/tests/Monolog/Handler/ErrorLogHandlerTest.php +++ b/tests/Monolog/Handler/ErrorLogHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Monolog\Formatter\LineFormatter; @@ -24,7 +24,7 @@ class ErrorLogHandlerTest extends TestCase { protected function setUp() { - $GLOBALS['error_log'] = array(); + $GLOBALS['error_log'] = []; } /** diff --git a/tests/Monolog/Handler/FilterHandlerTest.php b/tests/Monolog/Handler/FilterHandlerTest.php index 31b7686..0e64e76 100644 --- a/tests/Monolog/Handler/FilterHandlerTest.php +++ b/tests/Monolog/Handler/FilterHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Handler; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; class FilterHandlerTest extends TestCase { @@ -63,7 +63,7 @@ class FilterHandlerTest extends TestCase $this->assertFalse($test->hasEmergencyRecords()); $test = new TestHandler(); - $handler = new FilterHandler($test, array(Logger::INFO, Logger::ERROR)); + $handler = new FilterHandler($test, [Logger::INFO, Logger::ERROR]); $handler->handle($this->getRecord(Logger::DEBUG)); $this->assertFalse($test->hasDebugRecords()); @@ -86,14 +86,14 @@ class FilterHandlerTest extends TestCase $test = new TestHandler(); $handler = new FilterHandler($test); - $levels = array(Logger::INFO, Logger::ERROR); + $levels = [Logger::INFO, Logger::ERROR]; $handler->setAcceptedLevels($levels); $this->assertSame($levels, $handler->getAcceptedLevels()); - $handler->setAcceptedLevels(array('info', 'error')); + $handler->setAcceptedLevels(['info', 'error']); $this->assertSame($levels, $handler->getAcceptedLevels()); - $levels = array(Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY); + $levels = [Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY]; $handler->setAcceptedLevels(Logger::CRITICAL, Logger::EMERGENCY); $this->assertSame($levels, $handler->getAcceptedLevels()); diff --git a/tests/Monolog/Handler/FingersCrossedHandlerTest.php b/tests/Monolog/Handler/FingersCrossedHandlerTest.php index b92bf43..5b25a36 100644 --- a/tests/Monolog/Handler/FingersCrossedHandlerTest.php +++ b/tests/Monolog/Handler/FingersCrossedHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy; @@ -114,8 +114,8 @@ class FingersCrossedHandlerTest extends TestCase { $test = new TestHandler(); $handler = new FingersCrossedHandler(function ($record, $handler) use ($test) { - return $test; - }); + return $test; + }); $handler->handle($this->getRecord(Logger::DEBUG)); $handler->handle($this->getRecord(Logger::INFO)); $this->assertFalse($test->hasDebugRecords()); @@ -133,8 +133,8 @@ class FingersCrossedHandlerTest extends TestCase public function testHandleWithBadCallbackThrowsException() { $handler = new FingersCrossedHandler(function ($record, $handler) { - return 'foo'; - }); + return 'foo'; + }); $handler->handle($this->getRecord(Logger::WARNING)); } @@ -203,7 +203,7 @@ class FingersCrossedHandlerTest extends TestCase public function testChannelLevelActivationStrategy() { $test = new TestHandler(); - $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy(Logger::ERROR, array('othertest' => Logger::DEBUG))); + $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy(Logger::ERROR, ['othertest' => Logger::DEBUG])); $handler->handle($this->getRecord(Logger::WARNING)); $this->assertFalse($test->hasWarningRecords()); $record = $this->getRecord(Logger::DEBUG); @@ -220,7 +220,7 @@ class FingersCrossedHandlerTest extends TestCase public function testChannelLevelActivationStrategyWithPsrLevels() { $test = new TestHandler(); - $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy('error', array('othertest' => 'debug'))); + $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy('error', ['othertest' => 'debug'])); $handler->handle($this->getRecord(Logger::WARNING)); $this->assertFalse($test->hasWarningRecords()); $record = $this->getRecord(Logger::DEBUG); diff --git a/tests/Monolog/Handler/FirePHPHandlerTest.php b/tests/Monolog/Handler/FirePHPHandlerTest.php index 0eb10a6..b62e7fd 100644 --- a/tests/Monolog/Handler/FirePHPHandlerTest.php +++ b/tests/Monolog/Handler/FirePHPHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -32,13 +32,13 @@ class FirePHPHandlerTest extends TestCase $handler->handle($this->getRecord(Logger::DEBUG)); $handler->handle($this->getRecord(Logger::WARNING)); - $expected = array( + $expected = [ 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2', 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1', 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3', 'X-Wf-1-1-1-1' => 'test', 'X-Wf-1-1-1-2' => 'test', - ); + ]; $this->assertEquals($expected, $handler->getHeaders()); } @@ -55,18 +55,18 @@ class FirePHPHandlerTest extends TestCase $handler2->handle($this->getRecord(Logger::DEBUG)); $handler2->handle($this->getRecord(Logger::WARNING)); - $expected = array( + $expected = [ 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2', 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1', 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3', 'X-Wf-1-1-1-1' => 'test', 'X-Wf-1-1-1-2' => 'test', - ); + ]; - $expected2 = array( + $expected2 = [ 'X-Wf-1-1-1-3' => 'test', 'X-Wf-1-1-1-4' => 'test', - ); + ]; $this->assertEquals($expected, $handler->getHeaders()); $this->assertEquals($expected2, $handler2->getHeaders()); @@ -75,7 +75,7 @@ class FirePHPHandlerTest extends TestCase class TestFirePHPHandler extends FirePHPHandler { - protected $headers = array(); + protected $headers = []; public static function reset() { diff --git a/tests/Monolog/Handler/FleepHookHandlerTest.php b/tests/Monolog/Handler/FleepHookHandlerTest.php index 91cdd31..11b5a65 100644 --- a/tests/Monolog/Handler/FleepHookHandlerTest.php +++ b/tests/Monolog/Handler/FleepHookHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -13,7 +13,7 @@ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; /** * @coversDefaultClass \Monolog\Handler\FleepHookHandler @@ -56,15 +56,15 @@ class FleepHookHandlerTest extends TestCase */ public function testHandlerUsesLineFormatterWhichIgnoresEmptyArrays() { - $record = array( + $record = [ 'message' => 'msg', - 'context' => array(), + 'context' => [], 'level' => Logger::DEBUG, 'level_name' => Logger::getLevelName(Logger::DEBUG), 'channel' => 'channel', - 'datetime' => new \DateTime(), - 'extra' => array(), - ); + 'datetime' => new \DateTimeImmutable(), + 'extra' => [], + ]; $expectedFormatter = new LineFormatter(null, null, true, true); $expected = $expectedFormatter->format($record); diff --git a/tests/Monolog/Handler/FlowdockHandlerTest.php b/tests/Monolog/Handler/FlowdockHandlerTest.php index 4b120d5..8df847a 100644 --- a/tests/Monolog/Handler/FlowdockHandlerTest.php +++ b/tests/Monolog/Handler/FlowdockHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Handler; use Monolog\Formatter\FlowdockFormatter; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -61,11 +61,11 @@ class FlowdockHandlerTest extends TestCase private function createHandler($token = 'myToken') { - $constructorArgs = array($token, Logger::DEBUG); + $constructorArgs = [$token, Logger::DEBUG]; $this->res = fopen('php://memory', 'a'); $this->handler = $this->getMock( '\Monolog\Handler\FlowdockHandler', - array('fsockopen', 'streamSetTimeout', 'closeSocket'), + ['fsockopen', 'streamSetTimeout', 'closeSocket'], $constructorArgs ); diff --git a/tests/Monolog/Handler/GelfHandlerLegacyTest.php b/tests/Monolog/Handler/GelfHandlerLegacyTest.php index 9d007b1..00150a1 100644 --- a/tests/Monolog/Handler/GelfHandlerLegacyTest.php +++ b/tests/Monolog/Handler/GelfHandlerLegacyTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Handler; use Gelf\Message; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Monolog\Formatter\GelfMessageFormatter; diff --git a/tests/Monolog/Handler/GelfHandlerTest.php b/tests/Monolog/Handler/GelfHandlerTest.php index 8cdd64f..bc06fa3 100644 --- a/tests/Monolog/Handler/GelfHandlerTest.php +++ b/tests/Monolog/Handler/GelfHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Handler; use Gelf\Message; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Monolog\Formatter\GelfMessageFormatter; @@ -43,7 +43,7 @@ class GelfHandlerTest extends TestCase protected function getMessagePublisher() { - return $this->getMock('Gelf\Publisher', array('publish'), array(), '', false); + return $this->getMock('Gelf\Publisher', ['publish'], [], '', false); } public function testDebug() diff --git a/tests/Monolog/Handler/GelfMockMessagePublisher.php b/tests/Monolog/Handler/GelfMockMessagePublisher.php index 873d92f..b1e94ed 100644 --- a/tests/Monolog/Handler/GelfMockMessagePublisher.php +++ b/tests/Monolog/Handler/GelfMockMessagePublisher.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/tests/Monolog/Handler/GroupHandlerTest.php b/tests/Monolog/Handler/GroupHandlerTest.php index a1b8617..d0ffdf0 100644 --- a/tests/Monolog/Handler/GroupHandlerTest.php +++ b/tests/Monolog/Handler/GroupHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class GroupHandlerTest extends TestCase @@ -22,7 +22,7 @@ class GroupHandlerTest extends TestCase */ public function testConstructorOnlyTakesHandler() { - new GroupHandler(array(new TestHandler(), "foo")); + new GroupHandler([new TestHandler(), "foo"]); } /** @@ -31,7 +31,7 @@ class GroupHandlerTest extends TestCase */ public function testHandle() { - $testHandlers = array(new TestHandler(), new TestHandler()); + $testHandlers = [new TestHandler(), new TestHandler()]; $handler = new GroupHandler($testHandlers); $handler->handle($this->getRecord(Logger::DEBUG)); $handler->handle($this->getRecord(Logger::INFO)); @@ -47,9 +47,9 @@ class GroupHandlerTest extends TestCase */ public function testHandleBatch() { - $testHandlers = array(new TestHandler(), new TestHandler()); + $testHandlers = [new TestHandler(), new TestHandler()]; $handler = new GroupHandler($testHandlers); - $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO))); + $handler->handleBatch([$this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)]); foreach ($testHandlers as $test) { $this->assertTrue($test->hasDebugRecords()); $this->assertTrue($test->hasInfoRecords()); @@ -62,7 +62,7 @@ class GroupHandlerTest extends TestCase */ public function testIsHandling() { - $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING)); + $testHandlers = [new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING)]; $handler = new GroupHandler($testHandlers); $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR))); $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING))); @@ -75,7 +75,7 @@ class GroupHandlerTest extends TestCase public function testHandleUsesProcessors() { $test = new TestHandler(); - $handler = new GroupHandler(array($test)); + $handler = new GroupHandler([$test]); $handler->pushProcessor(function ($record) { $record['extra']['foo'] = true; @@ -92,14 +92,14 @@ class GroupHandlerTest extends TestCase */ public function testHandleBatchUsesProcessors() { - $testHandlers = array(new TestHandler(), new TestHandler()); + $testHandlers = [new TestHandler(), new TestHandler()]; $handler = new GroupHandler($testHandlers); $handler->pushProcessor(function ($record) { $record['extra']['foo'] = true; return $record; }); - $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO))); + $handler->handleBatch([$this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)]); foreach ($testHandlers as $test) { $this->assertTrue($test->hasDebugRecords()); $this->assertTrue($test->hasInfoRecords()); diff --git a/tests/Monolog/Handler/HandlerWrapperTest.php b/tests/Monolog/Handler/HandlerWrapperTest.php index d8d0452..4a34741 100644 --- a/tests/Monolog/Handler/HandlerWrapperTest.php +++ b/tests/Monolog/Handler/HandlerWrapperTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; /** * @author Alexey Karapetov <alexey@karapetov.com> @@ -37,10 +37,10 @@ class HandlerWrapperTest extends TestCase */ public function trueFalseDataProvider() { - return array( - array(true), - array(false), - ); + return [ + [true], + [false], + ]; } /** @@ -87,44 +87,4 @@ class HandlerWrapperTest extends TestCase $this->assertEquals($result, $this->wrapper->handleBatch($records)); } - - public function testPushProcessor() - { - $processor = function () {}; - $this->handler->expects($this->once()) - ->method('pushProcessor') - ->with($processor); - - $this->assertEquals($this->wrapper, $this->wrapper->pushProcessor($processor)); - } - - public function testPopProcessor() - { - $processor = function () {}; - $this->handler->expects($this->once()) - ->method('popProcessor') - ->willReturn($processor); - - $this->assertEquals($processor, $this->wrapper->popProcessor()); - } - - public function testSetFormatter() - { - $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); - $this->handler->expects($this->once()) - ->method('setFormatter') - ->with($formatter); - - $this->assertEquals($this->wrapper, $this->wrapper->setFormatter($formatter)); - } - - public function testGetFormatter() - { - $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); - $this->handler->expects($this->once()) - ->method('getFormatter') - ->willReturn($formatter); - - $this->assertEquals($formatter, $this->wrapper->getFormatter()); - } } diff --git a/tests/Monolog/Handler/HipChatHandlerTest.php b/tests/Monolog/Handler/HipChatHandlerTest.php index 52dc9da..0d2e8c0 100644 --- a/tests/Monolog/Handler/HipChatHandlerTest.php +++ b/tests/Monolog/Handler/HipChatHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -24,30 +24,6 @@ class HipChatHandlerTest extends TestCase /** @var HipChatHandler */ private $handler; - public function testWriteHeader() - { - $this->createHandler(); - $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); - fseek($this->res, 0); - $content = fread($this->res, 1024); - - $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: api.hipchat.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); - - return $content; - } - - public function testWriteCustomHostHeader() - { - $this->createHandler('myToken', 'room1', 'Monolog', true, 'hipchat.foo.bar'); - $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); - fseek($this->res, 0); - $content = fread($this->res, 1024); - - $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); - - return $content; - } - public function testWriteV2() { $this->createHandler('myToken', 'room1', 'Monolog', false, 'hipchat.foo.bar', 'v2'); @@ -92,18 +68,6 @@ class HipChatHandlerTest extends TestCase $this->assertRegexp('/notify=0&message=test1&message_format=text&color=red&room_id=room1&from=Monolog$/', $content); } - public function testWriteContentV1WithoutName() - { - $this->createHandler('myToken', 'room1', null, false, 'hipchat.foo.bar', 'v1'); - $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); - fseek($this->res, 0); - $content = fread($this->res, 1024); - - $this->assertRegexp('/notify=0&message=test1&message_format=text&color=red&room_id=room1&from=$/', $content); - - return $content; - } - /** * @depends testWriteCustomHostHeader */ @@ -175,16 +139,16 @@ class HipChatHandlerTest extends TestCase public function provideLevelColors() { - return array( - array(Logger::DEBUG, 'gray'), - array(Logger::INFO, 'green'), - array(Logger::WARNING, 'yellow'), - array(Logger::ERROR, 'red'), - array(Logger::CRITICAL, 'red'), - array(Logger::ALERT, 'red'), - array(Logger::EMERGENCY,'red'), - array(Logger::NOTICE, 'green'), - ); + return [ + [Logger::DEBUG, 'gray'], + [Logger::INFO, 'green'], + [Logger::WARNING, 'yellow'], + [Logger::ERROR, 'red'], + [Logger::CRITICAL, 'red'], + [Logger::ALERT, 'red'], + [Logger::EMERGENCY,'red'], + [Logger::NOTICE, 'green'], + ]; } /** @@ -204,45 +168,45 @@ class HipChatHandlerTest extends TestCase public function provideBatchRecords() { - return array( - array( - array( - array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()), - array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()), - array('level' => Logger::CRITICAL, 'message' => 'Everything is broken!', 'level_name' => 'critical', 'datetime' => new \DateTime()), - ), + return [ + [ + [ + ['level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTimeImmutable()], + ['level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTimeImmutable()], + ['level' => Logger::CRITICAL, 'message' => 'Everything is broken!', 'level_name' => 'critical', 'datetime' => new \DateTimeImmutable()], + ], 'red', - ), - array( - array( - array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()), - array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()), - ), + ], + [ + [ + ['level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTimeImmutable()], + ['level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTimeImmutable()], + ], 'yellow', - ), - array( - array( - array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()), - array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()), - ), + ], + [ + [ + ['level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTimeImmutable()], + ['level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTimeImmutable()], + ], 'green', - ), - array( - array( - array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()), - ), + ], + [ + [ + ['level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTimeImmutable()], + ], 'gray', - ), - ); + ], + ]; } private function createHandler($token = 'myToken', $room = 'room1', $name = 'Monolog', $notify = false, $host = 'api.hipchat.com', $version = 'v1') { - $constructorArgs = array($token, $room, $name, $notify, Logger::DEBUG, true, true, 'text', $host, $version); + $constructorArgs = [$token, $room, $name, $notify, Logger::DEBUG, true, true, 'text', $host, $version]; $this->res = fopen('php://memory', 'a'); $this->handler = $this->getMock( '\Monolog\Handler\HipChatHandler', - array('fsockopen', 'streamSetTimeout', 'closeSocket'), + ['fsockopen', 'streamSetTimeout', 'closeSocket'], $constructorArgs ); @@ -263,14 +227,6 @@ class HipChatHandlerTest extends TestCase $this->handler->setFormatter($this->getIdentityFormatter()); } - /** - * @expectedException InvalidArgumentException - */ - public function testCreateWithTooLongName() - { - $hipChatHandler = new HipChatHandler('token', 'room', 'SixteenCharsHere'); - } - public function testCreateWithTooLongNameV2() { // creating a handler with too long of a name but using the v2 api doesn't matter. diff --git a/tests/Monolog/Handler/LogEntriesHandlerTest.php b/tests/Monolog/Handler/LogEntriesHandlerTest.php index b2deb40..b6d2924 100644 --- a/tests/Monolog/Handler/LogEntriesHandlerTest.php +++ b/tests/Monolog/Handler/LogEntriesHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -37,33 +37,33 @@ class LogEntriesHandlerTest extends TestCase fseek($this->res, 0); $content = fread($this->res, 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() { - $records = array( + $records = [ $this->getRecord(), $this->getRecord(), $this->getRecord(), - ); + ]; $this->createHandler(); $this->handler->handleBatch($records); fseek($this->res, 0); $content = fread($this->res, 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() { $useSSL = extension_loaded('openssl'); - $args = array('testToken', $useSSL, Logger::DEBUG, true); + $args = ['testToken', $useSSL, Logger::DEBUG, true]; $this->res = fopen('php://memory', 'a'); $this->handler = $this->getMock( '\Monolog\Handler\LogEntriesHandler', - array('fsockopen', 'streamSetTimeout', 'closeSocket'), + ['fsockopen', 'streamSetTimeout', 'closeSocket'], $args ); diff --git a/tests/Monolog/Handler/LogmaticHandlerTest.php b/tests/Monolog/Handler/LogmaticHandlerTest.php new file mode 100644 index 0000000..3948a41 --- /dev/null +++ b/tests/Monolog/Handler/LogmaticHandlerTest.php @@ -0,0 +1,84 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Test\TestCase; +use Monolog\Logger; + +/** + * @author Julien Breux <julien.breux@gmail.com> + */ +class LogmaticHandlerTest extends TestCase +{ + /** + * @var resource + */ + private $res; + + /** + * @var LogmaticHandler + */ + private $handler; + + public function testWriteContent() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Critical write test')); + + 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"}/', $content); + } + + public function testWriteBatchContent() + { + $records = [ + $this->getRecord(), + $this->getRecord(), + $this->getRecord(), + ]; + $this->createHandler(); + $this->handler->handleBatch($records); + + 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"}/', $content); + } + + private function createHandler() + { + $useSSL = extension_loaded('openssl'); + $args = ['testToken', 'testHostname', 'testAppname', $useSSL, Logger::DEBUG, true]; + $this->res = fopen('php://memory', 'a'); + $this->handler = $this->getMock( + '\Monolog\Handler\LogmaticHandler', + ['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->res)); + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + $this->handler->expects($this->any()) + ->method('closeSocket') + ->will($this->returnValue(true)); + } +} diff --git a/tests/Monolog/Handler/MailHandlerTest.php b/tests/Monolog/Handler/MailHandlerTest.php index 6754f3d..ee686ad 100644 --- a/tests/Monolog/Handler/MailHandlerTest.php +++ b/tests/Monolog/Handler/MailHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Handler; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; class MailHandlerTest extends TestCase { @@ -25,7 +25,7 @@ class MailHandlerTest extends TestCase $formatter->expects($this->once()) ->method('formatBatch'); // Each record is formatted - $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler', [], '', true, true, true, ['send', 'write']); $handler->expects($this->once()) ->method('send'); $handler->expects($this->never()) @@ -41,11 +41,11 @@ class MailHandlerTest extends TestCase */ public function testHandleBatchNotSendsMailIfMessagesAreBelowLevel() { - $records = array( + $records = [ $this->getRecord(Logger::DEBUG, 'debug message 1'), $this->getRecord(Logger::DEBUG, 'debug message 2'), $this->getRecord(Logger::INFO, 'information'), - ); + ]; $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); $handler->expects($this->never()) @@ -61,10 +61,11 @@ class MailHandlerTest extends TestCase public function testHandle() { $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler->setFormatter(new \Monolog\Formatter\LineFormatter); $record = $this->getRecord(); - $records = array($record); - $records[0]['formatted'] = '['.$record['datetime']->format('Y-m-d H:i:s').'] test.WARNING: test [] []'."\n"; + $records = [$record]; + $records[0]['formatted'] = '['.$record['datetime'].'] test.WARNING: test [] []'."\n"; $handler->expects($this->once()) ->method('send') diff --git a/tests/Monolog/Handler/MockRavenClient.php b/tests/Monolog/Handler/MockRavenClient.php index a083322..d344d34 100644 --- a/tests/Monolog/Handler/MockRavenClient.php +++ b/tests/Monolog/Handler/MockRavenClient.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/tests/Monolog/Handler/MongoDBHandlerTest.php b/tests/Monolog/Handler/MongoDBHandlerTest.php index 0fdef63..7333ef6 100644 --- a/tests/Monolog/Handler/MongoDBHandlerTest.php +++ b/tests/Monolog/Handler/MongoDBHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,8 +11,9 @@ namespace Monolog\Handler; -use Monolog\TestCase; -use Monolog\Logger; +use MongoDB\Driver\Manager; +use Monolog\Test\TestCase; +use Monolog\Formatter\NormalizerFormatter; class MongoDBHandlerTest extends TestCase { @@ -21,45 +22,57 @@ class MongoDBHandlerTest extends TestCase */ public function testConstructorShouldThrowExceptionForInvalidMongo() { - new MongoDBHandler(new \stdClass(), 'DB', 'Collection'); + new MongoDBHandler(new \stdClass, 'db', 'collection'); } - public function testHandle() + public function testHandleWithLibraryClient() { - $mongo = $this->getMock('Mongo', array('selectCollection'), array(), '', false); - $collection = $this->getMock('stdClass', array('save')); + if (!(class_exists('MongoDB\Client'))) { + $this->markTestSkipped('mongodb/mongodb not installed'); + } + + $mongodb = $this->getMockBuilder('MongoDB\Client') + ->disableOriginalConstructor() + ->getMock(); - $mongo->expects($this->once()) + $collection = $this->getMockBuilder('MongoDB\Collection') + ->disableOriginalConstructor() + ->getMock(); + + $mongodb->expects($this->once()) ->method('selectCollection') - ->with('DB', 'Collection') + ->with('db', 'collection') ->will($this->returnValue($collection)); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); - - $expected = array( - 'message' => 'test', - 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34), - 'level' => Logger::WARNING, - 'level_name' => 'WARNING', - 'channel' => 'test', - 'datetime' => $record['datetime']->format('Y-m-d H:i:s'), - 'extra' => array(), - ); + $record = $this->getRecord(); + $expected = $record; + $expected['datetime'] = $record['datetime']->format(NormalizerFormatter::SIMPLE_DATE); $collection->expects($this->once()) - ->method('save') + ->method('insertOne') ->with($expected); - $handler = new MongoDBHandler($mongo, 'DB', 'Collection'); + $handler = new MongoDBHandler($mongodb, 'db', 'collection'); $handler->handle($record); } -} -if (!class_exists('Mongo')) { - class Mongo + public function testHandleWithDriverManager() { - public function selectCollection() - { + if (!(class_exists('MongoDB\Driver\Manager'))) { + $this->markTestSkipped('ext-mongodb not installed'); + } + + /* This can become a unit test once ManagerInterface can be mocked. + * See: https://jira.mongodb.org/browse/PHPC-378 + */ + $mongodb = new Manager('mongodb://localhost:27017'); + $handler = new MongoDBHandler($mongodb, 'test', 'monolog'); + $record = $this->getRecord(); + + try { + $handler->handle($record); + } catch (\RuntimeException $e) { + $this->markTestSkipped('Could not connect to MongoDB server on mongodb://localhost:27017'); } } } diff --git a/tests/Monolog/Handler/NativeMailerHandlerTest.php b/tests/Monolog/Handler/NativeMailerHandlerTest.php index ddf545d..d4aef95 100644 --- a/tests/Monolog/Handler/NativeMailerHandlerTest.php +++ b/tests/Monolog/Handler/NativeMailerHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use InvalidArgumentException; @@ -24,7 +24,7 @@ class NativeMailerHandlerTest extends TestCase { protected function setUp() { - $GLOBALS['mail'] = array(); + $GLOBALS['mail'] = []; } /** @@ -50,7 +50,7 @@ class NativeMailerHandlerTest extends TestCase public function testSetterArrayHeaderInjection() { $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org'); - $mailer->addHeader(array("Content-Type: text/html\r\nFrom: faked@attacker.org")); + $mailer->addHeader(["Content-Type: text/html\r\nFrom: faked@attacker.org"]); } /** @@ -78,7 +78,8 @@ class NativeMailerHandlerTest extends TestCase $from = 'receiver@example.org'; $mailer = new NativeMailerHandler($to, $subject, $from); - $mailer->handleBatch(array()); + $mailer->setFormatter(new \Monolog\Formatter\LineFormatter); + $mailer->handleBatch([]); // batch is empty, nothing sent $this->assertEmpty($GLOBALS['mail']); diff --git a/tests/Monolog/Handler/NewRelicHandlerTest.php b/tests/Monolog/Handler/NewRelicHandlerTest.php index 4d3a615..a71bbf8 100644 --- a/tests/Monolog/Handler/NewRelicHandlerTest.php +++ b/tests/Monolog/Handler/NewRelicHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class NewRelicHandlerTest extends TestCase @@ -24,7 +24,7 @@ class NewRelicHandlerTest extends TestCase public function setUp() { self::$appname = null; - self::$customParameters = array(); + self::$customParameters = []; self::$transactionName = null; } @@ -46,8 +46,8 @@ class NewRelicHandlerTest extends TestCase public function testThehandlerCanAddContextParamsToTheNewRelicTrace() { $handler = new StubNewRelicHandler(); - $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('a' => 'b'))); - $this->assertEquals(array('context_a' => 'b'), self::$customParameters); + $handler->handle($this->getRecord(Logger::ERROR, 'log message', ['a' => 'b'])); + $this->assertEquals(['context_a' => 'b'], self::$customParameters); } public function testThehandlerCanAddExplodedContextParamsToTheNewRelicTrace() @@ -56,10 +56,10 @@ class NewRelicHandlerTest extends TestCase $handler->handle($this->getRecord( Logger::ERROR, 'log message', - array('a' => array('key1' => 'value1', 'key2' => 'value2')) + ['a' => ['key1' => 'value1', 'key2' => 'value2']] )); $this->assertEquals( - array('context_a_key1' => 'value1', 'context_a_key2' => 'value2'), + ['context_a_key1' => 'value1', 'context_a_key2' => 'value2'], self::$customParameters ); } @@ -67,40 +67,40 @@ class NewRelicHandlerTest extends TestCase public function testThehandlerCanAddExtraParamsToTheNewRelicTrace() { $record = $this->getRecord(Logger::ERROR, 'log message'); - $record['extra'] = array('c' => 'd'); + $record['extra'] = ['c' => 'd']; $handler = new StubNewRelicHandler(); $handler->handle($record); - $this->assertEquals(array('extra_c' => 'd'), self::$customParameters); + $this->assertEquals(['extra_c' => 'd'], self::$customParameters); } public function testThehandlerCanAddExplodedExtraParamsToTheNewRelicTrace() { $record = $this->getRecord(Logger::ERROR, 'log message'); - $record['extra'] = array('c' => array('key1' => 'value1', 'key2' => 'value2')); + $record['extra'] = ['c' => ['key1' => 'value1', 'key2' => 'value2']]; $handler = new StubNewRelicHandler(Logger::ERROR, true, self::$appname, true); $handler->handle($record); $this->assertEquals( - array('extra_c_key1' => 'value1', 'extra_c_key2' => 'value2'), + ['extra_c_key1' => 'value1', 'extra_c_key2' => 'value2'], self::$customParameters ); } public function testThehandlerCanAddExtraContextAndParamsToTheNewRelicTrace() { - $record = $this->getRecord(Logger::ERROR, 'log message', array('a' => 'b')); - $record['extra'] = array('c' => 'd'); + $record = $this->getRecord(Logger::ERROR, 'log message', ['a' => 'b']); + $record['extra'] = ['c' => 'd']; $handler = new StubNewRelicHandler(); $handler->handle($record); - $expected = array( + $expected = [ 'context_a' => 'b', 'extra_c' => 'd', - ); + ]; $this->assertEquals($expected, self::$customParameters); } @@ -131,7 +131,7 @@ class NewRelicHandlerTest extends TestCase public function testTheAppNameCanBeOverriddenFromEachLog() { $handler = new StubNewRelicHandler(Logger::DEBUG, false, 'myAppName'); - $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('appname' => 'logAppName'))); + $handler->handle($this->getRecord(Logger::ERROR, 'log message', ['appname' => 'logAppName'])); $this->assertEquals('logAppName', self::$appname); } @@ -155,7 +155,7 @@ class NewRelicHandlerTest extends TestCase public function testTheTransactionNameCanBeOverriddenFromEachLog() { $handler = new StubNewRelicHandler(Logger::DEBUG, false, null, false, 'myTransaction'); - $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('transaction_name' => 'logTransactName'))); + $handler->handle($this->getRecord(Logger::ERROR, 'log message', ['transaction_name' => 'logTransactName'])); $this->assertEquals('logTransactName', self::$transactionName); } diff --git a/tests/Monolog/Handler/NullHandlerTest.php b/tests/Monolog/Handler/NullHandlerTest.php index 292df78..b7e482b 100644 --- a/tests/Monolog/Handler/NullHandlerTest.php +++ b/tests/Monolog/Handler/NullHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** diff --git a/tests/Monolog/Handler/PHPConsoleHandlerTest.php b/tests/Monolog/Handler/PHPConsoleHandlerTest.php index 152573e..0836b99 100644 --- a/tests/Monolog/Handler/PHPConsoleHandlerTest.php +++ b/tests/Monolog/Handler/PHPConsoleHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -14,11 +14,11 @@ namespace Monolog\Handler; use Exception; use Monolog\ErrorHandler; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; use PhpConsole\Connector; use PhpConsole\Dispatcher\Debug as DebugDispatcher; use PhpConsole\Dispatcher\Errors as ErrorDispatcher; -use PhpConsole\Handler; +use PhpConsole\Handler as VendorPhpConsoleHandler; use PHPUnit_Framework_MockObject_MockObject; /** @@ -52,8 +52,8 @@ class PHPConsoleHandlerTest extends TestCase { return $this->getMockBuilder('PhpConsole\Dispatcher\Debug') ->disableOriginalConstructor() - ->setMethods(array('dispatchDebug')) - ->setConstructorArgs(array($connector, $connector->getDumper())) + ->setMethods(['dispatchDebug']) + ->setConstructorArgs([$connector, $connector->getDumper()]) ->getMock(); } @@ -61,8 +61,8 @@ class PHPConsoleHandlerTest extends TestCase { return $this->getMockBuilder('PhpConsole\Dispatcher\Errors') ->disableOriginalConstructor() - ->setMethods(array('dispatchError', 'dispatchException')) - ->setConstructorArgs(array($connector, $connector->getDumper())) + ->setMethods(['dispatchError', 'dispatchException']) + ->setConstructorArgs([$connector, $connector->getDumper()]) ->getMock(); } @@ -70,7 +70,7 @@ class PHPConsoleHandlerTest extends TestCase { $connector = $this->getMockBuilder('PhpConsole\Connector') ->disableOriginalConstructor() - ->setMethods(array( + ->setMethods([ 'sendMessage', 'onShutDown', 'isActiveClient', @@ -81,7 +81,7 @@ class PHPConsoleHandlerTest extends TestCase 'setAllowedIpMasks', 'setHeadersLimit', 'startEvalRequestsListener', - )) + ]) ->getMock(); $connector->expects($this->any()) @@ -93,17 +93,17 @@ class PHPConsoleHandlerTest extends TestCase protected function getHandlerDefaultOption($name) { - $handler = new PHPConsoleHandler(array(), $this->connector); + $handler = new PHPConsoleHandler([], $this->connector); $options = $handler->getOptions(); return $options[$name]; } - protected function initLogger($handlerOptions = array(), $level = Logger::DEBUG) + protected function initLogger($handlerOptions = [], $level = Logger::DEBUG) { - return new Logger('test', array( + return new Logger('test', [ new PHPConsoleHandler($handlerOptions, $this->connector, $level), - )); + ]); } public function testInitWithDefaultConnector() @@ -114,33 +114,33 @@ class PHPConsoleHandlerTest extends TestCase public function testInitWithCustomConnector() { - $handler = new PHPConsoleHandler(array(), $this->connector); + $handler = new PHPConsoleHandler([], $this->connector); $this->assertEquals(spl_object_hash($this->connector), spl_object_hash($handler->getConnector())); } public function testDebug() { $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with($this->equalTo('test')); - $this->initLogger()->addDebug('test'); + $this->initLogger()->debug('test'); } public function testDebugContextInMessage() { $message = 'test'; $tag = 'tag'; - $context = array($tag, 'custom' => mt_rand()); + $context = [$tag, 'custom' => mt_rand()]; $expectedMessage = $message . ' ' . json_encode(array_slice($context, 1)); $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with( $this->equalTo($expectedMessage), $this->equalTo($tag) ); - $this->initLogger()->addDebug($message, $context); + $this->initLogger()->debug($message, $context); } public function testDebugTags($tagsContextKeys = null) { $expectedTags = mt_rand(); - $logger = $this->initLogger($tagsContextKeys ? array('debugTagsKeysInContext' => $tagsContextKeys) : array()); + $logger = $this->initLogger($tagsContextKeys ? ['debugTagsKeysInContext' => $tagsContextKeys] : []); if (!$tagsContextKeys) { $tagsContextKeys = $this->getHandlerDefaultOption('debugTagsKeysInContext'); } @@ -151,7 +151,7 @@ class PHPConsoleHandlerTest extends TestCase $this->equalTo($expectedTags) ); $this->connector->setDebugDispatcher($debugDispatcher); - $logger->addDebug('test', array($key => $expectedTags)); + $logger->debug('test', [$key => $expectedTags]); } } @@ -168,8 +168,8 @@ class PHPConsoleHandlerTest extends TestCase $this->equalTo($line), $classesPartialsTraceIgnore ?: $this->equalTo($this->getHandlerDefaultOption('classesPartialsTraceIgnore')) ); - $errorHandler = ErrorHandler::register($this->initLogger($classesPartialsTraceIgnore ? array('classesPartialsTraceIgnore' => $classesPartialsTraceIgnore) : array()), false); - $errorHandler->registerErrorHandler(array(), false, E_USER_WARNING); + $errorHandler = ErrorHandler::register($this->initLogger($classesPartialsTraceIgnore ? ['classesPartialsTraceIgnore' => $classesPartialsTraceIgnore] : []), false); + $errorHandler->registerErrorHandler([], false, E_USER_WARNING); $errorHandler->handleError($code, $message, $file, $line); } @@ -183,7 +183,7 @@ class PHPConsoleHandlerTest extends TestCase $handler->log( \Psr\Log\LogLevel::ERROR, sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), - array('exception' => $e) + ['exception' => $e] ); } @@ -192,45 +192,45 @@ class PHPConsoleHandlerTest extends TestCase */ public function testWrongOptionsThrowsException() { - new PHPConsoleHandler(array('xxx' => 1)); + new PHPConsoleHandler(['xxx' => 1]); } public function testOptionEnabled() { $this->debugDispatcher->expects($this->never())->method('dispatchDebug'); - $this->initLogger(array('enabled' => false))->addDebug('test'); + $this->initLogger(['enabled' => false])->debug('test'); } public function testOptionClassesPartialsTraceIgnore() { - $this->testError(array('Class', 'Namespace\\')); + $this->testError(['Class', 'Namespace\\']); } public function testOptionDebugTagsKeysInContext() { - $this->testDebugTags(array('key1', 'key2')); + $this->testDebugTags(['key1', 'key2']); } public function testOptionUseOwnErrorsAndExceptionsHandler() { - $this->initLogger(array('useOwnErrorsHandler' => true, 'useOwnExceptionsHandler' => true)); - $this->assertEquals(array(Handler::getInstance(), 'handleError'), set_error_handler(function () { + $this->initLogger(['useOwnErrorsHandler' => true, 'useOwnExceptionsHandler' => true]); + $this->assertEquals([VendorPhpConsoleHandler::getInstance(), 'handleError'], set_error_handler(function () { })); - $this->assertEquals(array(Handler::getInstance(), 'handleException'), set_exception_handler(function () { + $this->assertEquals([VendorPhpConsoleHandler::getInstance(), 'handleException'], set_exception_handler(function () { })); } public static function provideConnectorMethodsOptionsSets() { - return array( - array('sourcesBasePath', 'setSourcesBasePath', __DIR__), - array('serverEncoding', 'setServerEncoding', 'cp1251'), - array('password', 'setPassword', '******'), - array('enableSslOnlyMode', 'enableSslOnlyMode', true, false), - array('ipMasks', 'setAllowedIpMasks', array('127.0.0.*')), - array('headersLimit', 'setHeadersLimit', 2500), - array('enableEvalListener', 'startEvalRequestsListener', true, false), - ); + return [ + ['sourcesBasePath', 'setSourcesBasePath', __DIR__], + ['serverEncoding', 'setServerEncoding', 'cp1251'], + ['password', 'setPassword', '******'], + ['enableSslOnlyMode', 'enableSslOnlyMode', true, false], + ['ipMasks', 'setAllowedIpMasks', ['127.0.0.*']], + ['headersLimit', 'setHeadersLimit', 2500], + ['enableEvalListener', 'startEvalRequestsListener', true, false], + ]; } /** @@ -242,24 +242,24 @@ class PHPConsoleHandlerTest extends TestCase if ($isArgument) { $expectCall->with($value); } - new PHPConsoleHandler(array($option => $value), $this->connector); + new PHPConsoleHandler([$option => $value], $this->connector); } public function testOptionDetectDumpTraceAndSource() { - new PHPConsoleHandler(array('detectDumpTraceAndSource' => true), $this->connector); + new PHPConsoleHandler(['detectDumpTraceAndSource' => true], $this->connector); $this->assertTrue($this->connector->getDebugDispatcher()->detectTraceAndSource); } public static function provideDumperOptionsValues() { - return array( - array('dumperLevelLimit', 'levelLimit', 1001), - array('dumperItemsCountLimit', 'itemsCountLimit', 1002), - array('dumperItemSizeLimit', 'itemSizeLimit', 1003), - array('dumperDumpSizeLimit', 'dumpSizeLimit', 1004), - array('dumperDetectCallbacks', 'detectCallbacks', true), - ); + return [ + ['dumperLevelLimit', 'levelLimit', 1001], + ['dumperItemsCountLimit', 'itemsCountLimit', 1002], + ['dumperItemSizeLimit', 'itemSizeLimit', 1003], + ['dumperDumpSizeLimit', 'dumpSizeLimit', 1004], + ['dumperDetectCallbacks', 'detectCallbacks', true], + ]; } /** @@ -267,7 +267,7 @@ class PHPConsoleHandlerTest extends TestCase */ public function testDumperOptions($option, $dumperProperty, $value) { - new PHPConsoleHandler(array($option => $value), $this->connector); + new PHPConsoleHandler([$option => $value], $this->connector); $this->assertEquals($value, $this->connector->getDumper()->$dumperProperty); } } diff --git a/tests/Monolog/Handler/ProcessHandlerTest.php b/tests/Monolog/Handler/ProcessHandlerTest.php new file mode 100644 index 0000000..011c7c5 --- /dev/null +++ b/tests/Monolog/Handler/ProcessHandlerTest.php @@ -0,0 +1,195 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Test\TestCase; +use Monolog\Logger; + +class ProcessHandlerTest extends TestCase +{ + /** + * Dummy command to be used by tests that should not fail due to the command. + * + * @var string + */ + const DUMMY_COMMAND = 'echo'; + + /** + * @covers Monolog\Handler\ProcessHandler::__construct + * @covers Monolog\Handler\ProcessHandler::guardAgainstInvalidCommand + * @covers Monolog\Handler\ProcessHandler::guardAgainstInvalidCwd + * @covers Monolog\Handler\ProcessHandler::write + * @covers Monolog\Handler\ProcessHandler::ensureProcessIsStarted + * @covers Monolog\Handler\ProcessHandler::startProcess + * @covers Monolog\Handler\ProcessHandler::handleStartupErrors + */ + public function testWriteOpensProcessAndWritesToStdInOfProcess() + { + $fixtures = [ + 'chuck norris', + 'foobar1337', + ]; + + $mockBuilder = $this->getMockBuilder('Monolog\Handler\ProcessHandler'); + $mockBuilder->setMethods(['writeProcessInput']); + // using echo as command, as it is most probably available + $mockBuilder->setConstructorArgs([self::DUMMY_COMMAND]); + + $handler = $mockBuilder->getMock(); + + $handler->expects($this->exactly(2)) + ->method('writeProcessInput') + ->withConsecutive($this->stringContains($fixtures[0]), $this->stringContains($fixtures[1])); + + /** @var ProcessHandler $handler */ + $handler->handle($this->getRecord(Logger::WARNING, $fixtures[0])); + $handler->handle($this->getRecord(Logger::ERROR, $fixtures[1])); + } + + /** + * Data provider for invalid commands. + * + * @return array + */ + public function invalidCommandProvider() + { + return [ + [1337], + [''], + [null], + [fopen('php://input', 'r')], + ]; + } + + /** + * @dataProvider invalidCommandProvider + * @param mixed $invalidCommand + * @covers Monolog\Handler\ProcessHandler::guardAgainstInvalidCommand + */ + public function testConstructWithInvalidCommandThrowsInvalidArgumentException($invalidCommand) + { + $this->setExpectedException('\InvalidArgumentException'); + new ProcessHandler($invalidCommand, Logger::DEBUG); + } + + /** + * Data provider for invalid CWDs. + * + * @return array + */ + public function invalidCwdProvider() + { + return [ + [1337], + [''], + [fopen('php://input', 'r')], + ]; + } + + /** + * @dataProvider invalidCwdProvider + * @param mixed $invalidCwd + * @covers Monolog\Handler\ProcessHandler::guardAgainstInvalidCwd + */ + public function testConstructWithInvalidCwdThrowsInvalidArgumentException($invalidCwd) + { + $this->setExpectedException('\InvalidArgumentException'); + new ProcessHandler(self::DUMMY_COMMAND, Logger::DEBUG, true, $invalidCwd); + } + + /** + * @covers Monolog\Handler\ProcessHandler::__construct + * @covers Monolog\Handler\ProcessHandler::guardAgainstInvalidCwd + */ + public function testConstructWithValidCwdWorks() + { + $handler = new ProcessHandler(self::DUMMY_COMMAND, Logger::DEBUG, true, sys_get_temp_dir()); + $this->assertInstanceOf( + 'Monolog\Handler\ProcessHandler', + $handler, + 'Constructed handler is not a ProcessHandler.' + ); + } + + /** + * @covers Monolog\Handler\ProcessHandler::handleStartupErrors + */ + public function testStartupWithFailingToSelectErrorStreamThrowsUnexpectedValueException() + { + $mockBuilder = $this->getMockBuilder('Monolog\Handler\ProcessHandler'); + $mockBuilder->setMethods(['selectErrorStream']); + $mockBuilder->setConstructorArgs([self::DUMMY_COMMAND]); + + $handler = $mockBuilder->getMock(); + + $handler->expects($this->once()) + ->method('selectErrorStream') + ->will($this->returnValue(false)); + + $this->setExpectedException('\UnexpectedValueException'); + /** @var ProcessHandler $handler */ + $handler->handle($this->getRecord(Logger::WARNING, 'stream failing, whoops')); + } + + /** + * @covers Monolog\Handler\ProcessHandler::handleStartupErrors + * @covers Monolog\Handler\ProcessHandler::selectErrorStream + */ + public function testStartupWithErrorsThrowsUnexpectedValueException() + { + $handler = new ProcessHandler('>&2 echo "some fake error message"'); + $this->setExpectedException('\UnexpectedValueException'); + $handler->handle($this->getRecord(Logger::WARNING, 'some warning in the house')); + } + + /** + * @covers Monolog\Handler\ProcessHandler::write + */ + public function testWritingWithErrorsOnStdOutOfProcessThrowsInvalidArgumentException() + { + $mockBuilder = $this->getMockBuilder('Monolog\Handler\ProcessHandler'); + $mockBuilder->setMethods(['readProcessErrors']); + // using echo as command, as it is most probably available + $mockBuilder->setConstructorArgs([self::DUMMY_COMMAND]); + + $handler = $mockBuilder->getMock(); + + $handler->expects($this->exactly(2)) + ->method('readProcessErrors') + ->willReturnOnConsecutiveCalls('', $this->returnValue('some fake error message here')); + + $this->setExpectedException('\UnexpectedValueException'); + /** @var ProcessHandler $handler */ + $handler->handle($this->getRecord(Logger::WARNING, 'some test stuff')); + } + + /** + * @covers Monolog\Handler\ProcessHandler::close + */ + public function testCloseClosesProcess() + { + $class = new \ReflectionClass('Monolog\Handler\ProcessHandler'); + $property = $class->getProperty('process'); + $property->setAccessible(true); + + $handler = new ProcessHandler(self::DUMMY_COMMAND); + $handler->handle($this->getRecord(Logger::WARNING, '21 is only the half truth')); + + $process = $property->getValue($handler); + $this->assertTrue(is_resource($process), 'Process is not running although it should.'); + + $handler->close(); + + $process = $property->getValue($handler); + $this->assertFalse(is_resource($process), 'Process is still running although it should not.'); + } +} diff --git a/tests/Monolog/Handler/PsrHandlerTest.php b/tests/Monolog/Handler/PsrHandlerTest.php index 64eaab1..6398809 100644 --- a/tests/Monolog/Handler/PsrHandlerTest.php +++ b/tests/Monolog/Handler/PsrHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -21,11 +21,11 @@ class PsrHandlerTest extends TestCase { public function logLevelProvider() { - $levels = array(); + $levels = []; $monologLogger = new Logger(''); foreach ($monologLogger->getLevels() as $levelName => $level) { - $levels[] = array($levelName, $level); + $levels[] = [$levelName, $level]; } return $levels; @@ -37,7 +37,7 @@ class PsrHandlerTest extends TestCase public function testHandlesAllLevels($levelName, $level) { $message = 'Hello, world! ' . $level; - $context = array('foo' => 'bar', 'level' => $level); + $context = ['foo' => 'bar', 'level' => $level]; $psrLogger = $this->getMock('Psr\Log\NullLogger'); $psrLogger->expects($this->once()) @@ -45,6 +45,6 @@ class PsrHandlerTest extends TestCase ->with(strtolower($levelName), $message, $context); $handler = new PsrHandler($psrLogger); - $handler->handle(array('level' => $level, 'level_name' => $levelName, 'message' => $message, 'context' => $context)); + $handler->handle(['level' => $level, 'level_name' => $levelName, 'message' => $message, 'context' => $context]); } } diff --git a/tests/Monolog/Handler/PushoverHandlerTest.php b/tests/Monolog/Handler/PushoverHandlerTest.php index 56df474..e5336ab 100644 --- a/tests/Monolog/Handler/PushoverHandlerTest.php +++ b/tests/Monolog/Handler/PushoverHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -103,7 +103,7 @@ class PushoverHandlerTest extends TestCase public function testWriteToMultipleUsers() { - $this->createHandler('myToken', array('userA', 'userB')); + $this->createHandler('myToken', ['userA', 'userB']); $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1')); fseek($this->res, 0); $content = fread($this->res, 1024); @@ -114,11 +114,11 @@ class PushoverHandlerTest extends TestCase private function createHandler($token = 'myToken', $user = 'myUser', $title = 'Monolog') { - $constructorArgs = array($token, $user, $title); + $constructorArgs = [$token, $user, $title]; $this->res = fopen('php://memory', 'a'); $this->handler = $this->getMock( '\Monolog\Handler\PushoverHandler', - array('fsockopen', 'streamSetTimeout', 'closeSocket'), + ['fsockopen', 'streamSetTimeout', 'closeSocket'], $constructorArgs ); diff --git a/tests/Monolog/Handler/RavenHandlerTest.php b/tests/Monolog/Handler/RavenHandlerTest.php index a7c4845..d4325e5 100644 --- a/tests/Monolog/Handler/RavenHandlerTest.php +++ b/tests/Monolog/Handler/RavenHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Monolog\Formatter\LineFormatter; @@ -78,8 +78,8 @@ class RavenHandlerTest extends TestCase $ravenClient = $this->getRavenClient(); $handler = $this->getHandler($ravenClient); - $tags = array(1, 2, 'foo'); - $record = $this->getRecord(Logger::INFO, 'test', array('tags' => $tags)); + $tags = [1, 2, 'foo']; + $record = $this->getRecord(Logger::INFO, 'test', ['tags' => $tags]); $handler->handle($record); $this->assertEquals($tags, $ravenClient->lastData['tags']); @@ -92,7 +92,7 @@ class RavenHandlerTest extends TestCase $checksum = '098f6bcd4621d373cade4e832627b4f6'; $release = '05a671c66aefea124cc08b76ea6d30bb'; - $record = $this->getRecord(Logger::INFO, 'test', array('checksum' => $checksum, 'release' => $release)); + $record = $this->getRecord(Logger::INFO, 'test', ['checksum' => $checksum, 'release' => $release]); $handler->handle($record); $this->assertEquals($checksum, $ravenClient->lastData['checksum']); @@ -104,8 +104,8 @@ class RavenHandlerTest extends TestCase $ravenClient = $this->getRavenClient(); $handler = $this->getHandler($ravenClient); - $fingerprint = array('{{ default }}', 'other value'); - $record = $this->getRecord(Logger::INFO, 'test', array('fingerprint' => $fingerprint)); + $fingerprint = ['{{ default }}', 'other value']; + $record = $this->getRecord(Logger::INFO, 'test', ['fingerprint' => $fingerprint]); $handler->handle($record); $this->assertEquals($fingerprint, $ravenClient->lastData['fingerprint']); @@ -119,14 +119,14 @@ class RavenHandlerTest extends TestCase $recordWithNoContext = $this->getRecord(Logger::INFO, 'test with default user context'); // set user context 'externally' - $user = array( + $user = [ 'id' => '123', 'email' => 'test@test.com', - ); + ]; - $recordWithContext = $this->getRecord(Logger::INFO, 'test', array('user' => $user)); + $recordWithContext = $this->getRecord(Logger::INFO, 'test', ['user' => $user]); - $ravenClient->user_context(array('id' => 'test_user_id')); + $ravenClient->user_context(['id' => 'test_user_id']); // handle context $handler->handle($recordWithContext); $this->assertEquals($user, $ravenClient->lastData['user']); @@ -154,7 +154,7 @@ class RavenHandlerTest extends TestCase try { $this->methodThatThrowsAnException(); } catch (\Exception $e) { - $record = $this->getRecord(Logger::ERROR, $e->getMessage(), array('exception' => $e)); + $record = $this->getRecord(Logger::ERROR, $e->getMessage(), ['exception' => $e]); $handler->handle($record); } @@ -183,13 +183,13 @@ class RavenHandlerTest extends TestCase public function testHandleBatchDoNothingIfRecordsAreBelowLevel() { - $records = array( + $records = [ $this->getRecord(Logger::DEBUG, 'debug message 1'), $this->getRecord(Logger::DEBUG, 'debug message 2'), $this->getRecord(Logger::INFO, 'information'), - ); + ]; - $handler = $this->getMock('Monolog\Handler\RavenHandler', null, array($this->getRavenClient())); + $handler = $this->getMock('Monolog\Handler\RavenHandler', ['handle'], [$this->getRavenClient()]); $handler->expects($this->never())->method('handle'); $handler->setLevel(Logger::ERROR); $handler->handleBatch($records); @@ -215,7 +215,7 @@ class RavenHandlerTest extends TestCase $this->assertEquals($release, $ravenClient->lastData['release']); $localRelease = 'v41.41.41'; - $record = $this->getRecord(Logger::INFO, 'test', array('release' => $localRelease)); + $record = $this->getRecord(Logger::INFO, 'test', ['release' => $localRelease]); $handler->handle($record); $this->assertEquals($localRelease, $ravenClient->lastData['release']); } diff --git a/tests/Monolog/Handler/RedisHandlerTest.php b/tests/Monolog/Handler/RedisHandlerTest.php index 689d527..719a128 100644 --- a/tests/Monolog/Handler/RedisHandlerTest.php +++ b/tests/Monolog/Handler/RedisHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; use Monolog\Formatter\LineFormatter; @@ -39,14 +39,14 @@ class RedisHandlerTest extends TestCase public function testPredisHandle() { - $redis = $this->getMock('Predis\Client', array('rpush')); + $redis = $this->getMock('Predis\Client', ['rpush']); // Predis\Client uses rpush $redis->expects($this->once()) ->method('rpush') ->with('key', 'test'); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); $handler = new RedisHandler($redis, 'key'); $handler->setFormatter(new LineFormatter("%message%")); @@ -55,14 +55,14 @@ class RedisHandlerTest extends TestCase public function testRedisHandle() { - $redis = $this->getMock('Redis', array('rpush')); + $redis = $this->getMock('Redis', ['rpush']); // Redis uses rPush $redis->expects($this->once()) - ->method('rPush') + ->method('rpush') ->with('key', 'test'); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); $handler = new RedisHandler($redis, 'key'); $handler->setFormatter(new LineFormatter("%message%")); @@ -71,7 +71,7 @@ class RedisHandlerTest extends TestCase public function testRedisHandleCapped() { - $redis = $this->getMock('Redis', array('multi', 'rpush', 'ltrim', 'exec')); + $redis = $this->getMock('Redis', ['multi', 'rpush', 'ltrim', 'exec']); // Redis uses multi $redis->expects($this->once()) @@ -90,7 +90,7 @@ class RedisHandlerTest extends TestCase ->method('exec') ->will($this->returnSelf()); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10); $handler->setFormatter(new LineFormatter("%message%")); @@ -99,9 +99,9 @@ class RedisHandlerTest extends TestCase public function testPredisHandleCapped() { - $redis = $this->getMock('Predis\Client', array('transaction')); + $redis = $this->getMock('Predis\Client', ['transaction']); - $redisTransaction = $this->getMock('Predis\Client', array('rpush', 'ltrim')); + $redisTransaction = $this->getMock('Predis\Client', ['rpush', 'ltrim']); $redisTransaction->expects($this->once()) ->method('rpush') @@ -118,7 +118,7 @@ class RedisHandlerTest extends TestCase $cb($redisTransaction); })); - $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + $record = $this->getRecord(Logger::WARNING, 'test', ['data' => new \stdClass, 'foo' => 34]); $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10); $handler->setFormatter(new LineFormatter("%message%")); diff --git a/tests/Monolog/Handler/RotatingFileHandlerTest.php b/tests/Monolog/Handler/RotatingFileHandlerTest.php index 96e6dff..58188e2 100644 --- a/tests/Monolog/Handler/RotatingFileHandlerTest.php +++ b/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,8 +11,8 @@ namespace Monolog\Handler; -use Monolog\TestCase; -use PHPUnit_Framework_Error_Deprecated; +use InvalidArgumentException; +use Monolog\Test\TestCase; /** * @covers Monolog\Handler\RotatingFileHandler @@ -37,11 +37,11 @@ class RotatingFileHandlerTest extends TestCase $this->lastError = null; $self = $this; // workaround with &$self used for PHP 5.3 - set_error_handler(function($code, $message) use (&$self) { - $self->lastError = array( + set_error_handler(function ($code, $message) use (&$self) { + $self->lastError = [ 'code' => $code, 'message' => $message, - ); + ]; }); } @@ -107,32 +107,32 @@ class RotatingFileHandlerTest extends TestCase public function rotationTests() { $now = time(); - $dayCallback = function($ago) use ($now) { + $dayCallback = function ($ago) use ($now) { return $now + 86400 * $ago; }; - $monthCallback = function($ago) { - return gmmktime(0, 0, 0, date('n') + $ago, date('d'), date('Y')); + $monthCallback = function ($ago) { + return gmmktime(0, 0, 0, (int) (date('n') + $ago), (int) date('d'), (int) date('Y')); }; - $yearCallback = function($ago) { - return gmmktime(0, 0, 0, date('n'), date('d'), date('Y') + $ago); + $yearCallback = function ($ago) { + return gmmktime(0, 0, 0, (int) date('n'), (int) date('d'), (int) (date('Y') + $ago)); }; - return array( + return [ 'Rotation is triggered when the file of the current day is not present' - => array(true, RotatingFileHandler::FILE_PER_DAY, $dayCallback), + => [true, RotatingFileHandler::FILE_PER_DAY, $dayCallback], 'Rotation is not triggered when the file of the current day is already present' - => array(false, RotatingFileHandler::FILE_PER_DAY, $dayCallback), + => [false, RotatingFileHandler::FILE_PER_DAY, $dayCallback], 'Rotation is triggered when the file of the current month is not present' - => array(true, RotatingFileHandler::FILE_PER_MONTH, $monthCallback), + => [true, RotatingFileHandler::FILE_PER_MONTH, $monthCallback], 'Rotation is not triggered when the file of the current month is already present' - => array(false, RotatingFileHandler::FILE_PER_MONTH, $monthCallback), + => [false, RotatingFileHandler::FILE_PER_MONTH, $monthCallback], 'Rotation is triggered when the file of the current year is not present' - => array(true, RotatingFileHandler::FILE_PER_YEAR, $yearCallback), + => [true, RotatingFileHandler::FILE_PER_YEAR, $yearCallback], 'Rotation is not triggered when the file of the current year is already present' - => array(false, RotatingFileHandler::FILE_PER_YEAR, $yearCallback), - ); + => [false, RotatingFileHandler::FILE_PER_YEAR, $yearCallback], + ]; } /** @@ -141,26 +141,37 @@ class RotatingFileHandlerTest extends TestCase public function testAllowOnlyFixedDefinedDateFormats($dateFormat, $valid) { $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2); - $handler->setFilenameFormat('{filename}-{date}', $dateFormat); if (!$valid) { - $this->assertErrorWasTriggered( - E_USER_DEPRECATED, - 'Invalid date format - format should be one of '. - 'RotatingFileHandler::FILE_PER_DAY, RotatingFileHandler::FILE_PER_MONTH '. - 'or RotatingFileHandler::FILE_PER_YEAR.' - ); + $this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid date format~'); } + $handler->setFilenameFormat('{filename}-{date}', $dateFormat); } public function dateFormatProvider() { - return array( - array(RotatingFileHandler::FILE_PER_DAY, true), - array(RotatingFileHandler::FILE_PER_MONTH, true), - array(RotatingFileHandler::FILE_PER_YEAR, true), - array('m-d-Y', false), - array('Y-m-d-h-i', false) - ); + return [ + [RotatingFileHandler::FILE_PER_DAY, true], + [RotatingFileHandler::FILE_PER_MONTH, true], + [RotatingFileHandler::FILE_PER_YEAR, true], + ['Y/m/d', true], + ['Y.m.d', true], + ['Y_m_d', true], + ['Ymd', true], + ['Ym/d', true], + ['Y/m', true], + ['Ym', true], + ['Y.m', true], + ['Y_m', true], + ['Y/md', true], + ['', false], + ['m-d-Y', false], + ['Y-m-d-h-i', false], + ['Y-', false], + ['Y-m-', false], + ['Y--', false], + ['m-d', false], + ['Y-d', false] + ]; } /** @@ -169,26 +180,24 @@ class RotatingFileHandlerTest extends TestCase public function testDisallowFilenameFormatsWithoutDate($filenameFormat, $valid) { $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2); - $handler->setFilenameFormat($filenameFormat, RotatingFileHandler::FILE_PER_DAY); if (!$valid) { - $this->assertErrorWasTriggered( - E_USER_DEPRECATED, - 'Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.' - ); + $this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid filename format~'); } + + $handler->setFilenameFormat($filenameFormat, RotatingFileHandler::FILE_PER_DAY); } public function filenameFormatProvider() { - return array( - array('{filename}', false), - array('{filename}-{date}', true), - array('{date}', true), - array('foobar-{date}', true), - array('foo-{date}-bar', true), - array('{date}-foobar', true), - array('foobar', false), - ); + return [ + ['{filename}', false], + ['{filename}-{date}', true], + ['{date}', true], + ['foobar-{date}', true], + ['foo-{date}-bar', true], + ['{date}-foobar', true], + ['foobar', false], + ]; } public function testReuseCurrentFile() diff --git a/tests/Monolog/Handler/SamplingHandlerTest.php b/tests/Monolog/Handler/SamplingHandlerTest.php index b354cee..90f5c9b 100644 --- a/tests/Monolog/Handler/SamplingHandlerTest.php +++ b/tests/Monolog/Handler/SamplingHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; /** * @covers Monolog\Handler\SamplingHandler::handle diff --git a/tests/Monolog/Handler/SlackHandlerTest.php b/tests/Monolog/Handler/SlackHandlerTest.php index d657fae..d42c19b 100644 --- a/tests/Monolog/Handler/SlackHandlerTest.php +++ b/tests/Monolog/Handler/SlackHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -92,25 +92,25 @@ class SlackHandlerTest extends TestCase public function provideLevelColors() { - return array( - array(Logger::DEBUG, '%23e3e4e6'), // escaped #e3e4e6 - array(Logger::INFO, 'good'), - array(Logger::NOTICE, 'good'), - array(Logger::WARNING, 'warning'), - array(Logger::ERROR, 'danger'), - array(Logger::CRITICAL, 'danger'), - array(Logger::ALERT, 'danger'), - array(Logger::EMERGENCY,'danger'), - ); + return [ + [Logger::DEBUG, '%23e3e4e6'], // escaped #e3e4e6 + [Logger::INFO, 'good'], + [Logger::NOTICE, 'good'], + [Logger::WARNING, 'warning'], + [Logger::ERROR, 'danger'], + [Logger::CRITICAL, 'danger'], + [Logger::ALERT, 'danger'], + [Logger::EMERGENCY,'danger'], + ]; } private function createHandler($token = 'myToken', $channel = 'channel1', $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $useShortAttachment = false, $includeExtra = false) { - $constructorArgs = array($token, $channel, $username, $useAttachment, $iconEmoji, Logger::DEBUG, true, $useShortAttachment, $includeExtra); + $constructorArgs = [$token, $channel, $username, $useAttachment, $iconEmoji, Logger::DEBUG, true, $useShortAttachment, $includeExtra]; $this->res = fopen('php://memory', 'a'); $this->handler = $this->getMock( '\Monolog\Handler\SlackHandler', - array('fsockopen', 'streamSetTimeout', 'closeSocket'), + ['fsockopen', 'streamSetTimeout', 'closeSocket'], $constructorArgs ); diff --git a/tests/Monolog/Handler/SocketHandlerTest.php b/tests/Monolog/Handler/SocketHandlerTest.php index 1f9c1f2..4574859 100644 --- a/tests/Monolog/Handler/SocketHandlerTest.php +++ b/tests/Monolog/Handler/SocketHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -88,7 +88,7 @@ class SocketHandlerTest extends TestCase */ public function testExceptionIsThrownOnFsockopenError() { - $this->setMockHandler(array('fsockopen')); + $this->setMockHandler(['fsockopen']); $this->handler->expects($this->once()) ->method('fsockopen') ->will($this->returnValue(false)); @@ -100,7 +100,7 @@ class SocketHandlerTest extends TestCase */ public function testExceptionIsThrownOnPfsockopenError() { - $this->setMockHandler(array('pfsockopen')); + $this->setMockHandler(['pfsockopen']); $this->handler->expects($this->once()) ->method('pfsockopen') ->will($this->returnValue(false)); @@ -113,7 +113,7 @@ class SocketHandlerTest extends TestCase */ public function testExceptionIsThrownIfCannotSetTimeout() { - $this->setMockHandler(array('streamSetTimeout')); + $this->setMockHandler(['streamSetTimeout']); $this->handler->expects($this->once()) ->method('streamSetTimeout') ->will($this->returnValue(false)); @@ -125,13 +125,13 @@ class SocketHandlerTest extends TestCase */ public function testWriteFailsOnIfFwriteReturnsFalse() { - $this->setMockHandler(array('fwrite')); + $this->setMockHandler(['fwrite']); $callback = function ($arg) { - $map = array( + $map = [ 'Hello world' => 6, 'world' => false, - ); + ]; return $map[$arg]; }; @@ -148,13 +148,13 @@ class SocketHandlerTest extends TestCase */ public function testWriteFailsIfStreamTimesOut() { - $this->setMockHandler(array('fwrite', 'streamGetMetadata')); + $this->setMockHandler(['fwrite', 'streamGetMetadata']); $callback = function ($arg) { - $map = array( + $map = [ 'Hello world' => 6, 'world' => 5, - ); + ]; return $map[$arg]; }; @@ -164,7 +164,7 @@ class SocketHandlerTest extends TestCase ->will($this->returnCallback($callback)); $this->handler->expects($this->exactly(1)) ->method('streamGetMetadata') - ->will($this->returnValue(array('timed_out' => true))); + ->will($this->returnValue(['timed_out' => true])); $this->writeRecord('Hello world'); } @@ -174,7 +174,7 @@ class SocketHandlerTest extends TestCase */ public function testWriteFailsOnIncompleteWrite() { - $this->setMockHandler(array('fwrite', 'streamGetMetadata')); + $this->setMockHandler(['fwrite', 'streamGetMetadata']); $res = $this->res; $callback = function ($string) use ($res) { @@ -188,7 +188,7 @@ class SocketHandlerTest extends TestCase ->will($this->returnCallback($callback)); $this->handler->expects($this->exactly(1)) ->method('streamGetMetadata') - ->will($this->returnValue(array('timed_out' => false))); + ->will($this->returnValue(['timed_out' => false])); $this->writeRecord('Hello world'); } @@ -205,13 +205,13 @@ class SocketHandlerTest extends TestCase public function testWriteWithMock() { - $this->setMockHandler(array('fwrite')); + $this->setMockHandler(['fwrite']); $callback = function ($arg) { - $map = array( + $map = [ 'Hello world' => 6, 'world' => 5, - ); + ]; return $map[$arg]; }; @@ -247,7 +247,7 @@ class SocketHandlerTest extends TestCase */ public function testAvoidInfiniteLoopWhenNoDataIsWrittenForAWritingTimeoutSeconds() { - $this->setMockHandler(array('fwrite', 'streamGetMetadata')); + $this->setMockHandler(['fwrite', 'streamGetMetadata']); $this->handler->expects($this->any()) ->method('fwrite') @@ -255,7 +255,7 @@ class SocketHandlerTest extends TestCase $this->handler->expects($this->any()) ->method('streamGetMetadata') - ->will($this->returnValue(array('timed_out' => false))); + ->will($this->returnValue(['timed_out' => false])); $this->handler->setWritingTimeout(1); @@ -273,17 +273,17 @@ class SocketHandlerTest extends TestCase $this->handler->handle($this->getRecord(Logger::WARNING, $string)); } - private function setMockHandler(array $methods = array()) + private function setMockHandler(array $methods = []) { $this->res = fopen('php://memory', 'a'); - $defaultMethods = array('fsockopen', 'pfsockopen', 'streamSetTimeout'); + $defaultMethods = ['fsockopen', 'pfsockopen', 'streamSetTimeout']; $newMethods = array_diff($methods, $defaultMethods); $finalMethods = array_merge($defaultMethods, $newMethods); $this->handler = $this->getMock( - '\Monolog\Handler\SocketHandler', $finalMethods, array('localhost:1234') + '\Monolog\Handler\SocketHandler', $finalMethods, ['localhost:1234'] ); if (!in_array('fsockopen', $methods)) { diff --git a/tests/Monolog/Handler/StreamHandlerTest.php b/tests/Monolog/Handler/StreamHandlerTest.php index 487030f..377e296 100644 --- a/tests/Monolog/Handler/StreamHandlerTest.php +++ b/tests/Monolog/Handler/StreamHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class StreamHandlerTest extends TestCase @@ -51,13 +51,38 @@ class StreamHandlerTest extends TestCase { $handler = new StreamHandler('php://memory'); $handler->handle($this->getRecord(Logger::WARNING, 'test')); - $streamProp = new \ReflectionProperty('Monolog\Handler\StreamHandler', 'stream'); - $streamProp->setAccessible(true); - $handle = $streamProp->getValue($handler); + $stream = $handler->getStream(); - $this->assertTrue(is_resource($handle)); + $this->assertTrue(is_resource($stream)); $handler->close(); - $this->assertFalse(is_resource($handle)); + $this->assertFalse(is_resource($stream)); + } + + /** + * @covers Monolog\Handler\StreamHandler::close + * @covers Monolog\Handler\Handler::__sleep + */ + public function testSerialization() + { + $handler = new StreamHandler('php://memory'); + $handler->handle($this->getRecord(Logger::WARNING, 'testfoo')); + $stream = $handler->getStream(); + + $this->assertTrue(is_resource($stream)); + fseek($stream, 0); + $this->assertContains('testfoo', stream_get_contents($stream)); + $serialized = serialize($handler); + $this->assertFalse(is_resource($stream)); + + $handler = unserialize($serialized); + $handler->handle($this->getRecord(Logger::WARNING, 'testbar')); + $stream = $handler->getStream(); + + $this->assertTrue(is_resource($stream)); + fseek($stream, 0); + $contents = stream_get_contents($stream); + $this->assertNotContains('testfoo', $contents); + $this->assertContains('testbar', $contents); } /** @@ -93,11 +118,11 @@ class StreamHandlerTest extends TestCase public function invalidArgumentProvider() { - return array( - array(1), - array(array()), - array(array('bogus://url')), - ); + return [ + [1], + [[]], + [['bogus://url']], + ]; } /** diff --git a/tests/Monolog/Handler/SwiftMailerHandlerTest.php b/tests/Monolog/Handler/SwiftMailerHandlerTest.php index 8588691..ec7fc21 100644 --- a/tests/Monolog/Handler/SwiftMailerHandlerTest.php +++ b/tests/Monolog/Handler/SwiftMailerHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -12,7 +12,7 @@ namespace Monolog\Handler; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; class SwiftMailerHandlerTest extends TestCase { @@ -37,10 +37,10 @@ class SwiftMailerHandlerTest extends TestCase }; $handler = new SwiftMailerHandler($this->mailer, $callback); - $records = array( + $records = [ $this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO), - ); + ]; $handler->handleBatch($records); } @@ -66,9 +66,9 @@ class SwiftMailerHandlerTest extends TestCase $handler = new SwiftMailerHandler($this->mailer, $callback); // Logging 1 record makes this an Emergency - $records = array( + $records = [ $this->getRecord(Logger::EMERGENCY), - ); + ]; $handler->handleBatch($records); } @@ -83,14 +83,15 @@ class SwiftMailerHandlerTest extends TestCase ->method('send') ->with($this->callback(function ($value) use (&$receivedMessage) { $receivedMessage = $value; + return true; })); $handler = new SwiftMailerHandler($this->mailer, $messageTemplate); - $records = array( + $records = [ $this->getRecord(Logger::EMERGENCY), - ); + ]; $handler->handleBatch($records); $this->assertEquals('Alert: EMERGENCY test', $receivedMessage->getSubject()); @@ -103,10 +104,10 @@ class SwiftMailerHandlerTest extends TestCase $method = new \ReflectionMethod('Monolog\Handler\SwiftMailerHandler', 'buildMessage'); $method->setAccessible(true); - $method->invokeArgs($handler, array($messageTemplate, array())); + $method->invokeArgs($handler, [$messageTemplate, []]); - $builtMessage1 = $method->invoke($handler, $messageTemplate, array()); - $builtMessage2 = $method->invoke($handler, $messageTemplate, array()); + $builtMessage1 = $method->invoke($handler, $messageTemplate, []); + $builtMessage2 = $method->invoke($handler, $messageTemplate, []); $this->assertFalse($builtMessage1->getId() === $builtMessage2->getId(), 'Two different messages have the same id'); } diff --git a/tests/Monolog/Handler/SyslogHandlerTest.php b/tests/Monolog/Handler/SyslogHandlerTest.php index 8f9e46b..dd31f53 100644 --- a/tests/Monolog/Handler/SyslogHandlerTest.php +++ b/tests/Monolog/Handler/SyslogHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/tests/Monolog/Handler/SyslogUdpHandlerTest.php b/tests/Monolog/Handler/SyslogUdpHandlerTest.php index 497812b..25d7c58 100644 --- a/tests/Monolog/Handler/SyslogUdpHandlerTest.php +++ b/tests/Monolog/Handler/SyslogUdpHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -29,7 +29,7 @@ class SyslogUdpHandlerTest extends \PHPUnit_Framework_TestCase $handler = new SyslogUdpHandler("127.0.0.1", 514, "authpriv"); $handler->setFormatter(new \Monolog\Formatter\ChromePHPFormatter()); - $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('write'), array('lol', 'lol')); + $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', ['write'], ['lol', 'lol']); $socket->expects($this->at(0)) ->method('write') ->with("lol", "<".(LOG_AUTHPRIV + LOG_WARNING).">1 "); @@ -44,6 +44,6 @@ class SyslogUdpHandlerTest extends \PHPUnit_Framework_TestCase protected function getRecordWithMessage($msg) { - return array('message' => $msg, 'level' => \Monolog\Logger::WARNING, 'context' => null, 'extra' => array(), 'channel' => 'lol'); + return ['message' => $msg, 'level' => \Monolog\Logger::WARNING, 'context' => null, 'extra' => [], 'channel' => 'lol']; } } diff --git a/tests/Monolog/Handler/TestHandlerTest.php b/tests/Monolog/Handler/TestHandlerTest.php index 75cc4a8..4fa20bb 100644 --- a/tests/Monolog/Handler/TestHandlerTest.php +++ b/tests/Monolog/Handler/TestHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; /** @@ -47,20 +47,20 @@ class TestHandlerTest extends TestCase $records = $handler->getRecords(); unset($records[0]['formatted']); - $this->assertEquals(array($record), $records); + $this->assertEquals([$record], $records); } public function methodProvider() { - return array( - array('Emergency', Logger::EMERGENCY), - array('Alert' , Logger::ALERT), - array('Critical' , Logger::CRITICAL), - array('Error' , Logger::ERROR), - array('Warning' , Logger::WARNING), - array('Info' , Logger::INFO), - array('Notice' , Logger::NOTICE), - array('Debug' , Logger::DEBUG), - ); + return [ + ['Emergency', Logger::EMERGENCY], + ['Alert' , Logger::ALERT], + ['Critical' , Logger::CRITICAL], + ['Error' , Logger::ERROR], + ['Warning' , Logger::WARNING], + ['Info' , Logger::INFO], + ['Notice' , Logger::NOTICE], + ['Debug' , Logger::DEBUG], + ]; } } diff --git a/tests/Monolog/Handler/UdpSocketTest.php b/tests/Monolog/Handler/UdpSocketTest.php index fa524d0..de0f7fb 100644 --- a/tests/Monolog/Handler/UdpSocketTest.php +++ b/tests/Monolog/Handler/UdpSocketTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Handler\SyslogUdp\UdpSocket; /** @@ -21,7 +21,7 @@ class UdpSocketTest extends TestCase { public function testWeDoNotTruncateShortMessages() { - $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol')); + $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', ['send'], ['lol', 'lol']); $socket->expects($this->at(0)) ->method('send') @@ -32,7 +32,7 @@ class UdpSocketTest extends TestCase public function testLongMessagesAreTruncated() { - $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol')); + $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', ['send'], ['lol', 'lol']); $truncatedString = str_repeat("derp", 16254).'d'; diff --git a/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php b/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php index 8d37a1f..60f5175 100644 --- a/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php +++ b/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Logger; class WhatFailureGroupHandlerTest extends TestCase @@ -22,7 +22,7 @@ class WhatFailureGroupHandlerTest extends TestCase */ public function testConstructorOnlyTakesHandler() { - new WhatFailureGroupHandler(array(new TestHandler(), "foo")); + new WhatFailureGroupHandler([new TestHandler(), "foo"]); } /** @@ -31,7 +31,7 @@ class WhatFailureGroupHandlerTest extends TestCase */ public function testHandle() { - $testHandlers = array(new TestHandler(), new TestHandler()); + $testHandlers = [new TestHandler(), new TestHandler()]; $handler = new WhatFailureGroupHandler($testHandlers); $handler->handle($this->getRecord(Logger::DEBUG)); $handler->handle($this->getRecord(Logger::INFO)); @@ -47,9 +47,9 @@ class WhatFailureGroupHandlerTest extends TestCase */ public function testHandleBatch() { - $testHandlers = array(new TestHandler(), new TestHandler()); + $testHandlers = [new TestHandler(), new TestHandler()]; $handler = new WhatFailureGroupHandler($testHandlers); - $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO))); + $handler->handleBatch([$this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)]); foreach ($testHandlers as $test) { $this->assertTrue($test->hasDebugRecords()); $this->assertTrue($test->hasInfoRecords()); @@ -62,7 +62,7 @@ class WhatFailureGroupHandlerTest extends TestCase */ public function testIsHandling() { - $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING)); + $testHandlers = [new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING)]; $handler = new WhatFailureGroupHandler($testHandlers); $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR))); $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING))); @@ -75,7 +75,7 @@ class WhatFailureGroupHandlerTest extends TestCase public function testHandleUsesProcessors() { $test = new TestHandler(); - $handler = new WhatFailureGroupHandler(array($test)); + $handler = new WhatFailureGroupHandler([$test]); $handler->pushProcessor(function ($record) { $record['extra']['foo'] = true; @@ -94,7 +94,7 @@ class WhatFailureGroupHandlerTest extends TestCase { $test = new TestHandler(); $exception = new ExceptionTestHandler(); - $handler = new WhatFailureGroupHandler(array($exception, $test, $exception)); + $handler = new WhatFailureGroupHandler([$exception, $test, $exception]); $handler->pushProcessor(function ($record) { $record['extra']['foo'] = true; @@ -112,7 +112,7 @@ class ExceptionTestHandler extends TestHandler /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { parent::handle($record); diff --git a/tests/Monolog/Handler/ZendMonitorHandlerTest.php b/tests/Monolog/Handler/ZendMonitorHandlerTest.php index 69b001e..4879ebe 100644 --- a/tests/Monolog/Handler/ZendMonitorHandlerTest.php +++ b/tests/Monolog/Handler/ZendMonitorHandlerTest.php @@ -1,4 +1,5 @@ -<?php +<?php declare(strict_types=1); + /* * This file is part of the Monolog package. * @@ -10,7 +11,7 @@ namespace Monolog\Handler; -use Monolog\TestCase; +use Monolog\Test\TestCase; class ZendMonitorHandlerTest extends TestCase { @@ -29,12 +30,12 @@ class ZendMonitorHandlerTest extends TestCase public function testWrite() { $record = $this->getRecord(); - $formatterResult = array( + $formatterResult = [ 'message' => $record['message'], - ); + ]; $zendMonitor = $this->getMockBuilder('Monolog\Handler\ZendMonitorHandler') - ->setMethods(array('writeZendMonitorCustomEvent', 'getDefaultFormatter')) + ->setMethods(['writeZendMonitorCustomEvent', 'getDefaultFormatter']) ->getMock(); $formatterMock = $this->getMockBuilder('Monolog\Formatter\NormalizerFormatter') diff --git a/tests/Monolog/LoggerTest.php b/tests/Monolog/LoggerTest.php index c0bd1da..75c2dbd 100644 --- a/tests/Monolog/LoggerTest.php +++ b/tests/Monolog/LoggerTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -38,7 +38,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase */ public function testWithName() { - $first = new Logger('first', array($handler = new TestHandler())); + $first = new Logger('first', [$handler = new TestHandler()]); $second = $first->withName('second'); $this->assertSame('first', $first->getName()); @@ -78,7 +78,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase $logger = new Logger('foo'); $handler = new TestHandler; $logger->pushHandler($handler); - $logger->addWarning('test'); + $logger->warning('test'); list($record) = $handler->getRecords(); $this->assertEquals('foo', $record['channel']); } @@ -90,12 +90,12 @@ class LoggerTest extends \PHPUnit_Framework_TestCase { $logger = new Logger(__METHOD__); - $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle')); + $handler = $this->getMock('Monolog\Handler\NullHandler', ['handle']); $handler->expects($this->once()) ->method('handle'); $logger->pushHandler($handler); - $this->assertTrue($logger->addWarning('test')); + $this->assertTrue($logger->warning('test')); } /** @@ -105,19 +105,19 @@ class LoggerTest extends \PHPUnit_Framework_TestCase { $logger = new Logger(__METHOD__); - $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'), array(Logger::ERROR)); + $handler = $this->getMock('Monolog\Handler\NullHandler', ['handle'], [Logger::ERROR]); $handler->expects($this->never()) ->method('handle'); $logger->pushHandler($handler); - $this->assertFalse($logger->addWarning('test')); + $this->assertFalse($logger->warning('test')); } public function testHandlersInCtor() { $handler1 = new TestHandler; $handler2 = new TestHandler; - $logger = new Logger(__METHOD__, array($handler1, $handler2)); + $logger = new Logger(__METHOD__, [$handler1, $handler2]); $this->assertEquals($handler1, $logger->popHandler()); $this->assertEquals($handler2, $logger->popHandler()); @@ -127,7 +127,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase { $processor1 = new WebProcessor; $processor2 = new WebProcessor; - $logger = new Logger(__METHOD__, array(), array($processor1, $processor2)); + $logger = new Logger(__METHOD__, [], [$processor1, $processor2]); $this->assertEquals($processor1, $logger->popProcessor()); $this->assertEquals($processor2, $logger->popProcessor()); @@ -162,18 +162,18 @@ class LoggerTest extends \PHPUnit_Framework_TestCase $handler2 = new TestHandler; $logger->pushHandler($handler1); - $logger->setHandlers(array($handler2)); + $logger->setHandlers([$handler2]); // handler1 has been removed - $this->assertEquals(array($handler2), $logger->getHandlers()); + $this->assertEquals([$handler2], $logger->getHandlers()); - $logger->setHandlers(array( + $logger->setHandlers([ "AMapKey" => $handler1, "Woop" => $handler2, - )); + ]); // Keys have been scrubbed - $this->assertEquals(array($handler1, $handler2), $logger->getHandlers()); + $this->assertEquals([$handler1, $handler2], $logger->getHandlers()); } /** @@ -196,17 +196,6 @@ class LoggerTest extends \PHPUnit_Framework_TestCase } /** - * @covers Monolog\Logger::pushProcessor - * @expectedException InvalidArgumentException - */ - public function testPushProcessorWithNonCallable() - { - $logger = new Logger(__METHOD__); - - $logger->pushProcessor(new \stdClass()); - } - - /** * @covers Monolog\Logger::addRecord */ public function testProcessorsAreExecuted() @@ -219,7 +208,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase return $record; }); - $logger->addError('test'); + $logger->error('test'); list($record) = $handler->getRecords(); $this->assertTrue($record['extra']['win']); } @@ -243,7 +232,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase $processor = $this->getMockBuilder('Monolog\Processor\WebProcessor') ->disableOriginalConstructor() - ->setMethods(array('__invoke')) + ->setMethods(['__invoke']) ->getMock() ; $processor->expects($this->once()) @@ -252,7 +241,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase ; $logger->pushProcessor($processor); - $logger->addError('test'); + $logger->error('test'); } /** @@ -271,7 +260,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase $logger->pushProcessor(function ($record) use ($that) { $that->fail('The processor should not be called'); }); - $logger->addAlert('test'); + $logger->alert('test'); } /** @@ -350,7 +339,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase ->method('handle') ; - $logger = new Logger(__METHOD__, array('last' => $handler3, 'second' => $handler2, 'first' => $handler1)); + $logger = new Logger(__METHOD__, ['last' => $handler3, 'second' => $handler2, 'first' => $handler1]); $logger->debug('test'); } @@ -446,22 +435,14 @@ class LoggerTest extends \PHPUnit_Framework_TestCase /** * @dataProvider logMethodProvider - * @covers Monolog\Logger::addDebug - * @covers Monolog\Logger::addInfo - * @covers Monolog\Logger::addNotice - * @covers Monolog\Logger::addWarning - * @covers Monolog\Logger::addError - * @covers Monolog\Logger::addCritical - * @covers Monolog\Logger::addAlert - * @covers Monolog\Logger::addEmergency * @covers Monolog\Logger::debug * @covers Monolog\Logger::info * @covers Monolog\Logger::notice - * @covers Monolog\Logger::warn - * @covers Monolog\Logger::err - * @covers Monolog\Logger::crit + * @covers Monolog\Logger::warning + * @covers Monolog\Logger::error + * @covers Monolog\Logger::critical * @covers Monolog\Logger::alert - * @covers Monolog\Logger::emerg + * @covers Monolog\Logger::emergency */ public function testLogMethods($method, $expectedLevel) { @@ -475,27 +456,17 @@ class LoggerTest extends \PHPUnit_Framework_TestCase public function logMethodProvider() { - return array( - // monolog methods - array('addDebug', Logger::DEBUG), - array('addInfo', Logger::INFO), - array('addNotice', Logger::NOTICE), - array('addWarning', Logger::WARNING), - array('addError', Logger::ERROR), - array('addCritical', Logger::CRITICAL), - array('addAlert', Logger::ALERT), - array('addEmergency', Logger::EMERGENCY), - - // ZF/Sf2 compat methods - array('debug', Logger::DEBUG), - array('info', Logger::INFO), - array('notice', Logger::NOTICE), - array('warn', Logger::WARNING), - array('err', Logger::ERROR), - array('crit', Logger::CRITICAL), - array('alert', Logger::ALERT), - array('emerg', Logger::EMERGENCY), - ); + return [ + // PSR-3 methods + ['debug', Logger::DEBUG], + ['info', Logger::INFO], + ['notice', Logger::NOTICE], + ['warning', Logger::WARNING], + ['error', Logger::ERROR], + ['critical', Logger::CRITICAL], + ['alert', Logger::ALERT], + ['emergency', Logger::EMERGENCY], + ]; } /** @@ -504,8 +475,8 @@ class LoggerTest extends \PHPUnit_Framework_TestCase */ public function testSetTimezone($tz) { - Logger::setTimezone($tz); $logger = new Logger('foo'); + $logger->setTimezone($tz); $handler = new TestHandler; $logger->pushHandler($handler); $logger->info('test'); @@ -516,7 +487,9 @@ class LoggerTest extends \PHPUnit_Framework_TestCase public function setTimezoneProvider() { return array_map( - function ($tz) { return array(new \DateTimeZone($tz)); }, + function ($tz) { + return [new \DateTimeZone($tz)]; + }, \DateTimeZone::listIdentifiers() ); } @@ -539,10 +512,10 @@ class LoggerTest extends \PHPUnit_Framework_TestCase public function useMicrosecondTimestampsProvider() { - return array( + return [ // this has a very small chance of a false negative (1/10^6) - 'with microseconds' => array(true, 'assertNotSame'), - 'without microseconds' => array(false, 'assertSame'), - ); + 'with microseconds' => [true, 'assertNotSame'], + 'without microseconds' => [false, 'assertSame'], + ]; } } diff --git a/tests/Monolog/Processor/GitProcessorTest.php b/tests/Monolog/Processor/GitProcessorTest.php index 5adb505..0059e6d 100644 --- a/tests/Monolog/Processor/GitProcessorTest.php +++ b/tests/Monolog/Processor/GitProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Processor; -use Monolog\TestCase; +use Monolog\Test\TestCase; class GitProcessorTest extends TestCase { diff --git a/tests/Monolog/Processor/IntrospectionProcessorTest.php b/tests/Monolog/Processor/IntrospectionProcessorTest.php index 0dd411d..5f5d9ae 100644 --- a/tests/Monolog/Processor/IntrospectionProcessorTest.php +++ b/tests/Monolog/Processor/IntrospectionProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -27,7 +27,7 @@ function tester($handler, $record) namespace Monolog\Processor; use Monolog\Logger; -use Monolog\TestCase; +use Monolog\Test\TestCase; use Monolog\Handler\TestHandler; class IntrospectionProcessorTest extends TestCase @@ -66,10 +66,10 @@ class IntrospectionProcessorTest extends TestCase public function testLevelTooLow() { - $input = array( + $input = [ 'level' => Logger::DEBUG, - 'extra' => array(), - ); + 'extra' => [], + ]; $expected = $input; @@ -81,18 +81,18 @@ class IntrospectionProcessorTest extends TestCase public function testLevelEqual() { - $input = array( + $input = [ 'level' => Logger::CRITICAL, - 'extra' => array(), - ); + 'extra' => [], + ]; $expected = $input; - $expected['extra'] = array( + $expected['extra'] = [ 'file' => null, 'line' => null, 'class' => 'ReflectionMethod', 'function' => 'invokeArgs', - ); + ]; $processor = new IntrospectionProcessor(Logger::CRITICAL); $actual = $processor($input); @@ -102,18 +102,18 @@ class IntrospectionProcessorTest extends TestCase public function testLevelHigher() { - $input = array( + $input = [ 'level' => Logger::EMERGENCY, - 'extra' => array(), - ); + 'extra' => [], + ]; $expected = $input; - $expected['extra'] = array( + $expected['extra'] = [ 'file' => null, 'line' => null, 'class' => 'ReflectionMethod', 'function' => 'invokeArgs', - ); + ]; $processor = new IntrospectionProcessor(Logger::CRITICAL); $actual = $processor($input); diff --git a/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php b/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php index eb66614..cd80527 100644 --- a/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php +++ b/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Processor; -use Monolog\TestCase; +use Monolog\Test\TestCase; class MemoryPeakUsageProcessorTest extends TestCase { diff --git a/tests/Monolog/Processor/MemoryUsageProcessorTest.php b/tests/Monolog/Processor/MemoryUsageProcessorTest.php index 4692dbf..a4809cb 100644 --- a/tests/Monolog/Processor/MemoryUsageProcessorTest.php +++ b/tests/Monolog/Processor/MemoryUsageProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Processor; -use Monolog\TestCase; +use Monolog\Test\TestCase; class MemoryUsageProcessorTest extends TestCase { diff --git a/tests/Monolog/Processor/ProcessIdProcessorTest.php b/tests/Monolog/Processor/ProcessIdProcessorTest.php index 458d2a3..ec39e8e 100644 --- a/tests/Monolog/Processor/ProcessIdProcessorTest.php +++ b/tests/Monolog/Processor/ProcessIdProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Processor; -use Monolog\TestCase; +use Monolog\Test\TestCase; class ProcessIdProcessorTest extends TestCase { diff --git a/tests/Monolog/Processor/PsrLogMessageProcessorTest.php b/tests/Monolog/Processor/PsrLogMessageProcessorTest.php index 029a0c0..77db842 100644 --- a/tests/Monolog/Processor/PsrLogMessageProcessorTest.php +++ b/tests/Monolog/Processor/PsrLogMessageProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -20,24 +20,24 @@ class PsrLogMessageProcessorTest extends \PHPUnit_Framework_TestCase { $proc = new PsrLogMessageProcessor; - $message = $proc(array( + $message = $proc([ 'message' => '{foo}', - 'context' => array('foo' => $val), - )); + 'context' => ['foo' => $val], + ]); $this->assertEquals($expected, $message['message']); } public function getPairs() { - return array( - array('foo', 'foo'), - array('3', '3'), - array(3, '3'), - array(null, ''), - array(true, '1'), - array(false, ''), - array(new \stdClass, '[object stdClass]'), - array(array(), '[array]'), - ); + return [ + ['foo', 'foo'], + ['3', '3'], + [3, '3'], + [null, ''], + [true, '1'], + [false, ''], + [new \stdClass, '[object stdClass]'], + [[], '[array]'], + ]; } } diff --git a/tests/Monolog/Processor/TagProcessorTest.php b/tests/Monolog/Processor/TagProcessorTest.php index 0d860c6..da84378 100644 --- a/tests/Monolog/Processor/TagProcessorTest.php +++ b/tests/Monolog/Processor/TagProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Processor; -use Monolog\TestCase; +use Monolog\Test\TestCase; class TagProcessorTest extends TestCase { @@ -20,7 +20,7 @@ class TagProcessorTest extends TestCase */ public function testProcessor() { - $tags = array(1, 2, 3); + $tags = [1, 2, 3]; $processor = new TagProcessor($tags); $record = $processor($this->getRecord()); @@ -32,18 +32,18 @@ class TagProcessorTest extends TestCase */ public function testProcessorTagModification() { - $tags = array(1, 2, 3); + $tags = [1, 2, 3]; $processor = new TagProcessor($tags); $record = $processor($this->getRecord()); $this->assertEquals($tags, $record['extra']['tags']); - $processor->setTags(array('a', 'b')); + $processor->setTags(['a', 'b']); $record = $processor($this->getRecord()); - $this->assertEquals(array('a', 'b'), $record['extra']['tags']); + $this->assertEquals(['a', 'b'], $record['extra']['tags']); - $processor->addTags(array('a', 'c', 'foo' => 'bar')); + $processor->addTags(['a', 'c', 'foo' => 'bar']); $record = $processor($this->getRecord()); - $this->assertEquals(array('a', 'b', 'a', 'c', 'foo' => 'bar'), $record['extra']['tags']); + $this->assertEquals(['a', 'b', 'a', 'c', 'foo' => 'bar'], $record['extra']['tags']); } } diff --git a/tests/Monolog/Processor/UidProcessorTest.php b/tests/Monolog/Processor/UidProcessorTest.php index 5d13058..927d564 100644 --- a/tests/Monolog/Processor/UidProcessorTest.php +++ b/tests/Monolog/Processor/UidProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,7 +11,7 @@ namespace Monolog\Processor; -use Monolog\TestCase; +use Monolog\Test\TestCase; class UidProcessorTest extends TestCase { diff --git a/tests/Monolog/Processor/WebProcessorTest.php b/tests/Monolog/Processor/WebProcessorTest.php index 4105baf..6da6ab8 100644 --- a/tests/Monolog/Processor/WebProcessorTest.php +++ b/tests/Monolog/Processor/WebProcessorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -11,20 +11,20 @@ namespace Monolog\Processor; -use Monolog\TestCase; +use Monolog\Test\TestCase; class WebProcessorTest extends TestCase { public function testProcessor() { - $server = array( + $server = [ 'REQUEST_URI' => 'A', 'REMOTE_ADDR' => 'B', 'REQUEST_METHOD' => 'C', 'HTTP_REFERER' => 'D', 'SERVER_NAME' => 'F', 'UNIQUE_ID' => 'G', - ); + ]; $processor = new WebProcessor($server); $record = $processor($this->getRecord()); @@ -38,10 +38,10 @@ class WebProcessorTest extends TestCase public function testProcessorDoNothingIfNoRequestUri() { - $server = array( + $server = [ 'REMOTE_ADDR' => 'B', 'REQUEST_METHOD' => 'C', - ); + ]; $processor = new WebProcessor($server); $record = $processor($this->getRecord()); $this->assertEmpty($record['extra']); @@ -49,12 +49,12 @@ class WebProcessorTest extends TestCase public function testProcessorReturnNullIfNoHttpReferer() { - $server = array( + $server = [ 'REQUEST_URI' => 'A', 'REMOTE_ADDR' => 'B', 'REQUEST_METHOD' => 'C', 'SERVER_NAME' => 'F', - ); + ]; $processor = new WebProcessor($server); $record = $processor($this->getRecord()); $this->assertNull($record['extra']['referrer']); @@ -62,12 +62,12 @@ class WebProcessorTest extends TestCase public function testProcessorDoesNotAddUniqueIdIfNotPresent() { - $server = array( + $server = [ 'REQUEST_URI' => 'A', 'REMOTE_ADDR' => 'B', 'REQUEST_METHOD' => 'C', 'SERVER_NAME' => 'F', - ); + ]; $processor = new WebProcessor($server); $record = $processor($this->getRecord()); $this->assertFalse(isset($record['extra']['unique_id'])); @@ -75,32 +75,32 @@ class WebProcessorTest extends TestCase public function testProcessorAddsOnlyRequestedExtraFields() { - $server = array( + $server = [ 'REQUEST_URI' => 'A', 'REMOTE_ADDR' => 'B', 'REQUEST_METHOD' => 'C', 'SERVER_NAME' => 'F', - ); + ]; - $processor = new WebProcessor($server, array('url', 'http_method')); + $processor = new WebProcessor($server, ['url', 'http_method']); $record = $processor($this->getRecord()); - $this->assertSame(array('url' => 'A', 'http_method' => 'C'), $record['extra']); + $this->assertSame(['url' => 'A', 'http_method' => 'C'], $record['extra']); } public function testProcessorConfiguringOfExtraFields() { - $server = array( + $server = [ 'REQUEST_URI' => 'A', 'REMOTE_ADDR' => 'B', 'REQUEST_METHOD' => 'C', 'SERVER_NAME' => 'F', - ); + ]; - $processor = new WebProcessor($server, array('url' => 'REMOTE_ADDR')); + $processor = new WebProcessor($server, ['url' => 'REMOTE_ADDR']); $record = $processor($this->getRecord()); - $this->assertSame(array('url' => 'B'), $record['extra']); + $this->assertSame(['url' => 'B'], $record['extra']); } /** diff --git a/tests/Monolog/PsrLogCompatTest.php b/tests/Monolog/PsrLogCompatTest.php index ab89944..a4bbcd0 100644 --- a/tests/Monolog/PsrLogCompatTest.php +++ b/tests/Monolog/PsrLogCompatTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. diff --git a/tests/Monolog/RegistryTest.php b/tests/Monolog/RegistryTest.php index 15fdfbd..ef4e452 100644 --- a/tests/Monolog/RegistryTest.php +++ b/tests/Monolog/RegistryTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /* * This file is part of the Monolog package. @@ -38,26 +38,26 @@ class RegistryTest extends \PHPUnit_Framework_TestCase $logger2 = new Logger('test2'); $logger3 = new Logger('test3'); - return array( + return [ // only instances - array( - array($logger1), - array($logger1, $logger2), - array(true, false), - ), + [ + [$logger1], + [$logger1, $logger2], + [true, false], + ], // only names - array( - array($logger1), - array('test1', 'test2'), - array(true, false), - ), + [ + [$logger1], + ['test1', 'test2'], + [true, false], + ], // mixed case - array( - array($logger1, $logger2), - array('test1', $logger2, 'test3', $logger3), - array(true, true, false, false), - ), - ); + [ + [$logger1, $logger2], + ['test1', $logger2, 'test3', $logger3], + [true, true, false, false], + ], + ]; } /** @@ -90,10 +90,10 @@ class RegistryTest extends \PHPUnit_Framework_TestCase { $logger1 = new Logger('test1'); - return array( - array($logger1, $logger1), - array($logger1, 'test1'), - ); + return [ + [$logger1, $logger1], + [$logger1, 'test1'], + ]; } /** diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..d475dd3 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); + +/* + * This file is part of the Monolog package. + * + * (c) Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +date_default_timezone_set('UTC'); + +require __DIR__.'/../vendor/autoload.php'; |