extract handlers and processors to traits

This commit is contained in:
Daniel Seifert 2025-02-11 22:48:42 +01:00
bovenliggende 1bc0880219
commit babacc9c67
Getekend door: DanielS
GPG sleutel-ID: 6A513E13AEE66170
4 gewijzigde bestanden met toevoegingen van 275 en 100 verwijderingen

Bestand weergeven

@ -34,6 +34,9 @@ use RuntimeException;
class LoggerFactory
{
use SpecialHandlersTrait;
use ProcessorsTrait;
public const SPECIAL_HANDLERS_BUFFERING = 'buffering';
public const SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY = 'logOnErrorOnly';
public const SPECIAL_HANDLERS_MAKE_UNIQUE = 'makeUnique';
@ -156,104 +159,4 @@ class LoggerFactory
return OX_BASE_PATH . '/log' . DIRECTORY_SEPARATOR . $fileName;
}
/**
* @param AbstractProcessingHandler $handler
* @param array<int|string, string|array<string, string|int>> $specialHandlerFlags
* @return HandlerInterface
*/
public function applySpecialHandlers(
AbstractProcessingHandler $handler,
array $specialHandlerFlags = []
): HandlerInterface {
if (in_array(self::SPECIAL_HANDLERS_BUFFERING, $specialHandlerFlags, true)) {
$handler = $this->setBuffering($handler);
} elseif (in_array(self::SPECIAL_HANDLERS_BUFFERING, array_keys($specialHandlerFlags), true)) {
$options = $specialHandlerFlags[self::SPECIAL_HANDLERS_BUFFERING];
$handler = $this->setBuffering(
$handler,
/** @phpstan-ignore argument.type */
$options[self::BUFFERING_OPTION_LIMIT] ?? 0,
/** @phpstan-ignore argument.type */
$options[self::BUFFERING_OPTION_LEVEL] ?? Logger::DEBUG
);
}
if (in_array(self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY, $specialHandlerFlags, true)) {
$handler = $this->setLogItemsOnErrorOnly($handler);
} elseif (in_array(self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY, array_keys($specialHandlerFlags), true)) {
$options = $specialHandlerFlags[self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY];
$handler = $this->setLogItemsOnErrorOnly(
$handler,
/** @phpstan-ignore argument.type */
$options[self::LOGONERRORONLY_LEVEL] ?? Logger::ERROR
);
}
if (in_array(self::SPECIAL_HANDLERS_MAKE_UNIQUE, $specialHandlerFlags, true)) {
/** @phpstan-ignore argument.type */
$handler = $this->makeUnique($handler);
} elseif (in_array(self::SPECIAL_HANDLERS_MAKE_UNIQUE, array_keys($specialHandlerFlags), true)) {
$options = $specialHandlerFlags[self::SPECIAL_HANDLERS_MAKE_UNIQUE];
$handler = $this->makeUnique(
/** @phpstan-ignore argument.type */
$handler,
/** @phpstan-ignore argument.type */
$options[self::MAKEUNIQUE_OPTION_LEVEL] ?? Logger::ERROR,
/** @phpstan-ignore argument.type */
$options[self::MAKEUNIQUE_OPTION_TIME] ?? 60
);
}
return $handler;
}
public function setBuffering(
AbstractHandler $handler,
int $bufferLimit = 0,
int $loglevel = Logger::DEBUG
): BufferHandler {
/** @phpstan-ignore argument.type */
return new BufferHandler($handler, $bufferLimit, $loglevel);
}
public function setLogItemsOnErrorOnly(
AbstractHandler $handler,
int $activationLevel = Logger::ERROR
): FingersCrossedHandler {
return new FingersCrossedHandler(
$handler,
/** @phpstan-ignore argument.type */
new ErrorLevelActivationStrategy($activationLevel)
);
}
public function makeUnique(
AbstractHandler $handler,
int $deduplicationLevel = Logger::ERROR,
int $time = 60
): DeduplicationHandler {
/** @phpstan-ignore argument.type */
return new DeduplicationHandler($handler, null, $deduplicationLevel, $time);
}
public function applyProcessors($logger, array $processorFlags): Logger
{
if (in_array(self::PROCESSOR_UNIQUE_ID, $processorFlags, true)) {
$logger->pushProcessor(new UidProcessor());
}
if (in_array(self::PROCESSOR_FILTERSENSITIVE, array_keys($processorFlags), true)) {
$options = $processorFlags[self::PROCESSOR_FILTERSENSITIVE] ?? [];
$searchList = $options[self::FILTERSENSITIVE_SECRETS] ?? [];
if (!is_array($searchList)) {
throw new RuntimeException('sensitive list must be an array');
}
$logger->pushProcessor(new SensitiveFilterProcessor($searchList));
}
return $logger;
}
}

