From 97171d616000bdf0abedd5bb14d62fb4cfc0cfeb Mon Sep 17 00:00:00 2001 From: WorkOfStan Date: Sat, 27 Jul 2024 17:56:36 +0200 Subject: [PATCH] Stable version for PHP/5.3+ || PHP/7.x (#3) * Stable version for `"php": "^5.3 || ^7.0"` --- CHANGELOG.md | 6 +++- README.md | 2 ++ src/Logger.php | 80 +++++++++++++++++++++++++++++--------------------- 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5209fa4..4eb4708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### `Security` in case of vulnerabilities +## [1.0] - 2024-07-27 +Stable version for `"php": "^5.3 || ^7.0"` + ## [0.2] - 2024-07-23 ### Added - Class configuration is managed by an array where field names are defined as constants to enable IDE hints. @@ -27,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.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/v0.2...HEAD +[Unreleased]: https://github.com/WorkOfStan/seablast-logger/compare/v1.0...HEAD +[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 [0.1]: https://github.com/WorkOfStan/seablast-logger/releases/tag/v0.1 diff --git a/README.md b/README.md index 4a94f07..497b965 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ By default the logger logs the following levels of information: And ignores - speed +Note: Outputting log messages to the screen is not supported. + ## Runtime adjustment - method logAtLeastToLevel(int $level) may change the verbosity level above the level set when instatiating. - method setUser(int|string $user) may add the user identification to the error messages diff --git a/src/Logger.php b/src/Logger.php index af4bb11..d9d0e42 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -8,11 +8,7 @@ use Seablast\Logger\LoggerTime; /** - * TODO wrapper in backyard - * - add $RUNNING_TIME = $this->getLastRunningTime(); - * - KEEP dieGraciously - * - only log calls Seablast\Logger\Logger and catches ErrorLogFailureException('error_log() => return false - * TODO when adding PHP/8 support, add :void to the inherited methods and remove PHP/5 support + * A [PSR-3](http://www.php-fig.org/psr/psr-3/) compliant logger with adjustable verbosity. */ class Logger extends AbstractLogger implements LoggerInterface { @@ -74,10 +70,8 @@ public function __construct(array $conf = array(), LoggerTime $time = null) self::CONF_LOG_MONTHLY_ROTATION => true, // prefix message that took longer than profiling step (float) sec from the previous one by SLOWSTEP self::CONF_LOG_PROFILING_STEP => false, - // UNCOMMENT only if needed //'log_standard_output' => false, - // //true, pokud má zároveň vypisovat na obrazovku; false, pokud má vypisovat jen do logu - // fatal error may just be written in log, - // on production, it is however recommended to set an e-mail, where to announce fatal errors + // 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 @@ -133,6 +127,7 @@ public function setUser($user) */ public function emergency($message, array $context = array()) { + //TODO when adding PHP/8 support, add :void to the inherited methods and remove PHP/5 support $this->log(0, $message, $context); } @@ -231,15 +226,19 @@ public function debug($message, array $context = array()) $this->log(5, $message, $context); } - // phpcs:disable Generic.Files.LineLength /** * Error_log() modified to log necessary debug information by application to its own log. * Logs with an arbitrary verbosity level, e.g. debug info on production may be omitted. * Compliant with PSR-3 http://www.php-fig.org/psr/psr-3/ * + * Following gets written to log: + * [Timestamp: d-M-Y H:i:s] [Logging level] [$error_number] [$_SERVER['SCRIPT_FILENAME']] + * [username@gethostbyaddr($_SERVER['REMOTE_ADDR'])] [sec since page start] $message + * * @param mixed $level int|string Error level * @param string $message Message to be logged - * @param array $context OPTIONAL To enable error log filtering 'error_number' field expected or the first element element expected containing number of error category + * @param array $context OPTIONAL To enable error log filtering 'error_number' field expected + * or the first element element expected containing number of error category * * @return void * @@ -268,11 +267,11 @@ public function debug($message, array $context = array()) */ public function log($level, $message, array $context = array()) { - //TODO: přidat proměnnou $line - mělo by být vždy voláno jako basename(__FILE__)."#".__LINE__ , takže bude jasné, ze které řádky source souboru to bylo voláno - // Ve výsledku do logu zapíše: - //[Timestamp: d-M-Y H:i:s] [Logging level] [$error_number] [$_SERVER['SCRIPT_FILENAME']] [username@gethostbyaddr($_SERVER['REMOTE_ADDR'])] [sec od startu stránky] $message + //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 @@ -317,33 +316,49 @@ public function log($level, $message, array $context = array()) ) // or log page_speed everytime error_number equals 6 and // logging_level_page_speed has at least the severity of logging_level - || (($error_number === 6) && ($this->conf[self::CONF_LOGGING_LEVEL_PAGE_SPEED] <= $this->conf[self::CONF_LOGGING_LEVEL])) + || ( + ($error_number === 6) + && ($this->conf[self::CONF_LOGGING_LEVEL_PAGE_SPEED] <= $this->conf[self::CONF_LOGGING_LEVEL]) + ) ) { $RUNNING_TIME_PREVIOUS = $this->runningTime; - if (((($this->runningTime = round($this->time->getmicrotime() - $this->time->getPageTimestamp(), 4)) - $RUNNING_TIME_PREVIOUS) > $this->conf[self::CONF_LOG_PROFILING_STEP]) && $this->conf[self::CONF_LOG_PROFILING_STEP]) { + if ( + ( + (($this->runningTime = round($this->time->getmicrotime() - $this->time->getPageTimestamp(), 4)) + - $RUNNING_TIME_PREVIOUS) > $this->conf[self::CONF_LOG_PROFILING_STEP] + ) && $this->conf[self::CONF_LOG_PROFILING_STEP] + ) { $message = "SLOWSTEP " . $message; //110812, PROFILING } - // UNCOMMENT only if needed, DELETE otherwise - //if ($this->conf['log_standard_output']) { - // echo((($level <= 2) ? "" : "") . "{$message} [{$this->runningTime}]" . (($level <= 2) ? "" : "") . "
" . PHP_EOL); //110811, if fatal or error then bold//111119, RUNNING_TIME - //} - - $message_prefix = "[" . date("d-M-Y H:i:s") . "] [" . $this->conf[self::CONF_LOGGING_LEVEL_NAME][$level] . "] [" . $error_number . "] [" . $_SERVER['SCRIPT_FILENAME'] . "] [" + $message_prefix = "[" . date("d-M-Y H:i:s") . "] [" . $this->conf[self::CONF_LOGGING_LEVEL_NAME][$level] + . "] [" . $error_number . "] [" . $_SERVER['SCRIPT_FILENAME'] . "] [" . $this->user . "@" - . (isset($_SERVER['REMOTE_ADDR']) ? gethostbyaddr($_SERVER['REMOTE_ADDR']) : '-')//PHPUnit test (CLI) does not set REMOTE_ADDR + // 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 . "] [" - . (isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : '-')//PHPUnit test (CLI) does not set REQUEST_URI + // PHPUnit test (CLI) does not set REQUEST_URI + . (isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : '-') . "] "; - //gethostbyaddr($_SERVER['REMOTE_ADDR'])// co udělá s IP, která nelze přeložit? nebylo by lepší logovat přímo IP? - if (($this->conf[self::CONF_ERROR_LOG_MESSAGE_TYPE] == 3) && !$this->conf[self::CONF_LOGGING_FILE]) {// $logging_file not set and it should be - $result = error_log($message_prefix . "(error: logging_file should be set!) $message"); // so write into the default destination - //zaroven by mohlo poslat mail nebo tak neco .. vypis na obrazovku je asi az krajni reseni + // $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"); } else { - $messageType = ($this->conf[self::CONF_ERROR_LOG_MESSAGE_TYPE] == 0) ? $this->conf[self::CONF_ERROR_LOG_MESSAGE_TYPE] : 3; + $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]) - ? error_log($message_prefix . $message . (($messageType != 0) ? (PHP_EOL) : ('')), $messageType, "{$this->conf[self::CONF_LOGGING_FILE]}." . date("Y-m") . ".log") //writes into a monthly rotating file - : error_log($message_prefix . $message . PHP_EOL, $messageType, "{$this->conf[self::CONF_LOGGING_FILE]}.log"); //writes into one file + ? error_log( + $message_prefix . $message . (($messageType != 0) ? (PHP_EOL) : ('')), + $messageType, + "{$this->conf[self::CONF_LOGGING_FILE]}." . date("Y-m") . ".log" + ) // writes into a monthly rotating file + : error_log( + $message_prefix . $message . PHP_EOL, + $messageType, + "{$this->conf[self::CONF_LOGGING_FILE]}.log" + ); // 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]) { @@ -354,7 +369,6 @@ public function log($level, $message, array $context = array()) throw new ErrorLogFailureException('error_log() failed'); } } - // phpcs:enable /** Alternative way: Logging levels Log level Description Set bit