* @link https://www.oxidmodule.com */ declare(strict_types=1); namespace D3\LoggerFactory; use Exception; 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\Handler\RotatingFileHandler; use Monolog\Handler\StreamHandler; use Monolog\Logger; use Monolog\Processor\UidProcessor; use OxidEsales\Eshop\Core\Registry; 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'; 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'; public const PROCESSOR_UNIQUE_ID = 'processorUId'; public const PROCESSOR_FILTERSENSITIVE = 'processorFilterSensitive'; public const FILTERSENSITIVE_SECRETS = 'secrets'; public static function create(): LoggerFactory { return new LoggerFactory(); } /** * @param string $loggerName * @param string $filePath * @param int $logLevel * @param int|null $maxFiles * @param array> $specialHandlerFlags * @param array> $processorFlags * @return Logger * @throws Exception */ public function getFileLogger( string $loggerName, string $filePath, int $logLevel = Logger::INFO, ?int $maxFiles = null, array $specialHandlerFlags = [], array $processorFlags = [] ): Logger { $logger = new Logger($loggerName); $handler = $this->applySpecialHandlers( $this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles), $specialHandlerFlags ); $logger->pushHandler($handler); $this->applyProcessors( $logger, $processorFlags ); return $logger; } /** * @throws Exception */ public function getFileLoggerStreamHandler( string $filePath, int $logLevel = Logger::INFO, ?int $maxFiles = null ): AbstractProcessingHandler { return is_null($maxFiles) ? /** @phpstan-ignore argument.type */ new StreamHandler($filePath, $logLevel) : /** @phpstan-ignore argument.type */ new RotatingFileHandler($filePath, $maxFiles, $logLevel); } /** * @param string $loggerName * @param string $filePath * @param int $logLevel * @param int|null $maxFiles * @param array> $specialHandlerFlags * @param array> $processorFlags * @return Logger * @throws Exception */ public function getCombinedOxidAndFileLogger( string $loggerName, string $filePath, int $logLevel = Logger::INFO, ?int $maxFiles = null, array $specialHandlerFlags = [], array $processorFlags = [] ): Logger { if (!class_exists(Registry::class)) { throw new RuntimeException(__METHOD__.' can executed in OXID eShop installations only'); } $logger = new Logger($loggerName); $handler = $this->applySpecialHandlers( $this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles), $specialHandlerFlags ); $logger->pushHandler($handler); $oxidLogFilePath = $this->getOxidLogPath('oxideshop.log'); $oxidHandler = $this->applySpecialHandlers( new StreamHandler($oxidLogFilePath, Logger::ERROR), $specialHandlerFlags ); $logger->pushHandler($oxidHandler); $this->applyProcessors( $logger, $processorFlags ); return $logger; } public 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; } }