Skip to content

Commit

Permalink
Added JsonLoggingFormatter, min version php 8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
slischka committed Jan 13, 2024
1 parent fd99ebb commit 94a20e5
Show file tree
Hide file tree
Showing 35 changed files with 451 additions and 448 deletions.
4 changes: 2 additions & 2 deletions .docker-http-client/http-client/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM php:8.0-fpm-alpine
FROM php:8.1-fpm-alpine

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

WORKDIR /http-client
WORKDIR /http-client
28 changes: 14 additions & 14 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@
}
],
"require": {
"php": ">=7.1",
"composer/ca-bundle": "^1.1",
"psr/log": "^1.0",
"psr/http-message": "^1.0",
"php": ">=8.1",
"composer/ca-bundle": "^1.4",
"psr/log": "^3.0",
"psr/http-message": "^1.0 | ^2.0",
"psr/http-client": "^1.0",
"guzzlehttp/psr7": "^1.4 | ^2.0",
"guzzlehttp/psr7": "^1.4 |^2.6",
"ext-json": "*",
"ext-curl": "*"
},
"require-dev": {
"nette/tester": ">=2.3",
"nette/tester": "^2.5",
"guzzlehttp/guzzle": "^6.0 | ^7.0",
"tracy/tracy": ">=2.7",
"nette/di": "^3.0",
"phpstan/phpstan": "^0.12.85",
"phpstan/phpstan-nette": "^0.12.17",
"react/http": "^1.3",
"react/child-process": "^0.6.2",
"phpstan/phpstan-strict-rules": "^0.12.9",
"orisai/coding-standard": "^1.1"
"tracy/tracy": "^2.10",
"nette/di": "^3.1",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-nette": "^1.2",
"react/http": "^1.9",
"react/child-process": "^0.6.5",
"phpstan/phpstan-strict-rules": "^1.5",
"orisai/coding-standard": "^3.10"
},
"suggest": {
"ext-curl": "to use class CurlHttpClient",
Expand Down
113 changes: 1 addition & 112 deletions src/Fapi/HttpClient/BaseLoggingFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,118 +2,7 @@

namespace Fapi\HttpClient;

use Fapi\HttpClient\Utils\Json;
use Fapi\HttpClient\Utils\JsonException;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Throwable;
use function base64_encode;
use function extension_loaded;
use function function_exists;
use function get_class;
use function iconv_substr;
use function mb_substr;
use function serialize;
use function sprintf;
use function strlen;
use function substr;
use const JSON_UNESCAPED_UNICODE;

final class BaseLoggingFormatter implements ILoggingFormatter
final class BaseLoggingFormatter extends \Fapi\HttpClient\LoggingFormatters\BaseLoggingFormatter implements ILoggingFormatter
{

/** @var int */
private $maxBodyLength;

public function __construct(int $maxBodyLength = 40000)
{
$this->maxBodyLength = $maxBodyLength;
}

public function formatSuccessful(RequestInterface $request, ResponseInterface $response, float $elapsedTime): string
{
return 'Fapi\HttpClient: an HTTP request has been sent.'
. $this->dumpHttpRequest($request)
. $this->dumpHttpResponse($response)
. $this->dumpElapsedTime($elapsedTime);
}

public function formatFailed(RequestInterface $request, Throwable $exception, float $elapsedTime): string
{
return 'Fapi\HttpClient: an HTTP request failed.'
. $this->dumpHttpRequest($request)
. $this->dumpException($exception)
. $this->dumpElapsedTime($elapsedTime);
}

private function dumpHttpRequest(RequestInterface $request): string
{
$body = $this->processBody((string) $request->getBody());

return ' Request URL: ' . $this->dumpValue((string) $request->getUri())
. ' Request method: ' . $this->dumpValue($request->getMethod())
. ' Request headers: ' . $this->dumpValue($request->getHeaders())
. ' Request body: ' . $this->dumpValue($body);
}

private function dumpHttpResponse(ResponseInterface $response): string
{
$body = $this->processBody((string) $response->getBody());

return ' Response status code: ' . $this->dumpValue($response->getStatusCode())
. ' Response headers: ' . $this->dumpValue($response->getHeaders())
. ' Response body: ' . $this->dumpValue($body);
}

private function dumpException(Throwable $exception): string
{
$dump = ' Exception type: ' . $this->dumpValue(get_class($exception))
. ' Exception message: ' . $this->dumpValue($exception->getMessage());

if ($exception->getPrevious() !== null) {
$previousException = $exception->getPrevious();

$dump .= ' Previous exception type: ' . $this->dumpValue(get_class($previousException))
. ' Previous exception message: ' . $this->dumpValue($previousException->getMessage());
}

return $dump;
}

private function dumpElapsedTime(float $elapsedTime): string
{
$elapsedTime *= 1000;

return ' Elapsed time: ' . sprintf('%0.2f', $elapsedTime) . ' ms';
}

/**
* @param mixed $value
*/
private function dumpValue($value): string
{
try {
return Json::encode($value, JSON_UNESCAPED_UNICODE);
} catch (JsonException $e) {
return '(serialized) ' . base64_encode(serialize($value));
}
}

private function processBody(string $body): string
{
if (strlen($body) <= $this->maxBodyLength) {
return $body;
}

if (function_exists('mb_substr')) {
return mb_substr($body, 0, $this->maxBodyLength, 'UTF-8');
}

if (!extension_loaded('iconv')) {
return (string) iconv_substr($body, 0, $this->maxBodyLength, 'UTF-8');
}

return substr($body, 0, $this->maxBodyLength);
}

}
6 changes: 3 additions & 3 deletions src/Fapi/HttpClient/Bridges/NetteDI/HttpClientExtension.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types = 1);

