|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @var int[] Seconds and nanoseconds at start of logging period.
|
|
|
|
*/
|
|
|
|
$hrtime_start = hrtime();
|
|
|
|
|
|
|
|
/** @var int Constant giving number of nanoseconds in a second. */
|
|
|
|
$NANOSEC = 1E9;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Comparable enum describing the verbosity of logged messages.
|
|
|
|
*/
|
|
|
|
final class LoggingVerbosity {
|
|
|
|
// Make class functionally static.
|
|
|
|
private function __construct() {}
|
|
|
|
|
|
|
|
const Error = 10;
|
|
|
|
const Warning = 20;
|
|
|
|
const Info = 30;
|
|
|
|
const Debug = 40;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the proper letter to mark the given message verbosity.
|
|
|
|
* @param int $verbosity Numeric LoggingVerbosity value.
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
static function getVerbosityMarker(int $verbosity) {
|
|
|
|
return match($verbosity) {
|
|
|
|
LoggingVerbosity::Error => 'e',
|
|
|
|
LoggingVerbosity::Warning => 'w',
|
|
|
|
LoggingVerbosity::Info => 'i',
|
|
|
|
LoggingVerbosity::Debug => 'd'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const COLOR_RESET = "\033[0m";
|
|
|
|
|
|
|
|
static function getVerbosityColorMarker(int $verbosity) {
|
|
|
|
// See https://en.wikipedia.org/wiki/ANSI_escape_code#Colors for reference.
|
|
|
|
return match($verbosity) {
|
|
|
|
LoggingVerbosity::Error => "\033[31m",
|
|
|
|
LoggingVerbosity::Warning => "\033[93m",
|
|
|
|
LoggingVerbosity::Debug => "\033[90m",
|
|
|
|
default => ''
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate process runtime as [s, ns].
|
|
|
|
* @return int[] Seconds and nanoseconds.
|
|
|
|
*/
|
|
|
|
function hrtime_interval() {
|
|
|
|
global $hrtime_start, $NANOSEC;
|
|
|
|
list($s, $ns) = hrtime();
|
|
|
|
list($s0, $ns0) = $hrtime_start;
|
|
|
|
// Borrow
|
|
|
|
if ($ns < $ns0) { $s--; $ns += $NANOSEC; }
|
|
|
|
return [$s - $s0, $ns - $ns0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Format process runtime to milisecond precision.
|
|
|
|
*/
|
|
|
|
function runtime_str() {
|
|
|
|
list($s, $ns) = hrtime_interval();
|
|
|
|
return (
|
|
|
|
date('i:s.', $s) .
|
|
|
|
str_pad(intdiv($ns, 1E6), 3, "0", STR_PAD_LEFT)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function _log_message(string $msg, int $message_verbosity) {
|
|
|
|
global $LOGGING_VERBOSITY;
|
|
|
|
if ($message_verbosity > $LOGGING_VERBOSITY) return;
|
|
|
|
$runtime = runtime_str();
|
|
|
|
$marker = LoggingVerbosity::getVerbosityMarker($message_verbosity);
|
|
|
|
$color_marker = LoggingVerbosity::getVerbosityColorMarker($message_verbosity);
|
|
|
|
$color_reset = LoggingVerbosity::COLOR_RESET;
|
|
|
|
// Need to concatenate marker to avoid interpolated array member syntax.
|
|
|
|
fwrite(STDERR, $color_marker . "[$runtime] [$marker] $msg$color_reset" . PHP_EOL);
|
|
|
|
}
|
|
|
|
|
|
|
|
function log_error(string $msg) {
|
|
|
|
_log_message($msg, LoggingVerbosity::Error);
|
|
|
|
}
|
|
|
|
|
|
|
|
function log_warning(string $msg) {
|
|
|
|
_log_message($msg, LoggingVerbosity::Warning);
|
|
|
|
}
|
|
|
|
|
|
|
|
function log_info(string $msg) {
|
|
|
|
_log_message($msg, LoggingVerbosity::Info);
|
|
|
|
}
|
|
|
|
|
|
|
|
function log_debug(string $msg) {
|
|
|
|
_log_message($msg, LoggingVerbosity::Debug);
|
|
|
|
}
|
|
|
|
|
|
|
|
function log_value(mixed $value) {
|
|
|
|
log_debug(var_export($value, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
$LOGGING_VERBOSITY = LoggingVerbosity::Info;
|
|
|
|
?>
|