From 184f6cc255ff40e4db428bc256127403b03bd087 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 23 Oct 2021 12:22:27 +0200 Subject: [PATCH] Restructure Logger to new paradigm --- src/Core/Logger.php | 2 +- .../Exception/LoggerArgumentException.php | 13 ++++ src/Core/Logger/Exception/LoggerException.php | 13 ++++ .../Logger/Factory/Logger.php} | 68 +++++++++---------- .../Logger/Type}/AbstractLogger.php | 41 ++++++----- .../Logger/Type}/Monolog/DevelopHandler.php | 9 ++- .../Type}/Monolog/IntrospectionProcessor.php | 6 +- .../Logger/Type}/ProfilerLogger.php | 23 +++---- .../Logger => Core/Logger/Type}/README.md | 0 .../Logger/Type}/StreamLogger.php | 50 ++++++++++---- .../Logger/Type}/SyslogLogger.php | 47 +++++++------ .../Logger/Type}/VoidLogger.php | 2 +- .../Logger/Type}/WorkerLogger.php | 27 +++++--- src/DI.php | 2 +- src/Util/FileSystem.php | 4 +- static/dependencies.config.php | 4 +- .../AutomaticInstallationConsoleTest.php | 2 +- .../Factory/FriendSuggestTest.php | 2 +- .../Logger/AbstractLoggerTest.php | 2 +- .../{Util => Core}/Logger/LoggerDataTrait.php | 2 +- .../Logger/ProfilerLoggerTest.php | 4 +- .../Logger/StreamLoggerTest.php | 20 +++--- .../Logger/SyslogLoggerTest.php | 27 ++------ .../Logger/SyslogLoggerWrapper.php | 6 +- .../{Util => Core}/Logger/VoidLoggerTest.php | 4 +- .../Logger/WorkerLoggerTest.php | 4 +- .../ProfileField/Entity/ProfileFieldTest.php | 2 +- .../TwoFactor/Factory/TrustedBrowserTest.php | 2 +- 28 files changed, 219 insertions(+), 169 deletions(-) create mode 100644 src/Core/Logger/Exception/LoggerArgumentException.php create mode 100644 src/Core/Logger/Exception/LoggerException.php rename src/{Factory/LoggerFactory.php => Core/Logger/Factory/Logger.php} (81%) rename src/{Util/Logger => Core/Logger/Type}/AbstractLogger.php (77%) rename src/{Util/Logger => Core/Logger/Type}/Monolog/DevelopHandler.php (93%) rename src/{Util/Logger => Core/Logger/Type}/Monolog/IntrospectionProcessor.php (92%) rename src/{Util/Logger => Core/Logger/Type}/ProfilerLogger.php (82%) rename src/{Util/Logger => Core/Logger/Type}/README.md (100%) rename src/{Util/Logger => Core/Logger/Type}/StreamLogger.php (72%) rename src/{Util/Logger => Core/Logger/Type}/SyslogLogger.php (76%) rename src/{Util/Logger => Core/Logger/Type}/VoidLogger.php (98%) rename src/{Util/Logger => Core/Logger/Type}/WorkerLogger.php (84%) rename tests/src/{Util => Core}/Logger/AbstractLoggerTest.php (99%) rename tests/src/{Util => Core}/Logger/LoggerDataTrait.php (97%) rename tests/src/{Util => Core}/Logger/ProfilerLoggerTest.php (96%) rename tests/src/{Util => Core}/Logger/StreamLoggerTest.php (87%) rename tests/src/{Util => Core}/Logger/SyslogLoggerTest.php (72%) rename tests/src/{Util => Core}/Logger/SyslogLoggerWrapper.php (91%) rename tests/src/{Util => Core}/Logger/VoidLoggerTest.php (94%) rename tests/src/{Util => Core}/Logger/WorkerLoggerTest.php (97%) diff --git a/src/Core/Logger.php b/src/Core/Logger.php index 6dde142cc9..4e2575d1b9 100644 --- a/src/Core/Logger.php +++ b/src/Core/Logger.php @@ -22,7 +22,7 @@ namespace Friendica\Core; use Friendica\DI; -use Friendica\Util\Logger\WorkerLogger; +use Friendica\Core\Logger\Type\WorkerLogger; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; diff --git a/src/Core/Logger/Exception/LoggerArgumentException.php b/src/Core/Logger/Exception/LoggerArgumentException.php new file mode 100644 index 0000000000..1b5f653f43 --- /dev/null +++ b/src/Core/Logger/Exception/LoggerArgumentException.php @@ -0,0 +1,13 @@ +get('system', 'debugging', false))) { $logger = new VoidLogger(); @@ -106,6 +106,7 @@ class LoggerFactory static::addStreamHandler($logger, $stream, $loglevel); } catch (\Throwable $e) { // No Logger .. + /// @todo isn't it possible to give the admin any hint about this wrong configuration? $logger = new VoidLogger(); } } @@ -116,6 +117,7 @@ class LoggerFactory $logger = new SyslogLogger($this->channel, $introspection, $loglevel); } catch (\Throwable $e) { // No logger ... + /// @todo isn't it possible to give the admin any hint about this wrong configuration? $logger = new VoidLogger(); } break; @@ -129,9 +131,11 @@ class LoggerFactory $logger = new StreamLogger($this->channel, $stream, $introspection, $fileSystem, $loglevel); } catch (\Throwable $t) { // No logger ... + /// @todo isn't it possible to give the admin any hint about this wrong configuration? $logger = new VoidLogger(); } } else { + /// @todo isn't it possible to give the admin any hint about this wrong configuration? $logger = new VoidLogger(); } break; @@ -161,8 +165,6 @@ class LoggerFactory * @param FileSystem $fileSystem FileSystem utils * * @return LoggerInterface The PSR-3 compliant logger instance - * - * @throws InternalServerErrorException * @throws \Exception */ public static function createDev(IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem) @@ -172,9 +174,8 @@ class LoggerFactory $developerIp = $config->get('system', 'dlogip'); if ((!isset($developerIp) || !$debugging) && - (!is_file($stream) || is_writable($stream))) { - $logger = new VoidLogger(); - return $logger; + (!is_file($stream) || is_writable($stream))) { + return new VoidLogger(); } $loggerTimeZone = new \DateTimeZone('UTC'); @@ -228,7 +229,7 @@ class LoggerFactory * * @return string the PSR-3 compliant level */ - private static function mapLegacyConfigDebugLevel($level) + private static function mapLegacyConfigDebugLevel(string $level): string { switch ($level) { // legacy WARNING @@ -263,9 +264,9 @@ class LoggerFactory * * @return void * - * @throws \Exception in case of general failures + * @throws LoggerException */ - public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE) + public static function addStreamHandler(LoggerInterface $logger, $stream, string $level = LogLevel::NOTICE) { if ($logger instanceof Monolog\Logger) { $loglevel = Monolog\Logger::toMonologLevel($level); @@ -275,19 +276,16 @@ class LoggerFactory $loglevel = LogLevel::NOTICE; } - $fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel); + try { + $fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel); - $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n"); - $fileHandler->setFormatter($formatter); + $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n"); + $fileHandler->setFormatter($formatter); - $logger->pushHandler($fileHandler); - } - } - - public static function addVoidHandler($logger) - { - if ($logger instanceof Monolog\Logger) { - $logger->pushHandler(new Monolog\Handler\NullHandler()); + $logger->pushHandler($fileHandler); + } catch (\Exception $exception) { + throw new LoggerException('Cannot create Monolog Logger.', $exception); + } } } } diff --git a/src/Util/Logger/AbstractLogger.php b/src/Core/Logger/Type/AbstractLogger.php similarity index 77% rename from src/Util/Logger/AbstractLogger.php rename to src/Core/Logger/Type/AbstractLogger.php index a8aba34d34..0b6d9f38fd 100644 --- a/src/Util/Logger/AbstractLogger.php +++ b/src/Core/Logger/Type/AbstractLogger.php @@ -19,8 +19,9 @@ * */ -namespace Friendica\Util\Logger; +namespace Friendica\Core\Logger\Type; +use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Util\Introspection; use Friendica\Util\Strings; use Psr\Log\LoggerInterface; @@ -58,29 +59,35 @@ abstract class AbstractLogger implements LoggerInterface /** * Adds a new entry to the log * - * @param int $level + * @param mixed $level * @param string $message * @param array $context * * @return void */ - abstract protected function addEntry($level, $message, $context = []); + abstract protected function addEntry($level, string $message, array $context = []); /** * @param string $channel The output channel * @param Introspection $introspection The introspection of the current call * - * @throws \Exception + * @throws LoggerException */ - public function __construct($channel, Introspection $introspection) + public function __construct(string $channel, Introspection $introspection) { $this->channel = $channel; $this->introspection = $introspection; - $this->logUid = Strings::getRandomHex(6); + + try { + $this->logUid = Strings::getRandomHex(6); + } catch (\Exception $exception) { + throw new LoggerException('Cannot generate log Id', $exception); + } } /** * Simple interpolation of PSR-3 compliant replacements ( variables between '{' and '}' ) + * * @see https://www.php-fig.org/psr/psr-3/#12-message * * @param string $message @@ -88,7 +95,7 @@ abstract class AbstractLogger implements LoggerInterface * * @return string the interpolated message */ - protected function psrInterpolate($message, array $context = array()) + protected function psrInterpolate(string $message, array $context = []): string { $replace = []; foreach ($context as $key => $value) { @@ -104,7 +111,7 @@ abstract class AbstractLogger implements LoggerInterface } /** - * JSON Encodes an complete array including objects with "__toString()" methods + * JSON Encodes a complete array including objects with "__toString()" methods * * @param array $input an Input Array to encode * @@ -128,7 +135,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function emergency($message, array $context = array()) + public function emergency($message, array $context = []) { $this->addEntry(LogLevel::EMERGENCY, (string) $message, $context); } @@ -136,7 +143,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function alert($message, array $context = array()) + public function alert($message, array $context = []) { $this->addEntry(LogLevel::ALERT, (string) $message, $context); } @@ -144,7 +151,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function critical($message, array $context = array()) + public function critical($message, array $context = []) { $this->addEntry(LogLevel::CRITICAL, (string) $message, $context); } @@ -152,7 +159,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function error($message, array $context = array()) + public function error($message, array $context = []) { $this->addEntry(LogLevel::ERROR, (string) $message, $context); } @@ -160,7 +167,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function warning($message, array $context = array()) + public function warning($message, array $context = []) { $this->addEntry(LogLevel::WARNING, (string) $message, $context); } @@ -168,7 +175,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function notice($message, array $context = array()) + public function notice($message, array $context = []) { $this->addEntry(LogLevel::NOTICE, (string) $message, $context); } @@ -176,7 +183,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function info($message, array $context = array()) + public function info($message, array $context = []) { $this->addEntry(LogLevel::INFO, (string) $message, $context); } @@ -184,7 +191,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function debug($message, array $context = array()) + public function debug($message, array $context = []) { $this->addEntry(LogLevel::DEBUG, (string) $message, $context); } @@ -192,7 +199,7 @@ abstract class AbstractLogger implements LoggerInterface /** * {@inheritdoc} */ - public function log($level, $message, array $context = array()) + public function log($level, $message, array $context = []) { $this->addEntry($level, (string) $message, $context); } diff --git a/src/Util/Logger/Monolog/DevelopHandler.php b/src/Core/Logger/Type/Monolog/DevelopHandler.php similarity index 93% rename from src/Util/Logger/Monolog/DevelopHandler.php rename to src/Core/Logger/Type/Monolog/DevelopHandler.php index a55ac373ac..5d2a84401c 100644 --- a/src/Util/Logger/Monolog/DevelopHandler.php +++ b/src/Core/Logger/Type/Monolog/DevelopHandler.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Util\Logger\Monolog; +namespace Friendica\Core\Logger\Type\Monolog; use Monolog\Handler; use Monolog\Logger; @@ -42,7 +42,7 @@ class DevelopHandler extends Handler\AbstractHandler * @param int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ - public function __construct($developerIp, $level = Logger::DEBUG, $bubble = true) + public function __construct($developerIp, $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); @@ -52,15 +52,14 @@ class DevelopHandler extends Handler\AbstractHandler /** * {@inheritdoc} */ - public function handle(array $record) + public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; } /// Just in case the remote IP is the same as the developer IP log the output - if (!is_null($this->developerIp) && $_SERVER['REMOTE_ADDR'] != $this->developerIp) - { + if (!is_null($this->developerIp) && $_SERVER['REMOTE_ADDR'] != $this->developerIp) { return false; } diff --git a/src/Util/Logger/Monolog/IntrospectionProcessor.php b/src/Core/Logger/Type/Monolog/IntrospectionProcessor.php similarity index 92% rename from src/Util/Logger/Monolog/IntrospectionProcessor.php rename to src/Core/Logger/Type/Monolog/IntrospectionProcessor.php index ceb0e3123e..756331b22f 100644 --- a/src/Util/Logger/Monolog/IntrospectionProcessor.php +++ b/src/Core/Logger/Type/Monolog/IntrospectionProcessor.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Util\Logger\Monolog; +namespace Friendica\Core\Logger\Type\Monolog; use Friendica\Util\Introspection; use Monolog\Logger; @@ -41,11 +41,11 @@ class IntrospectionProcessor implements ProcessorInterface public function __construct(Introspection $introspection, $level = Logger::DEBUG) { $this->level = Logger::toMonologLevel($level); - $introspection->addClasses(array('Monolog\\')); + $introspection->addClasses(['Monolog\\']); $this->introspection = $introspection; } - public function __invoke(array $record) + public function __invoke(array $record): array { // return if the level is not high enough if ($record['level'] < $this->level) { diff --git a/src/Util/Logger/ProfilerLogger.php b/src/Core/Logger/Type/ProfilerLogger.php similarity index 82% rename from src/Util/Logger/ProfilerLogger.php rename to src/Core/Logger/Type/ProfilerLogger.php index 1c190d4f55..2333dd5403 100644 --- a/src/Util/Logger/ProfilerLogger.php +++ b/src/Core/Logger/Type/ProfilerLogger.php @@ -19,9 +19,8 @@ * */ -namespace Friendica\Util\Logger; +namespace Friendica\Core\Logger\Type; -use Friendica\Core\System; use Friendica\Util\Profiler; use Psr\Log\LoggerInterface; @@ -50,14 +49,14 @@ class ProfilerLogger implements LoggerInterface */ public function __construct(LoggerInterface $logger, Profiler $profiler) { - $this->logger = $logger; + $this->logger = $logger; $this->profiler = $profiler; } /** * {@inheritdoc} */ - public function emergency($message, array $context = array()) + public function emergency($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->emergency($message, $context); @@ -67,7 +66,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function alert($message, array $context = array()) + public function alert($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->alert($message, $context); @@ -77,7 +76,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function critical($message, array $context = array()) + public function critical($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->critical($message, $context); @@ -87,7 +86,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function error($message, array $context = array()) + public function error($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->error($message, $context); @@ -97,7 +96,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function warning($message, array $context = array()) + public function warning($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->warning($message, $context); @@ -107,7 +106,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function notice($message, array $context = array()) + public function notice($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->notice($message, $context); @@ -117,7 +116,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function info($message, array $context = array()) + public function info($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->info($message, $context); @@ -127,7 +126,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function debug($message, array $context = array()) + public function debug($message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->debug($message, $context); @@ -137,7 +136,7 @@ class ProfilerLogger implements LoggerInterface /** * {@inheritdoc} */ - public function log($level, $message, array $context = array()) + public function log($level, $message, array $context = []) { $this->profiler->startRecording('file'); $this->logger->log($level, $message, $context); diff --git a/src/Util/Logger/README.md b/src/Core/Logger/Type/README.md similarity index 100% rename from src/Util/Logger/README.md rename to src/Core/Logger/Type/README.md diff --git a/src/Util/Logger/StreamLogger.php b/src/Core/Logger/Type/StreamLogger.php similarity index 72% rename from src/Util/Logger/StreamLogger.php rename to src/Core/Logger/Type/StreamLogger.php index 752f486583..be0283d0ec 100644 --- a/src/Util/Logger/StreamLogger.php +++ b/src/Core/Logger/Type/StreamLogger.php @@ -19,8 +19,10 @@ * */ -namespace Friendica\Util\Logger; +namespace Friendica\Core\Logger\Type; +use Friendica\Core\Logger\Exception\LoggerArgumentException; +use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Util\DateTimeFormat; use Friendica\Util\FileSystem; use Friendica\Util\Introspection; @@ -80,9 +82,9 @@ class StreamLogger extends AbstractLogger * @param string|resource $stream The stream to write with this logger (either a file or a stream, i.e. stdout) * @param string $level The minimum loglevel at which this logger will be triggered * - * @throws \Exception + * @throws LoggerArgumentException */ - public function __construct($channel, $stream, Introspection $introspection, FileSystem $fileSystem, $level = LogLevel::DEBUG) + public function __construct($channel, $stream, Introspection $introspection, FileSystem $fileSystem, string $level = LogLevel::DEBUG) { $this->fileSystem = $fileSystem; @@ -93,14 +95,14 @@ class StreamLogger extends AbstractLogger } elseif (is_string($stream)) { $this->url = $stream; } else { - throw new \InvalidArgumentException('A stream must either be a resource or a string.'); + throw new LoggerArgumentException('A stream must either be a resource or a string.'); } $this->pid = getmypid(); if (array_key_exists($level, $this->levelToInt)) { $this->logLevel = $this->levelToInt[$level]; } else { - throw new \InvalidArgumentException(sprintf('The level "%s" is not valid.', $level)); + throw new LoggerArgumentException(sprintf('The level "%s" is not valid.', $level)); } $this->checkStream(); @@ -118,16 +120,19 @@ class StreamLogger extends AbstractLogger /** * Adds a new entry to the log * - * @param int $level + * @param mixed $level * @param string $message - * @param array $context + * @param array $context * * @return void + * + * @throws LoggerException + * @throws LoggerArgumentException */ - protected function addEntry($level, $message, $context = []) + protected function addEntry($level, string $message, array $context = []) { if (!array_key_exists($level, $this->levelToInt)) { - throw new \InvalidArgumentException(sprintf('The level "%s" is not valid.', $level)); + throw new LoggerArgumentException(sprintf('The level "%s" is not valid.', $level)); } $logLevel = $this->levelToInt[$level]; @@ -145,19 +150,24 @@ class StreamLogger extends AbstractLogger /** * Formats a log record for the syslog output * - * @param int $level The loglevel/priority + * @param mixed $level The loglevel/priority * @param string $message The message * @param array $context The context of this call * * @return string the formatted syslog output + * + * @throws LoggerException */ - private function formatLog($level, $message, $context = []) + private function formatLog($level, string $message, array $context = []): string { $record = $this->introspection->getRecord(); $record = array_merge($record, ['uid' => $this->logUid, 'process_id' => $this->pid]); - $logMessage = ''; - $logMessage .= DateTimeFormat::utcNow(DateTimeFormat::ATOM) . ' '; + try { + $logMessage = DateTimeFormat::utcNow(DateTimeFormat::ATOM) . ' '; + } catch (\Exception $exception) { + throw new LoggerException('Cannot get current datetime.', $exception); + } $logMessage .= $this->channel . ' '; $logMessage .= '[' . strtoupper($level) . ']: '; $logMessage .= $this->psrInterpolate($message, $context) . ' '; @@ -168,6 +178,12 @@ class StreamLogger extends AbstractLogger return $logMessage; } + /** + * Checks the current stream + * + * @throws LoggerException + * @throws LoggerArgumentException + */ private function checkStream() { if (is_resource($this->stream)) { @@ -175,9 +191,13 @@ class StreamLogger extends AbstractLogger } if (empty($this->url)) { - throw new \LogicException('Missing stream URL.'); + throw new LoggerArgumentException('Missing stream URL.'); } - $this->stream = $this->fileSystem->createStream($this->url); + try { + $this->stream = $this->fileSystem->createStream($this->url); + } catch (\UnexpectedValueException $exception) { + throw new LoggerException('Cannot create stream.', $exception); + } } } diff --git a/src/Util/Logger/SyslogLogger.php b/src/Core/Logger/Type/SyslogLogger.php similarity index 76% rename from src/Util/Logger/SyslogLogger.php rename to src/Core/Logger/Type/SyslogLogger.php index f33e2d624a..667b44ccc7 100644 --- a/src/Util/Logger/SyslogLogger.php +++ b/src/Core/Logger/Type/SyslogLogger.php @@ -19,10 +19,12 @@ * */ -namespace Friendica\Util\Logger; +namespace Friendica\Core\Logger\Type; -use Friendica\Network\HTTPException\InternalServerErrorException; +use Friendica\Core\Logger\Exception\LoggerArgumentException; +use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Util\Introspection; +use Psr\Log\InvalidArgumentException; use Psr\Log\LogLevel; /** @@ -97,27 +99,28 @@ class SyslogLogger extends AbstractLogger * @param int $logOpts Indicates what logging options will be used when generating a log message * @param int $logFacility Used to specify what type of program is logging the message * - * @throws \Exception + * @throws LoggerArgumentException */ - public function __construct($channel, Introspection $introspection, $level = LogLevel::NOTICE, $logOpts = LOG_PID, $logFacility = LOG_USER) + public function __construct($channel, Introspection $introspection, string $level = LogLevel::NOTICE, int $logOpts = LOG_PID, int $logFacility = LOG_USER) { parent::__construct($channel, $introspection); - $this->logOpts = $logOpts; + $this->logOpts = $logOpts; $this->logFacility = $logFacility; - $this->logLevel = $this->mapLevelToPriority($level); - $this->introspection->addClasses(array(self::class)); + $this->logLevel = $this->mapLevelToPriority($level); + $this->introspection->addClasses([self::class]); } /** * Adds a new entry to the syslog * - * @param int $level + * @param mixed $level * @param string $message * @param array $context * - * @throws InternalServerErrorException if the syslog isn't available + * @throws LoggerArgumentException in case the level isn't valid + * @throws LoggerException In case the syslog cannot be opened for writing */ - protected function addEntry($level, $message, $context = []) + protected function addEntry($level, string $message, array $context = []) { $logLevel = $this->mapLevelToPriority($level); @@ -136,12 +139,12 @@ class SyslogLogger extends AbstractLogger * * @return int The SysLog priority * - * @throws \Psr\Log\InvalidArgumentException If the loglevel isn't valid + * @throws LoggerArgumentException If the loglevel isn't valid */ - public function mapLevelToPriority($level) + public function mapLevelToPriority(string $level): int { if (!array_key_exists($level, $this->logLevels)) { - throw new \InvalidArgumentException(sprintf('The level "%s" is not valid.', $level)); + throw new LoggerArgumentException(sprintf('The level "%s" is not valid.', $level)); } return $this->logLevels[$level]; @@ -157,21 +160,22 @@ class SyslogLogger extends AbstractLogger /** * Writes a message to the syslog + * * @see http://php.net/manual/en/function.syslog.php#refsect1-function.syslog-parameters * * @param int $priority The Priority * @param string $message The message of the log * - * @throws InternalServerErrorException if syslog cannot be used + * @throws LoggerException In case the syslog cannot be opened/written */ - private function write($priority, $message) + private function write(int $priority, string $message) { set_error_handler([$this, 'customErrorHandler']); $opened = openlog(self::IDENT, $this->logOpts, $this->logFacility); restore_error_handler(); if (!$opened) { - throw new \UnexpectedValueException(sprintf('Can\'t open syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, $this->logFacility)); + throw new LoggerException(sprintf('Can\'t open syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, $this->logFacility)); } $this->syslogWrapper($priority, $message); @@ -186,13 +190,12 @@ class SyslogLogger extends AbstractLogger * * @return string the formatted syslog output */ - private function formatLog($level, $message, $context = []) + private function formatLog(int $level, string $message, array $context = []): string { $record = $this->introspection->getRecord(); $record = array_merge($record, ['uid' => $this->logUid]); - $logMessage = ''; - $logMessage .= $this->channel . ' '; + $logMessage = $this->channel . ' '; $logMessage .= '[' . $this->logToString[$level] . ']: '; $logMessage .= $this->psrInterpolate($message, $context) . ' '; $logMessage .= $this->jsonEncodeArray($context) . ' - '; @@ -211,15 +214,17 @@ class SyslogLogger extends AbstractLogger * * @param int $level The syslog priority * @param string $entry The message to send to the syslog function + * + * @throws LoggerException */ - protected function syslogWrapper($level, $entry) + protected function syslogWrapper(int $level, string $entry) { set_error_handler([$this, 'customErrorHandler']); $written = syslog($level, $entry); restore_error_handler(); if (!$written) { - throw new \UnexpectedValueException(sprintf('Can\'t write into syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, $this->logFacility)); + throw new LoggerException(sprintf('Can\'t write into syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, $this->logFacility)); } } } diff --git a/src/Util/Logger/VoidLogger.php b/src/Core/Logger/Type/VoidLogger.php similarity index 98% rename from src/Util/Logger/VoidLogger.php rename to src/Core/Logger/Type/VoidLogger.php index 6c47601a0a..5cd2cac868 100644 --- a/src/Util/Logger/VoidLogger.php +++ b/src/Core/Logger/Type/VoidLogger.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Util\Logger; +namespace Friendica\Core\Logger\Type; use Psr\Log\LoggerInterface; diff --git a/src/Util/Logger/WorkerLogger.php b/src/Core/Logger/Type/WorkerLogger.php similarity index 84% rename from src/Util/Logger/WorkerLogger.php rename to src/Core/Logger/Type/WorkerLogger.php index fdda6c9b53..fcbe128013 100644 --- a/src/Util/Logger/WorkerLogger.php +++ b/src/Core/Logger/Type/WorkerLogger.php @@ -19,13 +19,14 @@ * */ -namespace Friendica\Util\Logger; +namespace Friendica\Core\Logger\Type; +use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Util\Strings; use Psr\Log\LoggerInterface; /** - * A Logger for specific worker tasks, which adds an additional woker-id to it. + * A Logger for specific worker tasks, which adds a worker id to it. * Uses the decorator pattern (https://en.wikipedia.org/wiki/Decorator_pattern) */ class WorkerLogger implements LoggerInterface @@ -46,15 +47,21 @@ class WorkerLogger implements LoggerInterface private $functionName; /** - * @param LoggerInterface $logger The logger for worker entries - * @param string $functionName The current function name of the worker - * @param int $idLength The length of the generated worker ID + * @param LoggerInterface $logger The logger for worker entries + * @param string $functionName The current function name of the worker + * @param int $idLength The length of the generated worker ID + * + * @throws LoggerException */ - public function __construct(LoggerInterface $logger, $functionName = '', $idLength = 7) + public function __construct(LoggerInterface $logger, string $functionName = '', int $idLength = 7) { - $this->logger = $logger; + $this->logger = $logger; $this->functionName = $functionName; - $this->workerId = Strings::getRandomHex($idLength); + try { + $this->workerId = Strings::getRandomHex($idLength); + } catch (\Exception $exception) { + throw new LoggerException('Cannot generate random Hex.', $exception); + } } /** @@ -74,7 +81,7 @@ class WorkerLogger implements LoggerInterface */ private function addContext(array &$context) { - $context['worker_id'] = $this->workerId; + $context['worker_id'] = $this->workerId; $context['worker_cmd'] = $this->functionName; } @@ -83,7 +90,7 @@ class WorkerLogger implements LoggerInterface * * @return string */ - public function getWorkerId() + public function getWorkerId(): string { return $this->workerId; } diff --git a/src/DI.php b/src/DI.php index 5ba7e88db1..8ee7004408 100644 --- a/src/DI.php +++ b/src/DI.php @@ -243,7 +243,7 @@ abstract class DI */ public static function workerLogger() { - return self::$dice->create(Util\Logger\WorkerLogger::class); + return self::$dice->create(Core\Logger\Type\WorkerLogger::class); } // diff --git a/src/Util/FileSystem.php b/src/Util/FileSystem.php index 4fa5c31c8a..1a86f43be7 100644 --- a/src/Util/FileSystem.php +++ b/src/Util/FileSystem.php @@ -73,7 +73,9 @@ class FileSystem * * @param string $url The file/url * - * @return false|resource the open stream ressource + * @return resource the open stream rssource + * + * @throws \UnexpectedValueException */ public function createStream(string $url) { diff --git a/static/dependencies.config.php b/static/dependencies.config.php index bbf8c5599c..042949e60e 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -141,7 +141,7 @@ return [ * and is automatically passed as an argument with the same name */ LoggerInterface::class => [ - 'instanceOf' => Factory\LoggerFactory::class, + 'instanceOf' => \Friendica\Core\Logger\Factory\Logger::class, 'constructParams' => [ 'index', ], @@ -150,7 +150,7 @@ return [ ], ], '$devLogger' => [ - 'instanceOf' => Factory\LoggerFactory::class, + 'instanceOf' => \Friendica\Core\Logger\Factory\Logger::class, 'constructParams' => [ 'dev', ], diff --git a/tests/src/Console/AutomaticInstallationConsoleTest.php b/tests/src/Console/AutomaticInstallationConsoleTest.php index 760a732d67..3f4f8c03c9 100644 --- a/tests/src/Console/AutomaticInstallationConsoleTest.php +++ b/tests/src/Console/AutomaticInstallationConsoleTest.php @@ -32,7 +32,7 @@ use Friendica\Database\Database; use Friendica\DI; use Friendica\Test\Util\RendererMockTrait; use Friendica\Test\Util\VFSTrait; -use Friendica\Util\Logger\VoidLogger; +use Friendica\Core\Logger\Type\VoidLogger; use Mockery; use Mockery\MockInterface; use org\bovigo\vfs\vfsStream; diff --git a/tests/src/Contact/FriendSuggest/Factory/FriendSuggestTest.php b/tests/src/Contact/FriendSuggest/Factory/FriendSuggestTest.php index afa0711ae0..9691073168 100644 --- a/tests/src/Contact/FriendSuggest/Factory/FriendSuggestTest.php +++ b/tests/src/Contact/FriendSuggest/Factory/FriendSuggestTest.php @@ -5,7 +5,7 @@ namespace Friendica\Test\src\Contact\FriendSuggest\Factory; use Friendica\Contact\FriendSuggest\Factory\FriendSuggest; use Friendica\Contact\FriendSuggest\Entity; use Friendica\Test\MockedTest; -use Friendica\Util\Logger\VoidLogger; +use Friendica\Core\Logger\Type\VoidLogger; class FriendSuggestTest extends MockedTest { diff --git a/tests/src/Util/Logger/AbstractLoggerTest.php b/tests/src/Core/Logger/AbstractLoggerTest.php similarity index 99% rename from tests/src/Util/Logger/AbstractLoggerTest.php rename to tests/src/Core/Logger/AbstractLoggerTest.php index d008f4dc42..f1a0553102 100644 --- a/tests/src/Util/Logger/AbstractLoggerTest.php +++ b/tests/src/Core/Logger/AbstractLoggerTest.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; use Friendica\Test\MockedTest; use Friendica\Util\Introspection; diff --git a/tests/src/Util/Logger/LoggerDataTrait.php b/tests/src/Core/Logger/LoggerDataTrait.php similarity index 97% rename from tests/src/Util/Logger/LoggerDataTrait.php rename to tests/src/Core/Logger/LoggerDataTrait.php index 0bebe7d2cb..0d6b004cfe 100644 --- a/tests/src/Util/Logger/LoggerDataTrait.php +++ b/tests/src/Core/Logger/LoggerDataTrait.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; trait LoggerDataTrait { diff --git a/tests/src/Util/Logger/ProfilerLoggerTest.php b/tests/src/Core/Logger/ProfilerLoggerTest.php similarity index 96% rename from tests/src/Util/Logger/ProfilerLoggerTest.php rename to tests/src/Core/Logger/ProfilerLoggerTest.php index 7b62446142..3b8e7711f8 100644 --- a/tests/src/Util/Logger/ProfilerLoggerTest.php +++ b/tests/src/Core/Logger/ProfilerLoggerTest.php @@ -19,10 +19,10 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; use Friendica\Test\MockedTest; -use Friendica\Util\Logger\ProfilerLogger; +use Friendica\Core\Logger\Type\ProfilerLogger; use Friendica\Util\Profiler; use Mockery\MockInterface; use Psr\Log\LoggerInterface; diff --git a/tests/src/Util/Logger/StreamLoggerTest.php b/tests/src/Core/Logger/StreamLoggerTest.php similarity index 87% rename from tests/src/Util/Logger/StreamLoggerTest.php rename to tests/src/Core/Logger/StreamLoggerTest.php index 8599e08f45..65ef76ea3d 100644 --- a/tests/src/Util/Logger/StreamLoggerTest.php +++ b/tests/src/Core/Logger/StreamLoggerTest.php @@ -19,11 +19,13 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; +use Friendica\Core\Logger\Exception\LoggerArgumentException; +use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Util\FileSystem; use Friendica\Test\Util\VFSTrait; -use Friendica\Util\Logger\StreamLogger; +use Friendica\Core\Logger\Type\StreamLogger; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamFile; use Psr\Log\LogLevel; @@ -82,7 +84,7 @@ class StreamLoggerTest extends AbstractLoggerTest $filehandler = fopen($logfile->url(), 'ab'); - $logger = new StreamLogger('test', $filehandler, $this->introspection, $this->fileSystem); + $logger = new \Friendica\Core\Logger\Type\StreamLogger('test', $filehandler, $this->introspection, $this->fileSystem); $logger->emergency('working'); $text = $logfile->getContent(); @@ -114,7 +116,7 @@ class StreamLoggerTest extends AbstractLoggerTest */ public function testNoUrl() { - $this->expectException(\LogicException::class); + $this->expectException(LoggerArgumentException::class); $this->expectExceptionMessage("Missing stream URL."); $logger = new StreamLogger('test', '', $this->introspection, $this->fileSystem); @@ -127,8 +129,8 @@ class StreamLoggerTest extends AbstractLoggerTest */ public function testWrongUrl() { - $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessageMatches("/The stream or file .* could not be opened: .* /"); + $this->expectException(LoggerException::class); + $this->expectExceptionMessage("Cannot create stream."); $logfile = vfsStream::newFile('friendica.log') ->at($this->root)->chmod(0); @@ -158,7 +160,7 @@ class StreamLoggerTest extends AbstractLoggerTest */ public function testWrongMinimumLevel() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(LoggerArgumentException::class); $this->expectExceptionMessageMatches("/The level \".*\" is not valid./"); $logger = new StreamLogger('test', 'file.text', $this->introspection, $this->fileSystem, 'NOPE'); @@ -169,7 +171,7 @@ class StreamLoggerTest extends AbstractLoggerTest */ public function testWrongLogLevel() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(LoggerArgumentException::class); $this->expectExceptionMessageMatches("/The level \".*\" is not valid./"); $logfile = vfsStream::newFile('friendica.log') @@ -185,7 +187,7 @@ class StreamLoggerTest extends AbstractLoggerTest */ public function testWrongFile() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(LoggerArgumentException::class); $this->expectExceptionMessage("A stream must either be a resource or a string."); $logger = new StreamLogger('test', null, $this->introspection, $this->fileSystem); diff --git a/tests/src/Util/Logger/SyslogLoggerTest.php b/tests/src/Core/Logger/SyslogLoggerTest.php similarity index 72% rename from tests/src/Util/Logger/SyslogLoggerTest.php rename to tests/src/Core/Logger/SyslogLoggerTest.php index e93e43dd5c..8ba2ebc084 100644 --- a/tests/src/Util/Logger/SyslogLoggerTest.php +++ b/tests/src/Core/Logger/SyslogLoggerTest.php @@ -19,9 +19,11 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; -use Friendica\Util\Logger\SyslogLogger; +use Friendica\Core\Logger\Exception\LoggerArgumentException; +use Friendica\Core\Logger\Exception\LoggerException; +use Friendica\Core\Logger\Type\SyslogLogger; use Psr\Log\LogLevel; class SyslogLoggerTest extends AbstractLoggerTest @@ -62,7 +64,7 @@ class SyslogLoggerTest extends AbstractLoggerTest */ public function testWrongMinimumLevel() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(LoggerArgumentException::class); $this->expectExceptionMessageMatches("/The level \".*\" is not valid./"); $logger = new SyslogLoggerWrapper('test', $this->introspection, 'NOPE'); @@ -73,7 +75,7 @@ class SyslogLoggerTest extends AbstractLoggerTest */ public function testWrongLogLevel() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(LoggerArgumentException::class); $this->expectExceptionMessageMatches("/The level \".*\" is not valid./"); $logger = new SyslogLoggerWrapper('test', $this->introspection); @@ -81,23 +83,6 @@ class SyslogLoggerTest extends AbstractLoggerTest $logger->log('NOPE', 'a test'); } - /** - * Test when the logfacility is wrong (string) - */ - public function testServerException() - { - if (PHP_MAJOR_VERSION < 8) { - $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessageMatches("/Can\'t open syslog for ident \".*\" and facility \".*\": .* /"); - } else { - $this->expectException(\TypeError::class); - $this->expectExceptionMessage("openlog(): Argument #3 (\$facility) must be of type int, string given"); - } - - $logger = new SyslogLoggerWrapper('test', $this->introspection, LogLevel::DEBUG, null, 'a string'); - $logger->emergency('not working'); - } - /** * Test the close() method * @doesNotPerformAssertions diff --git a/tests/src/Util/Logger/SyslogLoggerWrapper.php b/tests/src/Core/Logger/SyslogLoggerWrapper.php similarity index 91% rename from tests/src/Util/Logger/SyslogLoggerWrapper.php rename to tests/src/Core/Logger/SyslogLoggerWrapper.php index 710899cc2b..05dcbd6bc5 100644 --- a/tests/src/Util/Logger/SyslogLoggerWrapper.php +++ b/tests/src/Core/Logger/SyslogLoggerWrapper.php @@ -19,10 +19,10 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; +use Friendica\Core\Logger\Type\SyslogLogger; use Friendica\Util\Introspection; -use Friendica\Util\Logger\SyslogLogger; use Psr\Log\LogLevel; /** @@ -53,7 +53,7 @@ class SyslogLoggerWrapper extends SyslogLogger * {@inheritdoc} * @noinspection PhpMissingParentCallCommonInspection */ - protected function syslogWrapper($level, $entry) + protected function syslogWrapper(int $level, string $entry) { $this->content .= $entry . PHP_EOL; } diff --git a/tests/src/Util/Logger/VoidLoggerTest.php b/tests/src/Core/Logger/VoidLoggerTest.php similarity index 94% rename from tests/src/Util/Logger/VoidLoggerTest.php rename to tests/src/Core/Logger/VoidLoggerTest.php index 75b2d1a8b8..a2134ce711 100644 --- a/tests/src/Util/Logger/VoidLoggerTest.php +++ b/tests/src/Core/Logger/VoidLoggerTest.php @@ -19,10 +19,10 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; use Friendica\Test\MockedTest; -use Friendica\Util\Logger\VoidLogger; +use Friendica\Core\Logger\Type\VoidLogger; use Psr\Log\LogLevel; class VoidLoggerTest extends MockedTest diff --git a/tests/src/Util/Logger/WorkerLoggerTest.php b/tests/src/Core/Logger/WorkerLoggerTest.php similarity index 97% rename from tests/src/Util/Logger/WorkerLoggerTest.php rename to tests/src/Core/Logger/WorkerLoggerTest.php index 06fae3c381..0f751f2e4d 100644 --- a/tests/src/Util/Logger/WorkerLoggerTest.php +++ b/tests/src/Core/Logger/WorkerLoggerTest.php @@ -19,10 +19,10 @@ * */ -namespace Friendica\Test\src\Util\Logger; +namespace Friendica\Test\src\Core\Logger; +use Friendica\Core\Logger\Type\WorkerLogger; use Friendica\Test\MockedTest; -use Friendica\Util\Logger\WorkerLogger; use Psr\Log\LoggerInterface; class WorkerLoggerTest extends MockedTest diff --git a/tests/src/Profile/ProfileField/Entity/ProfileFieldTest.php b/tests/src/Profile/ProfileField/Entity/ProfileFieldTest.php index 275a1d5972..6e054428d8 100644 --- a/tests/src/Profile/ProfileField/Entity/ProfileFieldTest.php +++ b/tests/src/Profile/ProfileField/Entity/ProfileFieldTest.php @@ -11,7 +11,7 @@ use Friendica\Security\PermissionSet\Factory\PermissionSet as PermissionSetFacto use Friendica\Test\MockedTest; use Friendica\Util\ACLFormatter; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Logger\VoidLogger; +use Friendica\Core\Logger\Type\VoidLogger; use Mockery\MockInterface; class ProfileFieldTest extends MockedTest diff --git a/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php b/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php index 0a093db5a1..e27445d32b 100644 --- a/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php +++ b/tests/src/Security/TwoFactor/Factory/TrustedBrowserTest.php @@ -5,7 +5,7 @@ namespace Friendica\Test\src\Security\TwoFactor\Factory; use Friendica\Security\TwoFactor\Factory\TrustedBrowser; use Friendica\Test\MockedTest; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Logger\VoidLogger; +use Friendica\Core\Logger\Type\VoidLogger; use Friendica\Util\Strings; class TrustedBrowserTest extends MockedTest