Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
1d8fd1459a | |||
6915e49ec3 | |||
318b3739af | |||
c9deb0f47c | |||
f46ab842e5 | |||
b69b3d206c | |||
78f6a69a59 | |||
fa142578d8 |
10
CHANGELOG.md
10
CHANGELOG.md
@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased](https://git.d3data.de/D3Public/guzzleFactory/compare/1.1.0...rel_1.x)
|
## [Unreleased](https://git.d3data.de/D3Public/guzzleFactory/compare/1.2.0...rel_1.x)
|
||||||
|
|
||||||
|
## [1.2.0](https://git.d3data.de/D3Public/guzzleFactory/compare/1.1.0...1.2.0) - 2025-02-10
|
||||||
|
### Added
|
||||||
|
- special log handlers
|
||||||
|
### Changed
|
||||||
|
- use [LoggerFactory](https://packagist.org/packages/d3/logger-factory) instead of internal methods
|
||||||
|
|
||||||
## [1.1.0](https://git.d3data.de/D3Public/guzzleFactory/compare/1.0.0...1.1.0) - 2025-01-27
|
## [1.1.0](https://git.d3data.de/D3Public/guzzleFactory/compare/1.0.0...1.1.0) - 2025-01-27
|
||||||
### Added
|
### Added
|
||||||
@ -15,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [1.0.0](https://git.d3data.de/D3Public/guzzleFactory/releases/tag/1.0.0) - 2025-01-01
|
## [1.0.0](https://git.d3data.de/D3Public/guzzleFactory/releases/tag/1.0.0) - 2025-01-01
|
||||||
### Added
|
### Added
|
||||||
- initial implementation
|
- initial implementation
|
||||||
- can create am cutom Guzzle instance
|
- can create a custom Guzzle instance
|
||||||
- "accept" option
|
- "accept" option
|
||||||
- "contentType" option
|
- "contentType" option
|
||||||
- "userAgent" option
|
- "userAgent" option
|
||||||
|
@ -17,7 +17,13 @@ composer require d3/guzzle-factory
|
|||||||
```
|
```
|
||||||
$guzzleFactory = GuzzleFactory::create();
|
$guzzleFactory = GuzzleFactory::create();
|
||||||
$guzzleFactory->setUserAgent('myApi-php-client/1.0.0'));
|
$guzzleFactory->setUserAgent('myApi-php-client/1.0.0'));
|
||||||
$guzzleFactory->addFileLogger('myPluginLogger', 'plugin_requests.log', Logger::DEBUG, 5);
|
$guzzleFactory->addFileLogger(
|
||||||
|
'myPluginLogger',
|
||||||
|
'plugin_requests.log',
|
||||||
|
Logger::DEBUG,
|
||||||
|
5,
|
||||||
|
[\D3\LoggerFactory\LoggerFactory::SPECIAL_HANDLERS_BUFFERING] // optional, see LoggerFactory for details
|
||||||
|
);
|
||||||
$guzzleFactory->setMessageFormatter(
|
$guzzleFactory->setMessageFormatter(
|
||||||
'{method} {uri} HTTP/{version} {req_body}'.PHP_EOL.'RESPONSE: {code} - {res_body}',
|
'{method} {uri} HTTP/{version} {req_body}'.PHP_EOL.'RESPONSE: {code} - {res_body}',
|
||||||
['myUsername', 'myPassword']
|
['myUsername', 'myPassword']
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"guzzlehttp/guzzle": "^7.0",
|
"guzzlehttp/guzzle": "^7.0",
|
||||||
"monolog/monolog": "^1.20",
|
"d3/sensitive-message-formatter": "^1.0",
|
||||||
"d3/sensitive-message-formatter": "^1.0"
|
"d3/logger-factory": "^1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^10.5",
|
"phpunit/phpunit": "^10.5",
|
||||||
|
@ -17,9 +17,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace D3\GuzzleFactory\Apps;
|
namespace D3\GuzzleFactory\Apps;
|
||||||
|
|
||||||
|
use D3\LoggerFactory\LoggerFactory;
|
||||||
use Exception;
|
use Exception;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Monolog\Handler\StreamHandler;
|
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use OxidEsales\Eshop\Core\Registry;
|
use OxidEsales\Eshop\Core\Registry;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
@ -36,35 +36,42 @@ trait OxidLoggerTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws Exception
|
* @param string $loggerName
|
||||||
|
* @param string $filePath
|
||||||
|
* @param int $logLevel
|
||||||
|
* @param int|null $maxFiles
|
||||||
|
* @param array<int|string, string|array<string, string|int>> $specialHandlers
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function addCombinedOxidAndFileLogger(
|
public function addCombinedOxidAndFileLogger(
|
||||||
string $loggerName,
|
string $loggerName,
|
||||||
string $filePath,
|
string $filePath,
|
||||||
int $logLevel = Logger::INFO,
|
int $logLevel = Logger::INFO,
|
||||||
?int $maxFiles = null
|
?int $maxFiles = null,
|
||||||
): void
|
array $specialHandlers = []
|
||||||
{
|
): void {
|
||||||
if (!class_exists(Registry::class)) {
|
|
||||||
throw new RuntimeException(__METHOD__.' can executed in OXID eShop installations only');
|
|
||||||
}
|
|
||||||
|
|
||||||
$logger = new Logger($loggerName);
|
|
||||||
$stream_handler = $this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles);
|
|
||||||
$logger->pushHandler($stream_handler);
|
|
||||||
|
|
||||||
$oxidLogFilePath = $this->getOxidLogPath('oxideshop.log');
|
|
||||||
$oxidStreamHandler = new StreamHandler($oxidLogFilePath, Logger::ERROR);
|
|
||||||
$logger->pushHandler($oxidStreamHandler);
|
|
||||||
|
|
||||||
if (isset($this->loggers['oxid'])) {
|
if (isset($this->loggers['oxid'])) {
|
||||||
unset($this->loggers['oxid']);
|
unset($this->loggers['oxid']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->loggers[$loggerName] = $logger;
|
$this->loggers[$loggerName] = $this->getLoggerFactory()->getCombinedOxidAndFileLogger(
|
||||||
|
$loggerName,
|
||||||
|
$filePath,
|
||||||
|
$logLevel,
|
||||||
|
$maxFiles,
|
||||||
|
/** @phpstan-ignore argument.type */
|
||||||
|
$specialHandlers
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use LoggerFactory::getOxidLogPath
|
||||||
|
* @param string $fileName
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getOxidLogPath(string $fileName): string
|
public function getOxidLogPath(string $fileName): string
|
||||||
{
|
{
|
||||||
if (!class_exists(Registry::class)) {
|
if (!class_exists(Registry::class)) {
|
||||||
|
@ -52,6 +52,7 @@ class GuzzleFactory
|
|||||||
|
|
||||||
foreach ($this->getLoggers() as $logger) {
|
foreach ($this->getLoggers() as $logger) {
|
||||||
/** @var 'alert'|'critical'|'debug'|'emergency'|'error'|'info'|'notice'|'warning' $logLevelName */
|
/** @var 'alert'|'critical'|'debug'|'emergency'|'error'|'info'|'notice'|'warning' $logLevelName */
|
||||||
|
/** @phpstan-ignore argument.type */
|
||||||
$logLevelName = Logger::getLevelName($this->getMessageLevel());
|
$logLevelName = Logger::getLevelName($this->getMessageLevel());
|
||||||
$stack->push(
|
$stack->push(
|
||||||
Middleware::log(
|
Middleware::log(
|
||||||
|
@ -18,11 +18,10 @@ declare(strict_types=1);
|
|||||||
namespace D3\GuzzleFactory;
|
namespace D3\GuzzleFactory;
|
||||||
|
|
||||||
use D3\GuzzleFactory\Apps\OxidLoggerTrait;
|
use D3\GuzzleFactory\Apps\OxidLoggerTrait;
|
||||||
|
use D3\LoggerFactory\LoggerFactory;
|
||||||
use Exception;
|
use Exception;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Monolog\Handler\AbstractProcessingHandler;
|
use Monolog\Handler\AbstractProcessingHandler;
|
||||||
use Monolog\Handler\RotatingFileHandler;
|
|
||||||
use Monolog\Handler\StreamHandler;
|
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
@ -34,25 +33,36 @@ trait LoggerTrait
|
|||||||
protected array $loggers = [];
|
protected array $loggers = [];
|
||||||
protected ?int $messageLevel = null;
|
protected ?int $messageLevel = null;
|
||||||
|
|
||||||
|
protected function getLoggerFactory(): LoggerFactory
|
||||||
|
{
|
||||||
|
return LoggerFactory::create();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws Exception
|
* @param string $loggerName
|
||||||
|
* @param string $filePath
|
||||||
|
* @param int $logLevel
|
||||||
|
* @param int|null $maxFiles
|
||||||
|
* @param array<int|string, string|array<string, string|int>> $specialHandlers
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function addFileLogger(
|
public function addFileLogger(
|
||||||
string $loggerName,
|
string $loggerName,
|
||||||
string $filePath,
|
string $filePath,
|
||||||
int $logLevel = Logger::INFO,
|
int $logLevel = Logger::INFO,
|
||||||
?int $maxFiles = null
|
?int $maxFiles = null,
|
||||||
): void
|
array $specialHandlers = [] // see LoggerFactory constants
|
||||||
{
|
): void {
|
||||||
$logger = new Logger($loggerName);
|
$this->loggers[$loggerName] = $this->getLoggerFactory()
|
||||||
$stream_handler = $this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles);
|
/** @phpstan-ignore argument.type */
|
||||||
$logger->pushHandler($stream_handler);
|
->getFileLogger($loggerName, $filePath, $logLevel, $maxFiles, $specialHandlers);
|
||||||
|
|
||||||
$this->loggers[$loggerName] = $logger;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated use LoggerFactory::getFileLoggerStreamHandler
|
||||||
* @param string $filePath
|
* @param string $filePath
|
||||||
* @param int $logLevel
|
* @param int $logLevel
|
||||||
* @param int|null $maxFiles
|
* @param int|null $maxFiles
|
||||||
@ -63,11 +73,8 @@ trait LoggerTrait
|
|||||||
string $filePath,
|
string $filePath,
|
||||||
int $logLevel = Logger::INFO,
|
int $logLevel = Logger::INFO,
|
||||||
?int $maxFiles = null
|
?int $maxFiles = null
|
||||||
): AbstractProcessingHandler
|
): AbstractProcessingHandler {
|
||||||
{
|
return $this->getLoggerFactory()->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles);
|
||||||
return is_null($maxFiles) ?
|
|
||||||
new StreamHandler($filePath, $logLevel) :
|
|
||||||
new RotatingFileHandler($filePath, $maxFiles, $logLevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addConfiguredLogger(LoggerInterface $logger): void
|
public function addConfiguredLogger(LoggerInterface $logger): void
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
namespace D3\GuzzleFactory\tests\Apps;
|
namespace D3\GuzzleFactory\tests\Apps;
|
||||||
|
|
||||||
use D3\GuzzleFactory\GuzzleFactory;
|
use D3\GuzzleFactory\GuzzleFactory;
|
||||||
|
use D3\LoggerFactory\LoggerFactory;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
@ -40,25 +41,6 @@ trait OxidLoggerTestTrait
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
* @return void
|
|
||||||
* @throws ReflectionException
|
|
||||||
* @covers \D3\GuzzleFactory\GuzzleFactory::addCombinedOxidAndFileLogger
|
|
||||||
*/
|
|
||||||
public function testAddCombinedOxidAndFileLoggerWithoutOxid(): void
|
|
||||||
{
|
|
||||||
$sut = GuzzleFactory::create();
|
|
||||||
|
|
||||||
$this->expectException(RuntimeException::class);
|
|
||||||
|
|
||||||
$this->callMethod(
|
|
||||||
$sut,
|
|
||||||
'addCombinedOxidAndFileLogger',
|
|
||||||
['nameFixture', 'file/path.log', 1, 5]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @return void
|
* @return void
|
||||||
@ -109,11 +91,19 @@ trait OxidLoggerTestTrait
|
|||||||
* @throws ReflectionException
|
* @throws ReflectionException
|
||||||
* @covers \D3\GuzzleFactory\GuzzleFactory::addCombinedOxidAndFileLogger
|
* @covers \D3\GuzzleFactory\GuzzleFactory::addCombinedOxidAndFileLogger
|
||||||
*/
|
*/
|
||||||
public function testAddCombinedOxidAndFileLoggerInOxid(): void
|
public function testAddCombinedOxidAndFileLogger(): void
|
||||||
{
|
{
|
||||||
require_once __DIR__.'/../Helpers/classAliases.php';
|
require_once __DIR__.'/../Helpers/classAliases.php';
|
||||||
|
|
||||||
$sut = GuzzleFactory::create();
|
$loggerFactory = $this->getMockBuilder(LoggerFactory::class)
|
||||||
|
->onlyMethods(['getCombinedOxidAndFileLogger'])
|
||||||
|
->getMock();
|
||||||
|
$loggerFactory->expects($this->once())->method('getCombinedOxidAndFileLogger');
|
||||||
|
|
||||||
|
$sut = $this->getMockBuilder(GuzzleFactory::class)
|
||||||
|
->onlyMethods(['getLoggerFactory'])
|
||||||
|
->getMock();
|
||||||
|
$sut->method('getLoggerFactory')->willReturn($loggerFactory);
|
||||||
|
|
||||||
$this->setValue($sut, 'loggers', ['oxid' => 1]);
|
$this->setValue($sut, 'loggers', ['oxid' => 1]);
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
namespace D3\GuzzleFactory\tests;
|
namespace D3\GuzzleFactory\tests;
|
||||||
|
|
||||||
use D3\GuzzleFactory\GuzzleFactory;
|
use D3\GuzzleFactory\GuzzleFactory;
|
||||||
|
use D3\LoggerFactory\LoggerFactory;
|
||||||
use Generator;
|
use Generator;
|
||||||
use Monolog\Handler\RotatingFileHandler;
|
|
||||||
use Monolog\Handler\StreamHandler;
|
use Monolog\Handler\StreamHandler;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
@ -26,15 +26,45 @@ trait LoggerTestTrait
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
|
* @return void
|
||||||
* @throws ReflectionException
|
* @throws ReflectionException
|
||||||
* @covers \D3\GuzzleFactory\GuzzleFactory::addFileLogger
|
* @covers \D3\GuzzleFactory\GuzzleFactory::getLoggerFactory
|
||||||
* @covers \D3\GuzzleFactory\GuzzleFactory::getFileLoggerStreamHandler
|
|
||||||
* @dataProvider addFileLoggerDataProvider
|
|
||||||
*/
|
*/
|
||||||
public function testAddFileLogger(int $logLevel, ?int $maxFiles, string $expectedHandlerClass): void
|
public function testGetLoggerFactory(): void
|
||||||
{
|
{
|
||||||
$sut = GuzzleFactory::create();
|
$sut = GuzzleFactory::create();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(
|
||||||
|
LoggerFactory::class,
|
||||||
|
$this->callMethod(
|
||||||
|
$sut,
|
||||||
|
'getLoggerFactory',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @throws ReflectionException
|
||||||
|
* @covers \D3\GuzzleFactory\GuzzleFactory::addFileLogger
|
||||||
|
* @dataProvider addFileLoggerDataProvider
|
||||||
|
*/
|
||||||
|
public function testAddFileLogger(int $logLevel, ?int $maxFiles): void
|
||||||
|
{
|
||||||
|
$logger = $this->getMockBuilder(Logger::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$loggerFactory = $this->getMockBuilder(LoggerFactory::class)
|
||||||
|
->onlyMethods(['getFileLogger'])
|
||||||
|
->getMock();
|
||||||
|
$loggerFactory->expects($this->once())->method('getFileLogger')->willReturn($logger);
|
||||||
|
|
||||||
|
$sut = $this->getMockBuilder(GuzzleFactory::class)
|
||||||
|
->onlyMethods(['getLoggerFactory'])
|
||||||
|
->getMock();
|
||||||
|
$sut->method("getLoggerFactory")->willReturn($loggerFactory);
|
||||||
|
|
||||||
$this->callMethod(
|
$this->callMethod(
|
||||||
$sut,
|
$sut,
|
||||||
'addFileLogger',
|
'addFileLogger',
|
||||||
@ -44,15 +74,36 @@ trait LoggerTestTrait
|
|||||||
$loggers = $this->getValue($sut, 'loggers');
|
$loggers = $this->getValue($sut, 'loggers');
|
||||||
$this->assertArrayHasKey('nameFixture', $loggers);
|
$this->assertArrayHasKey('nameFixture', $loggers);
|
||||||
$this->assertInstanceOf(Logger::class, $loggers['nameFixture']);
|
$this->assertInstanceOf(Logger::class, $loggers['nameFixture']);
|
||||||
$this->assertInstanceOf($expectedHandlerClass, $loggers['nameFixture']->getHandlers()[0]);
|
|
||||||
$this->assertSame($logLevel, $loggers['nameFixture']->popHandler('nameFixture')->getLevel());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function addFileLoggerDataProvider(): Generator
|
public static function addFileLoggerDataProvider(): Generator
|
||||||
{
|
{
|
||||||
yield 'no rotation' => [Logger::INFO, null, StreamHandler::class];
|
yield [Logger::INFO, null];
|
||||||
yield 'rotation 1' => [Logger::ERROR, 1, RotatingFileHandler::class];
|
}
|
||||||
yield 'rotation 20' => [Logger::DEBUG, 20, RotatingFileHandler::class];
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @return void
|
||||||
|
* @throws ReflectionException
|
||||||
|
* @covers \D3\GuzzleFactory\GuzzleFactory::getFileLoggerStreamHandler
|
||||||
|
*/
|
||||||
|
public function testGetFileLoggerStreamHandler(): void
|
||||||
|
{
|
||||||
|
$loggerFactory = $this->getMockBuilder(LoggerFactory::class)
|
||||||
|
->onlyMethods(['getFileLoggerStreamHandler'])
|
||||||
|
->getMock();
|
||||||
|
$loggerFactory->expects($this->once())->method('getFileLoggerStreamHandler');
|
||||||
|
|
||||||
|
$sut = $this->getMockBuilder(GuzzleFactory::class)
|
||||||
|
->onlyMethods(['getLoggerFactory'])
|
||||||
|
->getMock();
|
||||||
|
$sut->method("getLoggerFactory")->willReturn($loggerFactory);
|
||||||
|
|
||||||
|
$this->callMethod(
|
||||||
|
$sut,
|
||||||
|
'getFileLoggerStreamHandler',
|
||||||
|
['file/path.log', Logger::ERROR, 2]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user