Skip to content

Commit

Permalink
feat: Add support for Monolog 3.x (#5334)
Browse files Browse the repository at this point in the history
* fix: Allow `ServiceException` creation with `null` as the message

Some tests explicitly set the message to `null` which breaks the
creation of parent exceptions with newer PHP versions.

Setting a default `$message = ''` does not prevent the problem, so
we declare it with `null` being allowed, and check and replace it in the
`ServiceException` constructor.

The change is made in the `ServiceException` instead of the tests
calling it incorrectly to reduce the scope of updated files in the
context of the PR that handles the problem.

* feat: Enable the usage of `"psr/log": "^2.0|^3.0"`

`phpdocumentor/reflection` started supporting `"psr/log": "^2.0|^3.0"`
with v5.3.

See phpDocumentor/Reflection#247

* feat: Enable the installation of Monolog V3

`psr/log` v1 included a TestLogger that was removed starting with v2.
`fig/log-test` support all current versions of `psr/log`.

* feat: Introduce V3 versions of AppEngine Formatters and Handlers

* feat: Introduce LogMessageProcessors and their factory

* add monolog 3 to root composer

* remove provide

* allow log-test 1.0

* remove log-test in favor of skipping tests

* ignore cs warning

Co-authored-by: Brent Shaffer <[email protected]>
  • Loading branch information
jeromegamez and bshaffer authored Dec 14, 2022
1 parent 36cc50c commit 6ad6bc3
Show file tree
Hide file tree
Showing 22 changed files with 559 additions and 31 deletions.
4 changes: 2 additions & 2 deletions Core/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
"guzzlehttp/guzzle": "^5.3|^6.5.7|^7.4.4",
"guzzlehttp/promises": "^1.3",
"guzzlehttp/psr7": "^1.7|^2.0",
"monolog/monolog": "^1.1|^2.0",
"monolog/monolog": "^1.1|^2.0|^3.0",
"psr/http-message": "1.0.*"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.0|^8.0",
"yoast/phpunit-polyfills": "^1.0",
"phpspec/prophecy": "^1.10.3",
"squizlabs/php_codesniffer": "2.*",
"phpdocumentor/reflection": "^3.0||^4.0",
"phpdocumentor/reflection": "^3.0||^4.0||^5.3",
"erusev/parsedown": "^1.6",
"google/gax": "^1.9",
"opis/closure": "^3",
Expand Down
6 changes: 3 additions & 3 deletions Core/src/Exception/ServiceException.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ class ServiceException extends GoogleException
/**
* Handle previous exceptions differently here.
*
* @param string $message
* @param string|null $message
* @param int $code
* @param Exception|null $serviceException
* @param array $metadata [optional] Exception metadata.
*/
public function __construct(
$message,
$message = null,
$code = 0,
Exception $serviceException = null,
array $metadata = []
Expand All @@ -74,7 +74,7 @@ public function __construct(
$this->errorInfoMetadata = null;
$this->errorReason = null;

parent::__construct($message, $code);
parent::__construct($message ?: '', $code);
}

/**
Expand Down
1 change: 1 addition & 0 deletions Core/src/Logger/AppEngineFlexFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Monolog 1.x formatter for formatting logs on App Engine flexible environment.
*
* If you are using Monolog 2.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexFormatterV2} instead.
* If you are using Monolog 3.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexFormatterV3} instead.
*/
class AppEngineFlexFormatter extends LineFormatter
{
Expand Down
1 change: 1 addition & 0 deletions Core/src/Logger/AppEngineFlexFormatterV2.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Monolog 2.x formatter for formatting logs on App Engine flexible environment.
*
* If you are using Monolog 1.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexFormatter} instead.
* If you are using Monolog 3.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexFormatterV3} instead.
*/
class AppEngineFlexFormatterV2 extends LineFormatter
{
Expand Down
53 changes: 53 additions & 0 deletions Core/src/Logger/AppEngineFlexFormatterV3.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Google\Cloud\Core\Logger;

use Monolog\Formatter\LineFormatter;
use Monolog\LogRecord;

/**
* Monolog 3.x formatter for formatting logs on App Engine flexible environment.
*
* If you are using Monolog 1.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexFormatter} instead.
* If you are using Monolog 2.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexFormatterV2} instead.
*/
class AppEngineFlexFormatterV3 extends LineFormatter
{
use FormatterTrait;

/**
* @param string $format [optional] The format of the message
* @param string $dateFormat [optional] The format of the timestamp
* @param bool $ignoreEmptyContextAndExtra [optional]
*/
public function __construct($format = null, $dateFormat = null, $ignoreEmptyContextAndExtra = false)
{
parent::__construct($format, $dateFormat, true, $ignoreEmptyContextAndExtra);
}

/**
* Get the plain text message with LineFormatter's format method and add
* metadata including the trace id then return the json string.
*
* @param LogRecord $record A record to format
* @return string The formatted record
*/
public function format(LogRecord $record): string
{
return $this->formatPayload($record, parent::format($record));
}
}
1 change: 1 addition & 0 deletions Core/src/Logger/AppEngineFlexHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Monolog 1.x handler for logging on App Engine flexible environment.
*
* If you are using Monolog 2.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexHandlerV2} instead.
* If you are using Monolog 3.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexHandlerV3} instead.
*/
class AppEngineFlexHandler extends StreamHandler
{
Expand Down
4 changes: 3 additions & 1 deletion Core/src/Logger/AppEngineFlexHandlerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class AppEngineFlexHandlerFactory
*
* @throws Exception
*
* @return AppEngineFlexHandler|AppEngineFlexHandlerV2
* @return AppEngineFlexHandler|AppEngineFlexHandlerV2|AppEngineFlexHandlerV3
*/
public static function build(
$level = Logger::INFO,
Expand All @@ -55,6 +55,8 @@ public static function build(
return new AppEngineFlexHandler($level, $bubble, $filePermission, $useLocking, $stream);
case 2:
return new AppEngineFlexHandlerV2($level, $bubble, $filePermission, $useLocking, $stream);
case 3:
return new AppEngineFlexHandlerV3($level, $bubble, $filePermission, $useLocking, $stream);
default:
throw new Exception('Version not supported');
}
Expand Down
1 change: 1 addition & 0 deletions Core/src/Logger/AppEngineFlexHandlerV2.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Monolog 2.x handler for logging on App Engine flexible environment.
*
* If you are using Monolog 1.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexHandler} instead.
* If you are using Monolog 3.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexHandlerV3} instead.
*/
class AppEngineFlexHandlerV2 extends StreamHandler
{
Expand Down
66 changes: 66 additions & 0 deletions Core/src/Logger/AppEngineFlexHandlerV3.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Google\Cloud\Core\Logger;

use Monolog\Formatter\FormatterInterface;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

/**
* Monolog 3.x handler for logging on App Engine flexible environment.
*
* If you are using Monolog 1.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexHandler} instead.
* If you are using Monolog 2.x, use {@see \Google\Cloud\Core\Logger\AppEngineFlexHandlerV2} instead.
*/
class AppEngineFlexHandlerV3 extends StreamHandler
{
/**
* @param int $level [optional] The minimum logging level at which this
* handler will be triggered.
* @param Boolean $bubble [optional] Whether the messages that are handled
* can bubble up the stack or not.
* @param int|null $filePermission [optional] Optional file permissions
* (default (0640) are only for owner read/write).
* @param Boolean $useLocking [optional] Try to lock log file before doing
* any writes.
* @param resource|string|null $stream [optional]
*/
public function __construct(
$level = Logger::INFO,
$bubble = true,
$filePermission = 0640,
$useLocking = false,
$stream = null
) {
if ($stream === null) {
$pid = getmypid();
$stream = "file:///var/log/app_engine/app.$pid.json";
}
parent::__construct(
$stream,
$level,
$bubble,
$filePermission,
$useLocking
);
}

protected function getDefaultFormatter(): FormatterInterface
{
return new AppEngineFlexFormatterV3();
}
}
13 changes: 12 additions & 1 deletion Core/src/Logger/FormatterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,25 @@
*/
namespace Google\Cloud\Core\Logger;

use Monolog\LogRecord;

/**
* Shared trait to enrich and format a record with
* App Engine Flex specific information.
*/
trait FormatterTrait
{
protected function formatPayload(array $record, $message)
/**
* @param array|LogRecord $record
* @param string $message
* @return string
*/
protected function formatPayload($record, $message)
{
if ($record instanceof LogRecord) {
$record = $record->toArray();
}

list($usec, $sec) = explode(' ', microtime());
$usec = (int)(((float)$usec)*1000000000);
$sec = (int)$sec;
Expand Down
17 changes: 12 additions & 5 deletions Core/src/Testing/Reflection/ReflectionHandlerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@
namespace Google\Cloud\Core\Testing\Reflection;

use phpDocumentor\Reflection\File\LocalFile;
use phpDocumentor\Reflection\Php\EnumCase;

/**
* Class for determining if phpdocumentor/reflection v3 or v4 is being used.
* Class for determining if phpdocumentor/reflection v3, v4 or v5 is being used.
*/
class ReflectionHandlerFactory
{
/**
* @return ReflectionHandlerV3|ReflectionHandlerV4
* @return ReflectionHandlerV3|ReflectionHandlerV4|ReflectionHandlerV5
*/
public static function create()
{
return class_exists(LocalFile::class)
? new ReflectionHandlerV4()
: new ReflectionHandlerV3();
if (class_exists(EnumCase::class)) {
return new ReflectionHandlerV5();
}

if (class_exists(LocalFile::class)) {
return new ReflectionHandlerV4();
}

return new ReflectionHandlerV3();
}
}
Loading

0 comments on commit 6ad6bc3

Please sign in to comment.