namespace Fapi\HttpClient\Bidges\NetteDI;
namespace Fapi\HttpClient\Bridges\NetteDI;

use Fapi\HttpClient\Bridges\Tracy\BarHttpClient;
use Fapi\HttpClient\Bridges\Tracy\TracyToPsrLogger;
Expand All @@ -15,14 +15,14 @@ class HttpClientExtension extends CompilerExtension
{

/** @var array<mixed> */
public $defaults = [
public array $defaults = [
'type' => 'guzzle',
'logging' => false,
'bar' => false,
];

/** @var array<string> */
private $typeClasses = [
private array $typeClasses = [
'curl' => CurlHttpClient::class,
'guzzle' => GuzzleHttpClient::class,
];
Expand Down
17 changes: 5 additions & 12 deletions src/Fapi/HttpClient/Bridges/Tracy/BarHttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,17 @@
final class BarHttpClient implements IHttpClient, IBarPanel
{

/** @var int */
private $maxRequests = 100;

/** @var IHttpClient */
private $httpClient;
private int $maxRequests = 100;

/** @var array<mixed> */
private $requests = [];
private array $requests = [];

/** @var int */
private $count = 0;
private int $count = 0;

/** @var float */
private $totalTime = 0.0;
private float $totalTime = 0.0;

public function __construct(IHttpClient $httpClient)
public function __construct(private IHttpClient $httpClient)
{
$this->httpClient = $httpClient;
Debugger::getBar()->addPanel($this);
}

Expand Down
11 changes: 5 additions & 6 deletions src/Fapi/HttpClient/Bridges/Tracy/TracyToPsrLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Psr\Log\AbstractLogger;
use Psr\Log\LogLevel;
use Stringable;
use Throwable;
use Tracy\ILogger;

Expand All @@ -21,18 +22,16 @@ final class TracyToPsrLogger extends AbstractLogger
LogLevel::DEBUG => ILogger::DEBUG,
];

/** @var ILogger */
private $tracyLogger;

public function __construct(ILogger $tracyLogger)
public function __construct(private ILogger $tracyLogger)
{
$this->tracyLogger = $tracyLogger;
}

/**
* @param array<mixed> $context
*
* @inheritdoc
*/
public function log($level, $message, array $context = [])
public function log($level, string|Stringable $message, array $context = []): void
{
$priority = self::PRIORITY_MAP[$level] ?? ILogger::ERROR;

Expand Down
38 changes: 12 additions & 26 deletions src/Fapi/HttpClient/CapturingHttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,29 @@
class CapturingHttpClient implements IHttpClient
{

/** @var IHttpClient */
private $httpClient;

/** @var array<RequestInterface> */
private $httpRequests = [];
private array $httpRequests = [];

/** @var array<ResponseInterface> */
private $httpResponses = [];

/** @var string */
private $file;

/** @var string */
private $className;
private array $httpResponses = [];

public function __construct(IHttpClient $httpClient, string $file, string $className)
public function __construct(private IHttpClient $httpClient, private string $file, private string $className)
{
if (!class_exists('Tester\Dumper')) {
throw new InvalidStateException('Capturing HTTP client requires Nette Tester.');
}

$this->httpClient = $httpClient;

if (is_file($file)) {
require_once $file;
spl_autoload($className);

if (class_exists($className)) {
$this->httpClient = new $className();
/** @var IHttpClient $httpClient */
$httpClient = new $className();

$this->httpClient = $httpClient;
}
}

$this->file = $file;
$this->className = $className;
}

public function sendRequest(RequestInterface $request): ResponseInterface
Expand Down Expand Up @@ -82,7 +71,7 @@ private function writeToPhpFile(string $fileName, string $className): void
$code = '<?php declare(strict_types = 1);' . "\n";
$code .= "\n";
if ($namespace) {
if ((bool) $namespace) {
$code .= 'namespace ' . $namespace . ';' . "\n";
$code .= "\n";
}
Expand All @@ -106,13 +95,13 @@ private function writeToPhpFile(string $fileName, string $className): void
$code .= "\t\t\t\t" . $this->exportValue((string) $httpRequest->getUri(), "\t\t\t\t") . ",\n";
$code .= "\t\t\t\t" . $this->exportValue($httpRequest->getHeaders(), "\t\t\t\t") . ",\n";
$code .= "\t\t\t\t" . $this->exportValue((string) $httpRequest->getBody(), "\t\t\t\t") . ",\n";
$code .= "\t\t\t\t" . $this->exportValue($httpRequest->getProtocolVersion(), "\t\t\t\t") . "\n";
$code .= "\t\t\t\t" . $this->exportValue($httpRequest->getProtocolVersion(), "\t\t\t\t") . ",\n";
$code .= "\t\t\t" . '),' . "\n";
$code .= "\t\t\t" . 'new HttpResponse(' . "\n";
$code .= "\t\t\t\t" . $this->exportValue($httpResponse->getStatusCode(), "\t\t\t\t") . ",\n";
$code .= "\t\t\t\t" . $this->exportValue($httpResponse->getHeaders(), "\t\t\t\t") . ",\n";
$code .= "\t\t\t\t" . $this->exportValue((string) $httpResponse->getBody(), "\t\t\t\t") . "\n";
$code .= "\t\t\t" . ')' . "\n";
$code .= "\t\t\t\t" . $this->exportValue((string) $httpResponse->getBody(), "\t\t\t\t") . ",\n";
$code .= "\t\t\t" . ')' . ",\n";
$code .= "\t\t" . ');' . "\n";
}

Expand All @@ -123,10 +112,7 @@ private function writeToPhpFile(string $fileName, string $className): void
file_put_contents($fileName, $code);
}

/**
* @param mixed $value
*/
private function exportValue($value, string $indent = ''): string
private function exportValue(mixed $value, string $indent = ''): string
{
$s = Dumper::toPhp($value);
$s = str_replace("\n", "\n" . $indent, $s);
Expand Down
Loading

0 comments on commit 94a20e5

Please sign in to comment.