diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 19bf88f..c5f6b62 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,4 +9,4 @@ updates: directory: "/" schedule: # Check for updates to GitHub Actions every weekday - interval: "daily" + interval: "weekly" diff --git a/.gitignore b/.gitignore index f365511..78c231e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ #disable temporary and log files and dirs *.log +/.phpunit.result.cache #disable composer-managed libraries /vendor/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 93372e8..b98e1fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### `Security` in case of vulnerabilities +## [2.0.1] - 2024-08-10 +### Added +- PHPUnit test for class LoggerTime + ## [2.0] - 2024-07-27 Stable version for `"php": "^7.1 || ^8.0"`. (As of PHP 7.1.0 visibility modifiers are allowed for class constants.) @@ -33,7 +37,8 @@ Stable version for `"php": "^5.3 || ^7.0"` ## [0.1] - 2024-07-12 - A [PSR-3](https://www.php-fig.org/psr/psr-3/) compliant logger with adjustable verbosity (based on Backyard\BackyardError) -[Unreleased]: https://github.com/WorkOfStan/seablast-logger/compare/v2.0...HEAD +[Unreleased]: https://github.com/WorkOfStan/seablast-logger/compare/v2.0.1...HEAD +[2.0.1]: https://github.com/WorkOfStan/seablast-logger/compare/v2.0...v2.0.1 [2.0]: https://github.com/WorkOfStan/seablast-logger/compare/v1.0...v2.0 [1.0]: https://github.com/WorkOfStan/seablast-logger/compare/v0.2...v1.0 [0.2]: https://github.com/WorkOfStan/seablast-logger/compare/v0.1...v0.2 diff --git a/Test/LoggerTimeTest.php b/Test/LoggerTimeTest.php new file mode 100644 index 0000000..4cb9cd7 --- /dev/null +++ b/Test/LoggerTimeTest.php @@ -0,0 +1,88 @@ +object = new LoggerTime(); + } + + /** + * Tears down the fixture, for example, closes a network connection. + * This method is called after a test is executed. + * + * @return void + */ + protected function tearDown(): void + { + // no action + } + + /** + * @covers Seablast\Logger\LoggerTime::getmicrotime + * + * @return void + */ + public function testGetmicrotime(): void + { + $this->assertTrue(is_float($this->object->getmicrotime())); + } + + /** + * @covers Seablast\Logger\LoggerTime::getRunningTime + * + * @return void + */ + public function testGetRunningTime(): void + { + $expected = '0.0'; + + //$this->assertEquals($expected, substr((string) $this->object->getRunningTime(), 0, 3)); + $this->assertEquals((float) $expected, (float) substr((string) $this->object->getRunningTime(), 0, 3)); + } + + /** + * @covers Seablast\Logger\LoggerTime::pageGeneratedIn + * + * @return void + */ + public function testPageGeneratedInDefault(): void + { + $expected = '0.0'; + + //$this->assertEquals($expected, substr($this->object->pageGeneratedIn(), 0, 3)); + $this->assertEquals((float) $expected, (float) substr((string) $this->object->pageGeneratedIn(), 0, 3)); + } + + /** + * @return void + */ + public function testPageGeneratedInLangString(): void + { + $langStringPageGeneratedIn = "Page Generated in %s"; + $expected = 'Page Generated in 0'; + + $this->assertEquals( + $expected, + substr($this->object->pageGeneratedIn($langStringPageGeneratedIn), 0, strlen($expected)) + ); + } +} diff --git a/composer.json b/composer.json index 24eeb3a..6a011f4 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,9 @@ "psr/log": "^1.0 || ^2.0 || ^3.0", "tracy/tracy": "^2.6.0" }, + "require-dev": { + "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10 || ^11" + }, "license": "MIT", "authors": [ { @@ -28,5 +31,10 @@ "psr-4": { "Seablast\\Logger\\": ["src/"] } + }, + "autoload-dev": { + "psr-4": { + "Seablast\\Logger\\Test\\": ["Test/"] + } } } diff --git a/conf/phpunit-github.xml b/conf/phpunit-github.xml new file mode 100644 index 0000000..80d653f --- /dev/null +++ b/conf/phpunit-github.xml @@ -0,0 +1,14 @@ + + + + + ./../Test/ + + + \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..317a24c --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,14 @@ + + + + + ./Test/ + + + diff --git a/src/ErrorLogFailureException.php b/src/ErrorLogFailureException.php index 46fcb2e..784788e 100644 --- a/src/ErrorLogFailureException.php +++ b/src/ErrorLogFailureException.php @@ -1,5 +1,7 @@ int,string,bool,array */ - protected $conf = array(); + protected $conf = []; /** @var int */ private $overrideLoggingLevel; /** @var float */ @@ -34,15 +37,14 @@ class Logger extends AbstractLogger implements LoggerInterface private $user = 'unidentified'; /** - * * @param array $conf - * @param LoggerTime $time + * @param ?LoggerTime $time */ - public function __construct(array $conf = array(), LoggerTime $time = null) + public function __construct(array $conf = [], ?LoggerTime $time = null) { $this->time = ($time === null) ? (new LoggerTime()) : $time; $this->conf = array_merge( - array( // default values + [ // default values // 0 = send message to PHP's system logger; // recommended is however 3, i.e. append to the file destination set in the field 'logging_file' self::CONF_ERROR_LOG_MESSAGE_TYPE => 0, @@ -51,15 +53,15 @@ public function __construct(array $conf = array(), LoggerTime $time = null) // verbosity: log up to the level set here, default=5 = debug self::CONF_LOGGING_LEVEL => 5, // rename or renumber, if needed - self::CONF_LOGGING_LEVEL_NAME => array( + self::CONF_LOGGING_LEVEL_NAME => [ 0 => 'unknown', 1 => 'fatal', 'error', 'warning', 'info', 'debug', - 'speed' - ), + 'speed', + ], // the logging level to which the page generation speed (i.e. error_number 6) is to be logged self::CONF_LOGGING_LEVEL_PAGE_SPEED => 5, // false => use logging_file with log extension as destination @@ -70,7 +72,7 @@ public function __construct(array $conf = array(), LoggerTime $time = null) // A fatal error may be logged only. // However, in production, set up an email address to enable error notifications. self::CONF_MAIL_FOR_ADMIN_ENABLED => false, - ), + ], $conf ); if (!is_int($this->conf[self::CONF_LOGGING_LEVEL])) { @@ -86,6 +88,7 @@ public function __construct(array $conf = array(), LoggerTime $time = null) * It is however possible to programmatically raise the logging level set in configuration. * * @param int $newLevel + * * @return void */ public function logAtLeastToLevel(int $newLevel): void @@ -108,6 +111,7 @@ public function getLastRunningTime(): float * DI setter. * * @param int|string $user + * * @return void */ public function setUser($user): void @@ -120,9 +124,10 @@ public function setUser($user): void * * @param string $message * @param array $context + * * @return void */ - public function emergency($message, array $context = array()): void + public function emergency($message, array $context = []): void { $this->log(0, $message, $context); } @@ -135,9 +140,10 @@ public function emergency($message, array $context = array()): void * * @param string $message * @param array $context + * * @return void */ - public function alert($message, array $context = array()): void + public function alert($message, array $context = []): void { $this->log(1, $message, $context); } @@ -149,9 +155,10 @@ public function alert($message, array $context = array()): void * * @param string $message * @param array $context + * * @return void */ - public function critical($message, array $context = array()): void + public function critical($message, array $context = []): void { $this->log(1, $message, $context); } @@ -162,9 +169,10 @@ public function critical($message, array $context = array()): void * * @param string $message * @param array $context + * * @return void */ - public function error($message, array $context = array()): void + public function error($message, array $context = []): void { $this->log(2, $message, $context); } @@ -177,9 +185,10 @@ public function error($message, array $context = array()): void * * @param string $message * @param array $context + * * @return void */ - public function warning($message, array $context = array()): void + public function warning($message, array $context = []): void { $this->log(3, $message, $context); } @@ -189,9 +198,10 @@ public function warning($message, array $context = array()): void * * @param string $message * @param array $context + * * @return void */ - public function notice($message, array $context = array()): void + public function notice($message, array $context = []): void { $this->log(4, $message, $context); } @@ -203,9 +213,10 @@ public function notice($message, array $context = array()): void * * @param string $message * @param array $context + * * @return void */ - public function info($message, array $context = array()): void + public function info($message, array $context = []): void { $this->log(4, $message, $context); } @@ -215,9 +226,10 @@ public function info($message, array $context = array()): void * * @param string $message * @param array $context + * * @return void */ - public function debug($message, array $context = array()): void + public function debug($message, array $context = []): void { $this->log(5, $message, $context); } @@ -259,28 +271,27 @@ public function debug($message, array $context = array()): void * 23 Algorithm flow
* 24 Third party API
* 1001 Establish correct error_number - * */ - public function log($level, $message, array $context = array()): void + public function log($level, $message, array $context = []): void { //TODO add variable $line - it should always be called as basename(__FILE__)."#".__LINE__ , //so it's clear which line of the source code triggered the call if (!is_string($message)) { - $message = "wrong message type " . gettype($message) . ": Logger->log(" . print_r($level, true) . "," - . print_r($message, true) . ")"; + $message = 'wrong message type ' . gettype($message) . ': Logger->log(' . print_r($level, true) . ',' + . print_r($message, true) . ')'; $this->error($message); } // psr log levels to numbered severity - $psr2int = array( + $psr2int = [ LogLevel::EMERGENCY => 0, - LogLevel::ALERT => 1, - LogLevel::CRITICAL => 1, - LogLevel::ERROR => 2, - LogLevel::WARNING => 3, - LogLevel::NOTICE => 4, - LogLevel::INFO => 4, - LogLevel::DEBUG => 5, - ); + LogLevel::ALERT => 1, + LogLevel::CRITICAL => 1, + LogLevel::ERROR => 2, + LogLevel::WARNING => 3, + LogLevel::NOTICE => 4, + LogLevel::INFO => 4, + LogLevel::DEBUG => 5, + ]; if (is_string($level)) { if (array_key_exists($level, $psr2int)) { $level = $psr2int[$level]; @@ -294,7 +305,7 @@ public function log($level, $message, array $context = array()): void } // if context array is set then get the value of the 'error_number' field or the first element - $error_number = ($context === array()) + $error_number = ($context === []) ? 0 : (isset($context['error_number']) ? (int) $context['error_number'] : (int) reset($context)); @@ -304,10 +315,10 @@ public function log($level, $message, array $context = array()): void // log 0=unknown/default 1=fatal 2=error 3=warning 4=info 5=debug 6=speed according to $level ( $level <= max( - array( + [ $this->conf[self::CONF_LOGGING_LEVEL], $this->overrideLoggingLevel, - ) + ] ) ) // or log page_speed everytime error_number equals 6 and @@ -324,31 +335,31 @@ public function log($level, $message, array $context = array()): void - $RUNNING_TIME_PREVIOUS) > $this->conf[self::CONF_LOG_PROFILING_STEP] ) && $this->conf[self::CONF_LOG_PROFILING_STEP] ) { - $message = "SLOWSTEP " . $message; //110812, PROFILING + $message = 'SLOWSTEP ' . $message; //110812, PROFILING } - $message_prefix = "[" . date("d-M-Y H:i:s") . "] [" . $this->conf[self::CONF_LOGGING_LEVEL_NAME][$level] - . "] [" . $error_number . "] [" . $_SERVER['SCRIPT_FILENAME'] . "] [" - . $this->user . "@" + $message_prefix = '[' . date('d-M-Y H:i:s') . '] [' . $this->conf[self::CONF_LOGGING_LEVEL_NAME][$level] + . '] [' . $error_number . '] [' . $_SERVER['SCRIPT_FILENAME'] . '] [' + . $this->user . '@' // PHPUnit test (CLI) does not set REMOTE_ADDR // TODO what if gethostbyaddr can't resolve the IP? And wouldn't be faster to log IP? . (isset($_SERVER['REMOTE_ADDR']) ? gethostbyaddr($_SERVER['REMOTE_ADDR']) : '-') - . "] [" . $this->runningTime . "] [" + . '] [' . $this->runningTime . '] [' // PHPUnit test (CLI) does not set REQUEST_URI - . (isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : '-') - . "] "; + . (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '-') + . '] '; // $logging_file not set and it should be if (($this->conf[self::CONF_ERROR_LOG_MESSAGE_TYPE] == 3) && !$this->conf[self::CONF_LOGGING_FILE]) { // so write into the default destination - $result = error_log($message_prefix . "(error: logging_file should be set!) $message"); + $result = error_log("{$message_prefix}(error: logging_file should be set!) {$message}"); } else { - $messageType = ($this->conf[self::CONF_ERROR_LOG_MESSAGE_TYPE] == 0) + $messageType = ($this->conf[self::CONF_ERROR_LOG_MESSAGE_TYPE] === 0) ? $this->conf[self::CONF_ERROR_LOG_MESSAGE_TYPE] : 3; - $result = ($this->conf[self::CONF_LOG_MONTHLY_ROTATION]) + $result = $this->conf[self::CONF_LOG_MONTHLY_ROTATION] ? error_log( - $message_prefix . $message . (($messageType != 0) ? (PHP_EOL) : ('')), + $message_prefix . $message . (($messageType != 0) ? PHP_EOL : ''), $messageType, - "{$this->conf[self::CONF_LOGGING_FILE]}." . date("Y-m") . ".log" + "{$this->conf[self::CONF_LOGGING_FILE]}." . date('Y-m') . '.log' ) // writes into a monthly rotating file : error_log( $message_prefix . $message . PHP_EOL, @@ -357,7 +368,7 @@ public function log($level, $message, array $context = array()): void ); // writes into one file } // mailto admin. 'mail_for_admin_enabled' has to be an email - if ($level == 1 && $this->conf[self::CONF_MAIL_FOR_ADMIN_ENABLED]) { + if ($level === 1 && $this->conf[self::CONF_MAIL_FOR_ADMIN_ENABLED]) { error_log($message_prefix . $message . PHP_EOL, 1, $this->conf[self::CONF_MAIL_FOR_ADMIN_ENABLED]); } } diff --git a/src/LoggerTime.php b/src/LoggerTime.php index 23bd221..ad3a888 100644 --- a/src/LoggerTime.php +++ b/src/LoggerTime.php @@ -1,5 +1,7 @@ pageTimestamp)) { $this->pageTimestamp = $this->getmicrotime(); // initialisation, so that it can't return null @@ -45,7 +46,7 @@ public function getPageTimestamp() * * @return float */ - public function getRunningTime() + public function getRunningTime(): float { return round($this->getmicrotime() - $this->pageTimestamp, 4); } @@ -54,9 +55,10 @@ public function getRunningTime() * If called with 'Page Generated in %s seconds', it returns "Page Generated in x.xxxx seconds" * * @param string $langStringPageGeneratedIn instead of $backyardLangString['page_generated_in'] + * * @return string */ - public function pageGeneratedIn($langStringPageGeneratedIn = '%s') + public function pageGeneratedIn(string $langStringPageGeneratedIn = '%s'): string { return str_replace( '%s', diff --git a/test.php b/test.php index 61880cf..06143de 100644 --- a/test.php +++ b/test.php @@ -1,11 +1,13 @@ 3, Logger::CONF_LOGGING_FILE => './error_log', // extension .log will be added automatically Logger::CONF_LOGGING_LEVEL => 0, // start with logging almost nothing for purpose of test looping @@ -13,14 +15,14 @@ Logger::CONF_LOG_MONTHLY_ROTATION => true, Logger::CONF_LOG_PROFILING_STEP => 0.00048, Logger::CONF_MAIL_FOR_ADMIN_ENABLED => false, -); +]; $logger = new Logger($conf); -$severities = array('emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'); +$severities = ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug']; // Loop through levels 1 to 5 for ($level = 1; $level <= 5; $level++) { // Set the logging level - echo "

logAtLeastToLevel($level)

"; + echo "

logAtLeastToLevel({$level})

"; $logger->logAtLeastToLevel($level); foreach ($severities as $severity) {