64
src/ProcessorsTrait.php Normal file
Bestand weergeven

@ -0,0 +1,64 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\LoggerFactory;
use Monolog\Logger;
use Monolog\Processor\UidProcessor;
use RuntimeException;
trait ProcessorsTrait
{
public function applyProcessors($logger, array $processorFlags): Logger
{
$this->applyUidProcessor($processorFlags, $logger);
$this->applyFilterSensitiveProcessor($processorFlags, $logger);
return $logger;
}
/**
* @param array $processorFlags
* @param $logger
* @return void
*/
protected function applyUidProcessor(array $processorFlags, $logger): void
{
if (in_array(self::PROCESSOR_UNIQUE_ID, $processorFlags, true)) {
$logger->pushProcessor(new UidProcessor());
}
}
/**
* @param array $processorFlags
* @param $logger
* @return void
*/
protected function applyFilterSensitiveProcessor(array $processorFlags, $logger): void
{
if (in_array(self::PROCESSOR_FILTERSENSITIVE, array_keys($processorFlags), true)) {
$options = $processorFlags[self::PROCESSOR_FILTERSENSITIVE] ?? [];
$searchList = $options[self::FILTERSENSITIVE_SECRETS] ?? [];
if (!is_array($searchList)) {
throw new RuntimeException('sensitive list must be an array');
}
$logger->pushProcessor(new SensitiveFilterProcessor($searchList));
}
}
}

Bestand weergeven

@ -0,0 +1,69 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\LoggerFactory;
use Monolog\Processor\ProcessorInterface;
class SensitiveFilterProcessor implements ProcessorInterface
{
public function __construct(protected array $secrets, protected ?string $replacement = null)
{
$this->replacement ??= '*****';
$this->convertStringsToRegex($this->secrets);
}
protected function convertStringsToRegex(array $search = []): void
{
array_map(
function ($search) use (&$searchStrings) {
if (!$this->stringIsRegexp($search)) {
$searchStrings[] = '/'.preg_quote($search, '/').'/i';
if (urlencode($search) !== $search) {
$searchStrings[] = '/' . preg_quote(urlencode($search), '/') . '/i';
}
} else {
$searchStrings[] = $search;
}
},
$search
);
$this->secrets = $searchStrings;
}
protected function stringIsRegexp(string $string): bool
{
return @preg_match($string, '') !== false;
}
public function __invoke(array $records): array
{
foreach ($records as $key => $item) {
if (is_string($item)) {
$records[$key] = preg_replace(
$this->secrets,
$this->replacement,
$item
);
} elseif (is_array($item)) {
$records[$key] = $this($item);
}
}
return $records;
}
}

Bestand weergeven

