1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-10-24 10:06:08 +02:00

Convert level/levelName to enums (#1656)

This commit is contained in:
Jordi Boggiano
2022-04-19 21:49:03 +02:00
committed by GitHub
parent 248673e858
commit 2d006a8472
138 changed files with 1297 additions and 1216 deletions

View File

@@ -27,14 +27,13 @@ use Stringable;
* and uses them to store records that are added to it.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*
* @phpstan-type Level Logger::DEBUG|Logger::INFO|Logger::NOTICE|Logger::WARNING|Logger::ERROR|Logger::CRITICAL|Logger::ALERT|Logger::EMERGENCY
* @phpstan-type LevelName 'DEBUG'|'INFO'|'NOTICE'|'WARNING'|'ERROR'|'CRITICAL'|'ALERT'|'EMERGENCY'
*/
class Logger implements LoggerInterface, ResettableInterface
{
/**
* Detailed debug information
*
* @deprecated Use \Monolog\Level::Debug
*/
public const DEBUG = 100;
@@ -42,11 +41,15 @@ class Logger implements LoggerInterface, ResettableInterface
* Interesting events
*
* Examples: User logs in, SQL logs.
*
* @deprecated Use \Monolog\Level::Info
*/
public const INFO = 200;
/**
* Uncommon events
*
* @deprecated Use \Monolog\Level::Notice
*/
public const NOTICE = 250;
@@ -55,11 +58,15 @@ class Logger implements LoggerInterface, ResettableInterface
*
* Examples: Use of deprecated APIs, poor use of an API,
* undesirable things that are not necessarily wrong.
*
* @deprecated Use \Monolog\Level::Warning
*/
public const WARNING = 300;
/**
* Runtime errors
*
* @deprecated Use \Monolog\Level::Error
*/
public const ERROR = 400;
@@ -67,6 +74,8 @@ class Logger implements LoggerInterface, ResettableInterface
* Critical conditions
*
* Example: Application component unavailable, unexpected exception.
*
* @deprecated Use \Monolog\Level::Critical
*/
public const CRITICAL = 500;
@@ -75,11 +84,15 @@ class Logger implements LoggerInterface, ResettableInterface
*
* Example: Entire website down, database unavailable, etc.
* This should trigger the SMS alerts and wake you up.
*
* @deprecated Use \Monolog\Level::Alert
*/
public const ALERT = 550;
/**
* Urgent alert.
*
* @deprecated Use \Monolog\Level::Emergency
*/
public const EMERGENCY = 600;
@@ -91,25 +104,7 @@ class Logger implements LoggerInterface, ResettableInterface
*
* @var int
*/
public const API = 2;
/**
* This is a static variable and not a constant to serve as an extension point for custom levels
*
* @var array<int, string> $levels Logging levels with the levels as key
*
* @phpstan-var array<Level, LevelName> $levels Logging levels with the levels as key
*/
protected static $levels = [
self::DEBUG => 'DEBUG',
self::INFO => 'INFO',
self::NOTICE => 'NOTICE',
self::WARNING => 'WARNING',
self::ERROR => 'ERROR',
self::CRITICAL => 'CRITICAL',
self::ALERT => 'ALERT',
self::EMERGENCY => 'EMERGENCY',
];
public const API = 3;
/**
* @var string
@@ -287,16 +282,16 @@ class Logger implements LoggerInterface, ResettableInterface
* @param mixed[] $context The log context
* @return bool Whether the record has been processed
*
* @phpstan-param Level $level
* @phpstan-param value-of<Level::VALUES>|Level $level
*/
public function addRecord(int $level, string $message, array $context = []): bool
public function addRecord(int|Level $level, string $message, array $context = []): bool
{
$recordInitialized = count($this->processors) === 0;
$record = new LogRecord(
message: $message,
context: $context,
level: $level,
level: self::toMonologLevel($level),
channel: $this->name,
datetime: new DateTimeImmutable($this->microsecondTimestamps, $this->timezone),
extra: [],
@@ -380,79 +375,64 @@ class Logger implements LoggerInterface, ResettableInterface
}
}
/**
* Gets all supported logging levels.
*
* @return array<string, int> Assoc array with human-readable level names => level codes.
* @phpstan-return array<LevelName, Level>
*/
public static function getLevels(): array
{
return array_flip(static::$levels);
}
/**
* Gets the name of the logging level.
*
* @throws \Psr\Log\InvalidArgumentException If level is not defined
*
* @phpstan-param Level $level
* @phpstan-return LevelName
*/
public static function getLevelName(int $level): string
{
if (!isset(static::$levels[$level])) {
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
}
return static::$levels[$level];
}
/**
* Converts PSR-3 levels to Monolog ones if necessary
*
* @param string|int $level Level number (monolog) or name (PSR-3)
* @param int|string|Level|LevelName|LogLevel::* $level Level number (monolog) or name (PSR-3)
* @throws \Psr\Log\InvalidArgumentException If level is not defined
*
* @phpstan-param Level|LevelName|LogLevel::* $level
* @phpstan-return Level
* @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
*/
public static function toMonologLevel($level): int
public static function toMonologLevel(string|int|Level|LevelName $level): Level
{
if (is_string($level)) {
if (is_numeric($level)) {
return intval($level);
if ($level instanceof Level) {
return $level;
}
if ($level instanceof LevelName) {
return $level->toLevel();
}
if (\is_string($level)) {
if (\is_numeric($level)) {
$levelEnum = Level::tryFrom((int) $level);
if ($levelEnum === null) {
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', LevelName::VALUES + Level::VALUES));
}
return $levelEnum;
}
// Contains chars of all log levels and avoids using strtoupper() which may have
// Contains first char of all log levels and avoids using strtoupper() which may have
// strange results depending on locale (for example, "i" will become "İ" in Turkish locale)
$upper = strtr($level, 'abcdefgilmnortuwy', 'ABCDEFGILMNORTUWY');
if (defined(__CLASS__.'::'.$upper)) {
return constant(__CLASS__ . '::' . $upper);
$upper = strtr(substr($level, 0, 1), 'dinweca', 'DINWECA') . strtolower(substr($level, 1));
if (defined(Level::class.'::'.$upper)) {
return constant(Level::class . '::' . $upper);
}
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', LevelName::VALUES + Level::VALUES));
}
if (!is_int($level)) {
throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
$levelEnum = Level::tryFrom($level);
if ($levelEnum === null) {
throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', LevelName::VALUES + Level::VALUES));
}
return $level;
return $levelEnum;
}
/**
* Checks whether the Logger has a handler that listens on the given level
*
* @phpstan-param Level $level
* @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
*/
public function isHandling(int $level): bool
public function isHandling(int|string|LevelName|Level $level): bool
{
$record = new LogRecord(
datetime: new DateTimeImmutable($this->microsecondTimestamps, $this->timezone),
channel: $this->name,
message: '',
level: $level,
level: self::toMonologLevel($level),
);
foreach ($this->handlers as $handler) {
@@ -494,8 +474,8 @@ class Logger implements LoggerInterface, ResettableInterface
*/
public function log($level, string|\Stringable $message, array $context = []): void
{
if (!is_int($level) && !is_string($level)) {
throw new \InvalidArgumentException('$level is expected to be a string or int');
if (!is_string($level) && !is_int($level) && !$level instanceof Level) {
throw new \InvalidArgumentException('$level is expected to be a string, int or '.Level::class.' instance');
}
$level = static::toMonologLevel($level);