Skip to content

Commit

Permalink
feat: add StdOutLogger and LoggingTrait (#578)
Browse files Browse the repository at this point in the history
Co-authored-by: Brent Shaffer <[email protected]>
  • Loading branch information
Hectorhammett and bshaffer authored Dec 11, 2024
1 parent fe098f5 commit 4f793fe
Show file tree
Hide file tree
Showing 12 changed files with 791 additions and 11 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.4.5",
"psr/http-message": "^1.1||^2.0",
"psr/cache": "^2.0||^3.0"
"psr/cache": "^2.0||^3.0",
"psr/log": "^3.0"
},
"require-dev": {
"guzzlehttp/promises": "^2.0",
Expand Down
42 changes: 39 additions & 3 deletions src/ApplicationDefaultCredentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
use Google\Auth\Credentials\UserRefreshCredentials;
use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory;
use Google\Auth\Logging\StdOutLogger;
use Google\Auth\Middleware\AuthTokenMiddleware;
use Google\Auth\Middleware\ProxyAuthTokenMiddleware;
use Google\Auth\Subscriber\AuthTokenSubscriber;
use GuzzleHttp\Client;
use InvalidArgumentException;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Log\LoggerInterface;

/**
* ApplicationDefaultCredentials obtains the default credentials for
Expand Down Expand Up @@ -70,6 +72,8 @@
*/
class ApplicationDefaultCredentials
{
private const SDK_DEBUG_ENV_VAR = 'GOOGLE_SDK_PHP_LOGGING';

/**
* @deprecated
*
Expand Down Expand Up @@ -146,7 +150,8 @@ public static function getMiddleware(
* user-defined scopes exist, expressed either as an Array or as a
* space-delimited string.
* @param string|null $universeDomain Specifies a universe domain to use for the
* calling client library
* calling client library.
* @param null|false|LoggerInterface $logger A PSR3 compliant LoggerInterface.
*
* @return FetchAuthTokenInterface
* @throws DomainException if no implementation can be obtained.
Expand All @@ -158,7 +163,8 @@ public static function getCredentials(
?CacheItemPoolInterface $cache = null,
$quotaProject = null,
$defaultScope = null,
?string $universeDomain = null
?string $universeDomain = null,
null|false|LoggerInterface $logger = null,
) {
$creds = null;
$jsonKey = CredentialsLoader::fromEnv()
Expand All @@ -171,7 +177,7 @@ public static function getCredentials(
HttpClientCache::setHttpClient($client);
}

$httpHandler = HttpHandlerFactory::build($client);
$httpHandler = HttpHandlerFactory::build($client, $logger);
}

if (is_null($quotaProject)) {
Expand Down Expand Up @@ -318,6 +324,36 @@ public static function getIdTokenCredentials(
return $creds;
}

/**
* Returns a StdOutLogger instance
*
* @internal
*
* @return null|LoggerInterface
*/
public static function getDefaultLogger(): null|LoggerInterface
{
$loggingFlag = getenv(self::SDK_DEBUG_ENV_VAR);

// Env var is not set
if (empty($loggingFlag)) {
return null;
}

$loggingFlag = strtolower($loggingFlag);

// Env Var is not true
if ($loggingFlag !== 'true') {
if ($loggingFlag !== 'false') {
trigger_error('The ' . self::SDK_DEBUG_ENV_VAR . ' is set, but it is set to another value than false or true. Logging is disabled');
}

return null;
}

return new StdOutLogger();
}

/**
* @return string
*/
Expand Down
84 changes: 81 additions & 3 deletions src/HttpHandler/Guzzle6HttpHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,35 @@
*/
namespace Google\Auth\HttpHandler;

use Google\Auth\Logging\LoggingTrait;
use Google\Auth\Logging\RpcLogEvent;
use GuzzleHttp\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;

class Guzzle6HttpHandler
{
use LoggingTrait;

/**
* @var ClientInterface
*/
private $client;

/**
* @var null|LoggerInterface
*/
private $logger;

/**
* @param ClientInterface $client
* @param null|LoggerInterface $logger
*/
public function __construct(ClientInterface $client)
public function __construct(ClientInterface $client, ?LoggerInterface $logger = null)
{
$this->client = $client;
$this->logger = $logger;
}

/**
Expand All @@ -44,7 +56,19 @@ public function __construct(ClientInterface $client)
*/
public function __invoke(RequestInterface $request, array $options = [])
{
return $this->client->send($request, $options);
$requestEvent = null;

if ($this->logger) {
$requestEvent = $this->requestLog($request, $options);
}

$response = $this->client->send($request, $options);

if ($this->logger) {
$this->responseLog($response, $requestEvent);
}

return $response;
}

/**
Expand All @@ -57,6 +81,60 @@ public function __invoke(RequestInterface $request, array $options = [])
*/
public function async(RequestInterface $request, array $options = [])
{
return $this->client->sendAsync($request, $options);
$requestEvent = null;

if ($this->logger) {
$requestEvent = $this->requestLog($request, $options);
}

$promise = $this->client->sendAsync($request, $options);

if ($this->logger) {
$promise->then(function (ResponseInterface $response) use ($requestEvent) {
$this->responseLog($response, $requestEvent);
return $response;
});
}

return $promise;
}

/**
* @internal
* @param RequestInterface $request
* @param array<mixed> $options
*/
public function requestLog(RequestInterface $request, array $options): RpcLogEvent
{
$requestEvent = new RpcLogEvent();

$requestEvent->method = $request->getMethod();
$requestEvent->url = (string) $request->getUri();
$requestEvent->headers = $request->getHeaders();
$requestEvent->payload = $request->getBody()->getContents();
$requestEvent->retryAttempt = $options['retryAttempt'] ?? null;
$requestEvent->serviceName = $options['serviceName'] ?? null;
$requestEvent->processId = (int) getmypid();
$requestEvent->requestId = $options['requestId'] ?? crc32((string) spl_object_id($request) . getmypid());

$this->logRequest($requestEvent);

return $requestEvent;
}

/**
* @internal
*/
public function responseLog(ResponseInterface $response, RpcLogEvent $requestEvent): void
{
$responseEvent = new RpcLogEvent($requestEvent->milliseconds);

$responseEvent->headers = $response->getHeaders();
$responseEvent->payload = $response->getBody()->getContents();
$responseEvent->status = $response->getStatusCode();
$responseEvent->processId = $requestEvent->processId;
$responseEvent->requestId = $requestEvent->requestId;

$this->logResponse($responseEvent);
}
}
17 changes: 13 additions & 4 deletions src/HttpHandler/HttpHandlerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,28 @@
*/
namespace Google\Auth\HttpHandler;

use Google\Auth\ApplicationDefaultCredentials;
use GuzzleHttp\BodySummarizer;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Log\LoggerInterface;

class HttpHandlerFactory
{
/**
* Builds out a default http handler for the installed version of guzzle.
*
* @param ClientInterface|null $client
* @param null|false|LoggerInterface $logger
* @return Guzzle6HttpHandler|Guzzle7HttpHandler
* @throws \Exception
*/
public static function build(?ClientInterface $client = null)
{
public static function build(
?ClientInterface $client = null,
null|false|LoggerInterface $logger = null,
) {
if (is_null($client)) {
$stack = null;
if (class_exists(BodySummarizer::class)) {
Expand All @@ -45,6 +50,10 @@ public static function build(?ClientInterface $client = null)
$client = new Client(['handler' => $stack]);
}

$logger = ($logger === false)
? null
: $logger ?? ApplicationDefaultCredentials::getDefaultLogger();

$version = null;
if (defined('GuzzleHttp\ClientInterface::MAJOR_VERSION')) {
$version = ClientInterface::MAJOR_VERSION;
Expand All @@ -54,9 +63,9 @@ public static function build(?ClientInterface $client = null)

switch ($version) {
case 6:
return new Guzzle6HttpHandler($client);
return new Guzzle6HttpHandler($client, $logger);
case 7:
return new Guzzle7HttpHandler($client);
return new Guzzle7HttpHandler($client, $logger);
default:
throw new \Exception('Version not supported');
}
Expand Down
Loading

0 comments on commit 4f793fe

Please sign in to comment.