2025-02-05 21:57:47 +01:00
|
|
|
<?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 Exception;
|
2025-02-07 16:31:18 +01:00
|
|
|
use Monolog\Handler\AbstractHandler;
|
2025-02-05 21:57:47 +01:00
|
|
|
use Monolog\Handler\AbstractProcessingHandler;
|
2025-02-06 22:51:32 +01:00
|
|
|
use Monolog\Handler\BufferHandler;
|
2025-02-07 16:31:18 +01:00
|
|
|
use Monolog\Handler\DeduplicationHandler;
|
2025-02-06 22:51:32 +01:00
|
|
|
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
|
|
|
|
use Monolog\Handler\FingersCrossedHandler;
|
2025-02-08 13:58:46 +01:00
|
|
|
use Monolog\Handler\HandlerInterface;
|
2025-02-05 21:57:47 +01:00
|
|
|
use Monolog\Handler\RotatingFileHandler;
|
|
|
|
use Monolog\Handler\StreamHandler;
|
|
|
|
use Monolog\Logger;
|
|
|
|
use OxidEsales\Eshop\Core\Registry;
|
|
|
|
use RuntimeException;
|
|
|
|
|
|
|
|
class LoggerFactory
|
|
|
|
{
|
2025-02-06 22:51:32 +01:00
|
|
|
public const SPECIAL_HANDLERS_BUFFERING = 'buffering';
|
|
|
|
public const SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY = 'logOnErrorOnly';
|
2025-02-07 16:31:18 +01:00
|
|
|
public const SPECIAL_HANDLERS_MAKE_UNIQUE = 'makeUnique';
|
|
|
|
|
|
|
|
public const BUFFERING_OPTION_LIMIT = 'bufferLimit';
|
|
|
|
public const BUFFERING_OPTION_LEVEL = 'loglevel';
|
|
|
|
|
|
|
|
public const LOGONERRORONLY_LEVEL = 'activationLevel';
|
|
|
|
|
|
|
|
public const MAKEUNIQUE_OPTION_LEVEL = 'loglevel';
|
|
|
|
public const MAKEUNIQUE_OPTION_TIME = 'time';
|
2025-02-06 22:51:32 +01:00
|
|
|
|
2025-02-05 21:57:47 +01:00
|
|
|
public static function create(): LoggerFactory
|
|
|
|
{
|
|
|
|
return new LoggerFactory();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function getFileLogger(
|
|
|
|
string $loggerName,
|
|
|
|
string $filePath,
|
|
|
|
int $logLevel = Logger::INFO,
|
2025-02-06 22:51:32 +01:00
|
|
|
?int $maxFiles = null,
|
|
|
|
array $specialHandlers = []
|
2025-02-08 22:23:57 +01:00
|
|
|
): Logger {
|
2025-02-05 21:57:47 +01:00
|
|
|
$logger = new Logger($loggerName);
|
2025-02-06 22:51:32 +01:00
|
|
|
$handler = $this->applySpecialHandlers(
|
|
|
|
$this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles),
|
|
|
|
$specialHandlers
|
|
|
|
);
|
|
|
|
$logger->pushHandler($handler);
|
2025-02-05 21:57:47 +01:00
|
|
|
|
|
|
|
return $logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
2025-02-06 22:51:32 +01:00
|
|
|
public function getFileLoggerStreamHandler(
|
2025-02-05 21:57:47 +01:00
|
|
|
string $filePath,
|
|
|
|
int $logLevel = Logger::INFO,
|
|
|
|
?int $maxFiles = null
|
2025-02-08 22:23:57 +01:00
|
|
|
): AbstractProcessingHandler {
|
2025-02-05 21:57:47 +01:00
|
|
|
return is_null($maxFiles) ?
|
|
|
|
new StreamHandler($filePath, $logLevel) :
|
|
|
|
new RotatingFileHandler($filePath, $maxFiles, $logLevel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function getCombinedOxidAndFileLogger(
|
|
|
|
string $loggerName,
|
|
|
|
string $filePath,
|
|
|
|
int $logLevel = Logger::INFO,
|
2025-02-06 22:51:32 +01:00
|
|
|
?int $maxFiles = null,
|
|
|
|
array $specialHandlers = []
|
2025-02-08 22:23:57 +01:00
|
|
|
): Logger {
|
2025-02-05 21:57:47 +01:00
|
|
|
if (!class_exists(Registry::class)) {
|
|
|
|
throw new RuntimeException(__METHOD__.' can executed in OXID eShop installations only');
|
|
|
|
}
|
|
|
|
|
|
|
|
$logger = new Logger($loggerName);
|
2025-02-06 22:51:32 +01:00
|
|
|
$handler = $this->applySpecialHandlers(
|
|
|
|
$this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles),
|
|
|
|
$specialHandlers
|
|
|
|
);
|
|
|
|
$logger->pushHandler($handler);
|
2025-02-05 21:57:47 +01:00
|
|
|
|
|
|
|
$oxidLogFilePath = $this->getOxidLogPath('oxideshop.log');
|
2025-02-06 22:51:32 +01:00
|
|
|
$oxidHandler = $this->applySpecialHandlers(
|
|
|
|
new StreamHandler($oxidLogFilePath, Logger::ERROR),
|
|
|
|
$specialHandlers
|
|
|
|
);
|
|
|
|
$logger->pushHandler($oxidHandler);
|
2025-02-05 21:57:47 +01:00
|
|
|
|
|
|
|
return $logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getOxidLogPath(string $fileName): string
|
|
|
|
{
|
|
|
|
if (!class_exists(Registry::class)) {
|
|
|
|
throw new RuntimeException(__METHOD__.' can executed in OXID eShop installations only');
|
|
|
|
}
|
|
|
|
|
|
|
|
return OX_BASE_PATH . '/log' . DIRECTORY_SEPARATOR . $fileName;
|
|
|
|
}
|
2025-02-06 22:51:32 +01:00
|
|
|
|
|
|
|
public function applySpecialHandlers(
|
|
|
|
AbstractProcessingHandler $handler,
|
|
|
|
array $specialHandlers = []
|
2025-02-08 22:23:57 +01:00
|
|
|
): HandlerInterface {
|
2025-02-06 22:51:32 +01:00
|
|
|
if (in_array(self::SPECIAL_HANDLERS_BUFFERING, $specialHandlers, true)) {
|
2025-02-07 16:31:18 +01:00
|
|
|
$handler = $this->setBuffering($handler);
|
|
|
|
} elseif (in_array(self::SPECIAL_HANDLERS_BUFFERING, array_keys($specialHandlers), true)) {
|
|
|
|
$options = $specialHandlers[self::SPECIAL_HANDLERS_BUFFERING];
|
|
|
|
$handler = $this->setBuffering(
|
|
|
|
$handler,
|
|
|
|
$options[self::BUFFERING_OPTION_LIMIT] ?? 0,
|
|
|
|
$options[self::BUFFERING_OPTION_LEVEL] ?? Logger::DEBUG
|
|
|
|
);
|
2025-02-06 22:51:32 +01:00
|
|
|
}
|
2025-02-07 16:31:18 +01:00
|
|
|
|
2025-02-06 22:51:32 +01:00
|
|
|
if (in_array(self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY, $specialHandlers, true)) {
|
|
|
|
$handler = $this->setLogItemsOnErrorOnly($handler);
|
2025-02-07 16:31:18 +01:00
|
|
|
} elseif (in_array(self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY, array_keys($specialHandlers), true)) {
|
|
|
|
$options = $specialHandlers[self::SPECIAL_HANDLERS_LOG_ON_ERROR_ONLY];
|
|
|
|
$handler = $this->setLogItemsOnErrorOnly(
|
|
|
|
$handler,
|
|
|
|
$options[self::LOGONERRORONLY_LEVEL] ?? Logger::ERROR
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (in_array(self::SPECIAL_HANDLERS_MAKE_UNIQUE, $specialHandlers, true)) {
|
|
|
|
$handler = $this->makeUnique($handler);
|
|
|
|
} elseif (in_array(self::SPECIAL_HANDLERS_MAKE_UNIQUE, array_keys($specialHandlers), true)) {
|
|
|
|
$options = $specialHandlers[self::SPECIAL_HANDLERS_MAKE_UNIQUE];
|
|
|
|
$handler = $this->makeUnique(
|
|
|
|
$handler,
|
|
|
|
$options[self::MAKEUNIQUE_OPTION_LEVEL] ?? Logger::ERROR,
|
|
|
|
$options[self::MAKEUNIQUE_OPTION_TIME] ?? 60
|
|
|
|
);
|
2025-02-06 22:51:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $handler;
|
|
|
|
}
|
|
|
|
|
2025-02-07 16:31:18 +01:00
|
|
|
public function setBuffering(
|
|
|
|
AbstractHandler $handler,
|
|
|
|
int $bufferLimit = 0,
|
|
|
|
int $loglevel = Logger::DEBUG
|
2025-02-08 22:23:57 +01:00
|
|
|
): BufferHandler {
|
2025-02-07 16:31:18 +01:00
|
|
|
return new BufferHandler($handler, $bufferLimit, $loglevel);
|
2025-02-06 22:51:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function setLogItemsOnErrorOnly(
|
2025-02-07 16:31:18 +01:00
|
|
|
AbstractHandler $handler,
|
2025-02-06 22:51:32 +01:00
|
|
|
int $activationLevel = Logger::ERROR
|
2025-02-08 22:23:57 +01:00
|
|
|
): FingersCrossedHandler {
|
2025-02-06 22:51:32 +01:00
|
|
|
return new FingersCrossedHandler(
|
|
|
|
$handler,
|
|
|
|
new ErrorLevelActivationStrategy($activationLevel)
|
|
|
|
);
|
|
|
|
}
|
2025-02-07 16:31:18 +01:00
|
|
|
|
|
|
|
public function makeUnique(
|
|
|
|
AbstractHandler $handler,
|
|
|
|
int $deduplicationLevel = Logger::ERROR,
|
|
|
|
int $time = 60
|
2025-02-08 22:23:57 +01:00
|
|
|
): DeduplicationHandler {
|
2025-02-07 16:31:18 +01:00
|
|
|
return new DeduplicationHandler($handler, null, $deduplicationLevel, $time);
|
|
|
|
}
|
2025-02-08 22:23:57 +01:00
|
|
|
}
|