Skip to content

Commit

Permalink
feat: add logging
Browse files Browse the repository at this point in the history
  • Loading branch information
TPete committed Jan 20, 2022
1 parent 3a5ca5c commit d9b3755
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 7 deletions.
66 changes: 59 additions & 7 deletions lib/CommunicationAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

use Checkdomain\Comodo\Model\Account;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\MessageFormatter;
use GuzzleHttp\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;

/**
* Class CommunicationAdapter
Expand All @@ -24,6 +31,21 @@ class CommunicationAdapter
*/
protected $account;

/**
* @var LoggerInterface
*/
protected $logger;

/**
* @var HandlerStack
*/
protected $handlerStack;

/**
* @var array
*/
protected $denyList;

/**
* @param \Checkdomain\Comodo\Model\Account $account
*
Expand All @@ -44,14 +66,18 @@ public function getAccount()
return $this->account;
}

/**
* Constructs a communication adapter with an account
*
* @param Account $account
*/
public function __construct(Account $account = null)
public function __construct(Account $account = null, LoggerInterface $logger = null, array $denyList = [])
{
$this->account = $account;
$this->denyList = $denyList;
$this->handlerStack = HandlerStack::create();

if ($logger) {
$this->logger = $logger;
$this->handlerStack = $this->addLogMiddleware($this->handlerStack);
} else {
$this->logger = new NullLogger();
}
}

/**
Expand All @@ -72,7 +98,7 @@ public function setClient($client)
public function getClient()
{
if ($this->client === null) {
$this->client = new Client();
$this->client = new Client(['handler' => $this->handlerStack]);
}

return $this->client;
Expand Down Expand Up @@ -281,4 +307,30 @@ protected function decodeUrlEncodedResponse(

return $responseArray;
}

protected function addLogMiddleware(HandlerStack $handlerStack)
{
$handlerStack->push(
Middleware::mapResponse(
function (ResponseInterface $response) {
$response->getBody()->rewind();

return $response;
}
)
);

$handlerStack->push(
Middleware::log(
$this->logger,
new SanitizingMessageFormatter(
'{method} {uri} HTTP/{version} - Body: {req_body} | {code} - Body: {res_body}',
$this->denyList
),
LogLevel::DEBUG
)
);

return $handlerStack;
}
}
130 changes: 130 additions & 0 deletions lib/SanitizingMessageFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

namespace Checkdomain\Comodo;

use GuzzleHttp\MessageFormatter;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;

/**
* Class SanitizingMessageFormatter
*/
class SanitizingMessageFormatter extends MessageFormatter
{
/** @var string Template used to format log messages */
private $template;

/**
* @var array
*/
private $denyList;

/**
* @param string $template Log message template
* @param array $denyList
*/
public function __construct($template, array $denyList = [])
{
parent::__construct($template);
$this->template = $template;
$this->blacklist = $denyList;
}

/**
* @param RequestInterface $request
* @param ResponseInterface|null $response
* @param \Exception|null $error
*
* @return string|string[]|null
*/
public function format(RequestInterface $request, ResponseInterface $response = null, \Exception $error = null)
{
$cache = [];

return preg_replace_callback(
'/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
function (array $matches) use ($request, $response, $error, &$cache) {
if (isset($cache[$matches[1]])) {
return $cache[$matches[1]];
}

$result = '';
switch ($matches[1]) {
case 'req_body':
$result = $this->sanitizeBody($request->getBody());
break;
case 'res_body':
$result = $response ? $this->sanitizeBody($response->getBody()) : 'NULL';
break;
case 'method':
$result = $request->getMethod();
break;
case 'version':
$result = $request->getProtocolVersion();
break;
case 'uri':
case 'url':
$result = $request->getUri();
break;
case 'code':
$result = $response ? $response->getStatusCode() : 'NULL';
break;
}

$cache[$matches[1]] = $result;

return $result;
},
$this->template
);
}

/**
* @param StreamInterface $body
*
* @return string
*/
private function sanitizeBody(StreamInterface $body)
{
$body->rewind();
$content = $body->getContents();

if (false === empty($content)) {
$parsed = [];
parse_str($content, $parsed);

if (is_array($parsed)) {
$parsed = $this->sanitize($parsed);
}
}

return false === empty($parsed) ? http_build_query($parsed) : '';
}

/**
* @param array $iterable
*
* @return array
*/
private function sanitize(array $iterable)
{
$filtered = [];

foreach ($iterable as $key => $item) {
if (is_string($key) && is_string($item)) {
if (in_array($key, $this->blacklist)) {
$item = 'sanitized';
}
}

if (is_array($item)) {
$item = $this->sanitize($item);
}

$filtered[$key] = $item;
}

return $filtered;
}
}

0 comments on commit d9b3755

Please sign in to comment.