@ -0,0 +1,139 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\LoggerFactory;
use Monolog\Handler\AbstractHandler;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Handler\BufferHandler;
use Monolog\Handler\DeduplicationHandler;
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
use Monolog\Handler\FingersCrossedHandler;
use Monolog\Handler\HandlerInterface;
use Monolog\Logger;
trait SpecialHandlersTrait
{
/**
* @param AbstractProcessingHandler $handler
* @param array<int|string, string|array<string, string|int>> $specialHandlerFlags
* @return HandlerInterface
*/
public function applySpecialHandlers(
AbstractProcessingHandler $handler,
array $specialHandlerFlags = []
): HandlerInterface {
$handler = $this->applyBufferHandler($specialHandlerFlags, $handler);
$handler = $this->applyLogOnErrorOnlyHandler($specialHandlerFlags, $handler);
return $this->applyMakeUniqueHandler($specialHandlerFlags, $handler);
}
public function setBuffering(
AbstractHandler $handler,
int $bufferLimit = 0,
int $loglevel = Logger::DEBUG
): BufferHandler {
/** @phpstan-ignore argument.type */
return new BufferHandler($handler, $bufferLimit, $loglevel);
}
public function setLogItemsOnErrorOnly(
AbstractHandler $handler,
int $activationLevel = Logger::ERROR
): FingersCrossedHandler {
return new FingersCrossedHandler(
$handler,
/** @phpstan-ignore argument.type */
new ErrorLevelActivationStrategy($activationLevel)
);
}
public function makeUnique(
AbstractHandler $handler,
int $deduplicationLevel = Logger::ERROR,
int $time = 60
): DeduplicationHandler {
/** @phpstan-ignore argument.type */
return new DeduplicationHandler($handler, null, $deduplicationLevel, $time);
}
/**
* @param array $specialHandlerFlags
* @param AbstractHandler $handler
* @return AbstractHandler
*/
protected function applyBufferHandler(array $specialHandlerFlags, AbstractHandler $handler): AbstractHandler
{
if (in_array(self::SPECIAL_HANDLERS_BUFFERING, $specialHandlerFlags, true)) {
$handler = $this->setBuffering($handler);
} elseif (in_array(self::SPECIAL_HANDLERS_BUFFERING, array_keys($specialHandlerFlags), true)) {
$options = $specialHandlerFlags[self::SPECIAL_HANDLERS_BUFFERING];
$handler = $this->setBuffering(
$handler,
/** @phpstan-ignore argument.type */
$options[self::BUFFERING_OPTION_LIMIT] ?? 0,
/** @phpstan-ignore argument.type */
$options[self::BUFFERING_OPTION_LEVEL] ?? Logger::DEBUG
);
}
return $handler;
}
/**
* @param array $specialHandlerFlags
* @param AbstractHandler $handler
* @return AbstractHandler
*/
protected function applyLogOnErrorOnlyHandler(array $specialHandlerFlags, AbstractHandler $handler): AbstractHandler
{
if (in_array(self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY, $specialHandlerFlags, true)) {
$handler = $this->setLogItemsOnErrorOnly($handler);
} elseif (in_array(self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY, array_keys($specialHandlerFlags), true)) {
$options = $specialHandlerFlags[self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY];
$handler = $this->setLogItemsOnErrorOnly(
$handler,
/** @phpstan-ignore argument.type */
$options[self::LOGONERRORONLY_LEVEL] ?? Logger::ERROR
);
}
return $handler;
}
/**
* @param array $specialHandlerFlags
* @param AbstractHandler $handler
* @return AbstractHandler
*/
protected function applyMakeUniqueHandler(array $specialHandlerFlags, AbstractHandler $handler): AbstractHandler
{
if (in_array(self::SPECIAL_HANDLERS_MAKE_UNIQUE, $specialHandlerFlags, true)) {
/** @phpstan-ignore argument.type */
$handler = $this->makeUnique($handler);
} elseif (in_array(self::SPECIAL_HANDLERS_MAKE_UNIQUE, array_keys($specialHandlerFlags), true)) {
$options = $specialHandlerFlags[self::SPECIAL_HANDLERS_MAKE_UNIQUE];
$handler = $this->makeUnique(
/** @phpstan-ignore argument.type */
$handler,
/** @phpstan-ignore argument.type */
$options[self::MAKEUNIQUE_OPTION_LEVEL] ?? Logger::ERROR,
/** @phpstan-ignore argument.type */
$options[self::MAKEUNIQUE_OPTION_TIME] ?? 60
);
}
return $handler;
}
}