Parcourir la source

Remove LevelName enum in favor of a Level::getName method, fixes #1667 (#1668)

Jordi Boggiano il y a 3 ans
Parent
commit
1dacc790b9
65 fichiers modifiés avec 219 ajouts et 279 suppressions
  1. 6 0
      CHANGELOG.md
  2. 1 1
      UPGRADE.md
  3. 1 2
      doc/04-extending.md
  4. 1 2
      doc/message-structure.md
  5. 2 2
      phpstan-baseline.neon
  6. 2 2
      src/Monolog/Formatter/FlowdockFormatter.php
  7. 2 2
      src/Monolog/Formatter/FluentdFormatter.php
  8. 1 1
      src/Monolog/Formatter/HtmlFormatter.php
  9. 6 7
      src/Monolog/Handler/AbstractHandler.php
  10. 1 2
      src/Monolog/Handler/AbstractSyslogHandler.php
  11. 2 3
      src/Monolog/Handler/AmqpHandler.php
  12. 1 2
      src/Monolog/Handler/BufferHandler.php
  13. 1 2
      src/Monolog/Handler/ChromePHPHandler.php
  14. 1 2
      src/Monolog/Handler/CouchDBHandler.php
  15. 1 2
      src/Monolog/Handler/CubeHandler.php
  16. 5 6
      src/Monolog/Handler/DeduplicationHandler.php
  17. 1 2
      src/Monolog/Handler/DoctrineCouchDBHandler.php
  18. 1 2
      src/Monolog/Handler/DynamoDbHandler.php
  19. 1 2
      src/Monolog/Handler/ElasticaHandler.php
  20. 1 2
      src/Monolog/Handler/ElasticsearchHandler.php
  21. 1 2
      src/Monolog/Handler/ErrorLogHandler.php
  22. 10 11
      src/Monolog/Handler/FilterHandler.php
  23. 5 6
      src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php
  24. 3 4
      src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php
  25. 5 6
      src/Monolog/Handler/FingersCrossedHandler.php
  26. 1 2
      src/Monolog/Handler/GelfHandler.php
  27. 1 2
      src/Monolog/Handler/IFTTTHandler.php
  28. 1 2
      src/Monolog/Handler/LogglyHandler.php
  29. 1 2
      src/Monolog/Handler/MandrillHandler.php
  30. 1 2
      src/Monolog/Handler/MongoDBHandler.php
  31. 1 2
      src/Monolog/Handler/NativeMailerHandler.php
  32. 1 2
      src/Monolog/Handler/NewRelicHandler.php
  33. 3 4
      src/Monolog/Handler/NullHandler.php
  34. 2 3
      src/Monolog/Handler/PHPConsoleHandler.php
  35. 1 2
      src/Monolog/Handler/ProcessHandler.php
  36. 3 4
      src/Monolog/Handler/PsrHandler.php
  37. 13 14
      src/Monolog/Handler/PushoverHandler.php
  38. 1 2
      src/Monolog/Handler/RedisHandler.php
  39. 1 2
      src/Monolog/Handler/RedisPubSubHandler.php
  40. 2 3
      src/Monolog/Handler/RollbarHandler.php
  41. 1 2
      src/Monolog/Handler/RotatingFileHandler.php
  42. 1 2
      src/Monolog/Handler/SendGridHandler.php
  43. 1 2
      src/Monolog/Handler/SqsHandler.php
  44. 1 2
      src/Monolog/Handler/StreamHandler.php
  45. 1 2
      src/Monolog/Handler/SymfonyMailerHandler.php
  46. 1 2
      src/Monolog/Handler/SyslogHandler.php
  47. 1 2
      src/Monolog/Handler/SyslogUdpHandler.php
  48. 3 4
      src/Monolog/Handler/TestHandler.php
  49. 2 3
      src/Monolog/Handler/ZendMonitorHandler.php
  50. 64 12
      src/Monolog/Level.php
  51. 0 57
      src/Monolog/LevelName.php
  52. 6 9
      src/Monolog/LogRecord.php
  53. 13 17
      src/Monolog/Logger.php
  54. 3 4
      src/Monolog/Processor/GitProcessor.php
  55. 3 4
      src/Monolog/Processor/IntrospectionProcessor.php
  56. 3 4
      src/Monolog/Processor/MercurialProcessor.php
  57. 3 3
      src/Monolog/SignalHandler.php
  58. 2 3
      src/Monolog/Test/TestCase.php
  59. 1 2
      tests/Monolog/Formatter/LogstashFormatterTest.php
  60. 1 2
      tests/Monolog/Formatter/MongoDBFormatterTest.php
  61. 3 4
      tests/Monolog/Formatter/NormalizerFormatterTest.php
  62. 4 6
      tests/Monolog/Handler/PsrHandlerTest.php
  63. 4 5
      tests/Monolog/Handler/Slack/SlackRecordTest.php
  64. 1 2
      tests/Monolog/Handler/SlackWebhookHandlerTest.php
  65. 1 1
      tests/Monolog/Handler/ZendMonitorHandlerTest.php

+ 6 - 0
CHANGELOG.md

@@ -1,3 +1,9 @@
+### 3.0.0-RC2
+
+BC Breaks from RC1
+
+- The `Monolog\LevelName` enum does not exist anymore, use `Monolog\Level->getName()` instead.
+
 ### 3.0.0-RC1 (2022-05-08)
 
 This is mostly a cleanup release offering stronger type guarantees for integrators with the

+ 1 - 1
UPGRADE.md

@@ -18,7 +18,7 @@ Overall / notable changes:
   The interfaces do not require a `LogRecord` return type even where it would be applicable, but if you only
   support Monolog 3 in integration code I would recommend you use `LogRecord` return types wherever fitting
   to ensure forward compatibility as it may be added in Monolog 4.
-- Log levels are now enums [`Monolog\Level`](src/Monolog/Level.php) and [`Monolog\LevelName`](src/Monolog/LevelName.php)
+- Log levels are now stored as an enum [`Monolog\Level`](src/Monolog/Level.php)
 - All properties have had types added, which may require you to do so as well if you extended
   a Monolog class and declared the same property.
 

+ 1 - 2
doc/04-extending.md

@@ -22,7 +22,6 @@ abstract class provided by Monolog to keep things DRY.
 <?php
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Monolog\Handler\AbstractProcessingHandler;
 
@@ -32,7 +31,7 @@ class PDOHandler extends AbstractProcessingHandler
     private PDO $pdo;
     private PDOStatement $statement;
 
-    public function __construct(PDO $pdo, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(PDO $pdo, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         $this->pdo = $pdo;
         parent::__construct($level, $bubble);

+ 1 - 2
doc/message-structure.md

@@ -9,7 +9,6 @@ property   | type                      | description
 -----------|---------------------------|-------------------------------------------------------------------------------
 message    | string                    | The log message. When the `PsrLogMessageProcessor` is used this string may contain placeholders that will be replaced by variables from the context, e.g., "User {username} logged in" with `['username' => 'John']` as context will be written as "User John logged in".
 level      | Monolog\Level case        | Severity of the log message. See log levels described in [01-usage.md](01-usage.md#log-levels).
-levelName  | Monolog\LevelName case    | String representation of log level.
 context    | array                     | Arbitrary data passed with the construction of the message. For example the username of the current user or their IP address.
 channel    | string                    | The channel this message was logged to. This is the name that was passed when the logger was created with `new Logger($channel)`.
 datetime   | Monolog\DateTimeImmutable | Date and time when the message was logged. Class extends `\DateTimeImmutable`.
@@ -22,4 +21,4 @@ and can be filled by processors. The reason processors write to `extra` and not
 All properties except `extra` are read-only.
 
 > Note: For BC reasons with Monolog 1 and 2 which used arrays, `LogRecord` implements `ArrayAccess` so you can access the above properties
-> using `$record['message']` for example, with the notable exception of `levelName` which must be referred to as `level_name` for BC.
+> using `$record['message']` for example, with the notable exception of `level->getName()` which must be referred to as `level_name` for BC.

+ 2 - 2
phpstan-baseline.neon

@@ -82,11 +82,11 @@ parameters:
 
 		-
 			message: "#^Variable property access on \\$this\\(Monolog\\\\LogRecord\\)\\.$#"
-			count: 5
+			count: 4
 			path: src/Monolog/LogRecord.php
 
 		-
-			message: "#^Parameter \\#1 \\$level \\('alert'\\|'critical'\\|'debug'\\|'emergency'\\|'error'\\|'info'\\|'notice'\\|'warning'\\|Monolog\\\\Level\\|Monolog\\\\LevelName\\) of method Monolog\\\\Logger\\:\\:log\\(\\) should be contravariant with parameter \\$level \\(mixed\\) of method Psr\\\\Log\\\\LoggerInterface\\:\\:log\\(\\)$#"
+			message: "#^Parameter \\#1 \\$level \\('alert'\\|'critical'\\|'debug'\\|'emergency'\\|'error'\\|'info'\\|'notice'\\|'warning'\\|Monolog\\\\Level\\) of method Monolog\\\\Logger\\:\\:log\\(\\) should be contravariant with parameter \\$level \\(mixed\\) of method Psr\\\\Log\\\\LoggerInterface\\:\\:log\\(\\)$#"
 			count: 1
 			path: src/Monolog/Logger.php
 

+ 2 - 2
src/Monolog/Formatter/FlowdockFormatter.php

@@ -39,7 +39,7 @@ class FlowdockFormatter implements FormatterInterface
     {
         $tags = [
             '#logs',
-            '#' . strtolower($record->levelName->value),
+            '#' . $record->level->toPsrLogLevel(),
             '#' . $record->channel,
         ];
 
@@ -50,7 +50,7 @@ class FlowdockFormatter implements FormatterInterface
         $subject = sprintf(
             'in %s: %s - %s',
             $this->source,
-            $record->levelName->value,
+            $record->level->getName(),
             $this->getShortMessage($record->message)
         );
 

+ 2 - 2
src/Monolog/Formatter/FluentdFormatter.php

@@ -60,7 +60,7 @@ class FluentdFormatter implements FormatterInterface
     {
         $tag = $record->channel;
         if ($this->levelTag) {
-            $tag .= '.' . strtolower($record->levelName->value);
+            $tag .= '.' . $record->level->toPsrLogLevel();
         }
 
         $message = [
@@ -71,7 +71,7 @@ class FluentdFormatter implements FormatterInterface
 
         if (!$this->levelTag) {
             $message['level'] = $record->level->value;
-            $message['level_name'] = $record->levelName->value;
+            $message['level_name'] = $record->level->getName();
         }
 
         return Utils::jsonEncode([$tag, $record->datetime->getTimestamp(), $message]);

+ 1 - 1
src/Monolog/Formatter/HtmlFormatter.php

@@ -85,7 +85,7 @@ class HtmlFormatter extends NormalizerFormatter
      */
     public function format(LogRecord $record): string
     {
-        $output = $this->addTitle($record->levelName->value, $record->level);
+        $output = $this->addTitle($record->level->getName(), $record->level);
         $output .= '<table cellspacing="1" width="100%" class="monolog-output">';
 
         $output .= $this->addRow('Message', $record->message);

+ 6 - 7
src/Monolog/Handler/AbstractHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Monolog\ResettableInterface;
 use Psr\Log\LogLevel;
@@ -29,12 +28,12 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
     protected bool $bubble = true;
 
     /**
-     * @param int|string|Level|LevelName|LogLevel::* $level  The minimum logging level at which this handler will be triggered
+     * @param int|string|Level|LogLevel::* $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
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function __construct(int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         $this->setLevel($level);
         $this->bubble = $bubble;
@@ -51,11 +50,11 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
     /**
      * Sets minimum logging level at which this handler will be triggered.
      *
-     * @param Level|LevelName|LogLevel::* $level Level or level name
+     * @param Level|LogLevel::* $level Level or level name
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function setLevel(int|string|Level|LevelName $level): self
+    public function setLevel(int|string|Level $level): self
     {
         $this->level = Logger::toMonologLevel($level);
 

+ 1 - 2
src/Monolog/Handler/AbstractSyslogHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Level;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\LineFormatter;
-use Monolog\LevelName;
 
 /**
  * Common syslog functionality
@@ -61,7 +60,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler
     /**
      * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant
      */
-    public function __construct(string|int $facility = \LOG_USER, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(string|int $facility = \LOG_USER, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
 

+ 2 - 3
src/Monolog/Handler/AmqpHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Level;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\JsonFormatter;
-use Monolog\LevelName;
 use PhpAmqpLib\Message\AMQPMessage;
 use PhpAmqpLib\Channel\AMQPChannel;
 use AMQPExchange;
@@ -30,7 +29,7 @@ class AmqpHandler extends AbstractProcessingHandler
      * @param AMQPExchange|AMQPChannel $exchange     AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use
      * @param string|null              $exchangeName Optional exchange name, for AMQPChannel (PhpAmqpLib) only
      */
-    public function __construct(AMQPExchange|AMQPChannel $exchange, ?string $exchangeName = null, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(AMQPExchange|AMQPChannel $exchange, ?string $exchangeName = null, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         if ($exchange instanceof AMQPChannel) {
             $this->exchangeName = (string) $exchangeName;
@@ -103,7 +102,7 @@ class AmqpHandler extends AbstractProcessingHandler
      */
     protected function getRoutingKey(LogRecord $record): string
     {
-        $routingKey = sprintf('%s.%s', $record->levelName->value, $record->channel);
+        $routingKey = sprintf('%s.%s', $record->level->name, $record->channel);
 
         return strtolower($routingKey);
     }

+ 1 - 2
src/Monolog/Handler/BufferHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\ResettableInterface;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\LogRecord;
@@ -47,7 +46,7 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
      * @param int              $bufferLimit     How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
      * @param bool             $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded
      */
-    public function __construct(HandlerInterface $handler, int $bufferLimit = 0, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, bool $flushOnOverflow = false)
+    public function __construct(HandlerInterface $handler, int $bufferLimit = 0, int|string|Level $level = Level::Debug, bool $bubble = true, bool $flushOnOverflow = false)
     {
         parent::__construct($level, $bubble);
         $this->handler = $handler;

+ 1 - 2
src/Monolog/Handler/ChromePHPHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Formatter\ChromePHPFormatter;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 use Monolog\DateTimeImmutable;
@@ -63,7 +62,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
 
     protected static bool $sendHeaders = true;
 
-    public function __construct(int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
         if (!function_exists('json_encode')) {

+ 1 - 2
src/Monolog/Handler/CouchDBHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\JsonFormatter;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -49,7 +48,7 @@ class CouchDBHandler extends AbstractProcessingHandler
      *
      * @phpstan-param InputOptions $options
      */
-    public function __construct(array $options = [], int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(array $options = [], int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         $this->options = array_merge([
             'host'     => 'localhost',

+ 1 - 2
src/Monolog/Handler/CubeHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -39,7 +38,7 @@ class CubeHandler extends AbstractProcessingHandler
      *                                   A valid url must consist of three parts : protocol://host:port
      *                                   Only valid protocols used by Cube are http and udp
      */
-    public function __construct(string $url, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(string $url, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         $urlInfo = parse_url($url);
 

+ 5 - 6
src/Monolog/Handler/DeduplicationHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Psr\Log\LogLevel;
 use Monolog\LogRecord;
@@ -50,13 +49,13 @@ class DeduplicationHandler extends BufferHandler
     /**
      * @param HandlerInterface                       $handler            Handler.
      * @param string                                 $deduplicationStore The file/path where the deduplication log should be kept
-     * @param int|string|Level|LevelName|LogLevel::* $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes
+     * @param int|string|Level|LogLevel::* $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes
      * @param int                                    $time               The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through
      * @param bool                                   $bubble             Whether the messages that are handled can bubble up the stack or not
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $deduplicationLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $deduplicationLevel
      */
-    public function __construct(HandlerInterface $handler, ?string $deduplicationStore = null, int|string|Level|LevelName $deduplicationLevel = Level::Error, int $time = 60, bool $bubble = true)
+    public function __construct(HandlerInterface $handler, ?string $deduplicationStore = null, int|string|Level $deduplicationLevel = Level::Error, int $time = 60, bool $bubble = true)
     {
         parent::__construct($handler, 0, Level::Debug, $bubble, false);
 
@@ -112,7 +111,7 @@ class DeduplicationHandler extends BufferHandler
         for ($i = count($store) - 1; $i >= 0; $i--) {
             list($timestamp, $level, $message) = explode(':', $store[$i], 3);
 
-            if ($level === $record->levelName->value && $message === $expectedMessage && $timestamp > $timestampValidity) {
+            if ($level === $record->level->getName() && $message === $expectedMessage && $timestamp > $timestampValidity) {
                 return true;
             }
 
@@ -162,6 +161,6 @@ class DeduplicationHandler extends BufferHandler
 
     private function appendRecord(LogRecord $record): void
     {
-        file_put_contents($this->deduplicationStore, $record->datetime->getTimestamp() . ':' . $record->levelName->value . ':' . preg_replace('{[\r\n].*}', '', $record->message) . "\n", FILE_APPEND);
+        file_put_contents($this->deduplicationStore, $record->datetime->getTimestamp() . ':' . $record->level->getName() . ':' . preg_replace('{[\r\n].*}', '', $record->message) . "\n", FILE_APPEND);
     }
 }

+ 1 - 2
src/Monolog/Handler/DoctrineCouchDBHandler.php

@@ -15,7 +15,6 @@ use Monolog\Level;
 use Monolog\Formatter\NormalizerFormatter;
 use Monolog\Formatter\FormatterInterface;
 use Doctrine\CouchDB\CouchDBClient;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -27,7 +26,7 @@ class DoctrineCouchDBHandler extends AbstractProcessingHandler
 {
     private CouchDBClient $client;
 
-    public function __construct(CouchDBClient $client, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(CouchDBClient $client, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         $this->client = $client;
         parent::__construct($level, $bubble);

+ 1 - 2
src/Monolog/Handler/DynamoDbHandler.php

@@ -17,7 +17,6 @@ use Monolog\Formatter\FormatterInterface;
 use Aws\DynamoDb\Marshaler;
 use Monolog\Formatter\ScalarFormatter;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -36,7 +35,7 @@ class DynamoDbHandler extends AbstractProcessingHandler
 
     protected Marshaler $marshaler;
 
-    public function __construct(DynamoDbClient $client, string $table, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(DynamoDbClient $client, string $table, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         $this->marshaler = new Marshaler;
 

+ 1 - 2
src/Monolog/Handler/ElasticaHandler.php

@@ -17,7 +17,6 @@ use Monolog\Formatter\ElasticaFormatter;
 use Monolog\Level;
 use Elastica\Client;
 use Elastica\Exception\ExceptionInterface;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -62,7 +61,7 @@ class ElasticaHandler extends AbstractProcessingHandler
      *
      * @phpstan-param InputOptions $options
      */
-    public function __construct(Client $client, array $options = [], int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(Client $client, array $options = [], int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
         $this->client = $client;

+ 1 - 2
src/Monolog/Handler/ElasticsearchHandler.php

@@ -11,7 +11,6 @@
 
 namespace Monolog\Handler;
 
-use Monolog\LevelName;
 use Elastic\Elasticsearch\Response\Elasticsearch;
 use Throwable;
 use RuntimeException;
@@ -77,7 +76,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
      *
      * @phpstan-param InputOptions $options
      */
-    public function __construct(Client|Client8 $client, array $options = [], int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(Client|Client8 $client, array $options = [], int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
         $this->client = $client;

+ 1 - 2
src/Monolog/Handler/ErrorLogHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Formatter\LineFormatter;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -35,7 +34,7 @@ class ErrorLogHandler extends AbstractProcessingHandler
      * @param int  $messageType    Says where the error should go.
      * @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries
      */
-    public function __construct(int $messageType = self::OPERATING_SYSTEM, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, bool $expandNewlines = false)
+    public function __construct(int $messageType = self::OPERATING_SYSTEM, int|string|Level $level = Level::Debug, bool $bubble = true, bool $expandNewlines = false)
     {
         parent::__construct($level, $bubble);
 

+ 10 - 11
src/Monolog/Handler/FilterHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use Closure;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Monolog\ResettableInterface;
 use Monolog\Formatter\FormatterInterface;
@@ -56,14 +55,14 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
      * @phpstan-param (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface $handler
      *
      * @param Closure|HandlerInterface                                                 $handler        Handler or factory Closure($record|null, $filterHandler).
-     * @param int|string|Level|LevelName|array<int|string|Level|LevelName|LogLevel::*> $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
-     * @param int|string|Level|LevelName|LogLevel::*                                   $maxLevel       Maximum level to accept, only used if $minLevelOrList is not an array
+     * @param int|string|Level|array<int|string|Level|LogLevel::*> $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
+     * @param int|string|Level|LogLevel::*                                   $maxLevel       Maximum level to accept, only used if $minLevelOrList is not an array
      * @param bool                                                                     $bubble         Whether the messages that are handled can bubble up the stack or not
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::*|array<value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::*> $minLevelOrList
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $maxLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::*|array<value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::*> $minLevelOrList
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $maxLevel
      */
-    public function __construct(Closure|HandlerInterface $handler, int|string|Level|LevelName|array $minLevelOrList = Level::Debug, int|string|Level|LevelName $maxLevel = Level::Emergency, bool $bubble = true)
+    public function __construct(Closure|HandlerInterface $handler, int|string|Level|array $minLevelOrList = Level::Debug, int|string|Level $maxLevel = Level::Emergency, bool $bubble = true)
     {
         $this->handler  = $handler;
         $this->bubble   = $bubble;
@@ -79,13 +78,13 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
     }
 
     /**
-     * @param int|string|Level|LevelName|LogLevel::*|array<int|string|Level|LevelName|LogLevel::*> $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided
-     * @param int|string|Level|LevelName|LogLevel::*                                               $maxLevel       Maximum level or level name to accept, only used if $minLevelOrList is not an array
+     * @param int|string|Level|LogLevel::*|array<int|string|Level|LogLevel::*> $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided
+     * @param int|string|Level|LogLevel::*                                               $maxLevel       Maximum level or level name to accept, only used if $minLevelOrList is not an array
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::*|array<value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::*> $minLevelOrList
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $maxLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::*|array<value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::*> $minLevelOrList
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $maxLevel
      */
-    public function setAcceptedLevels(int|string|Level|LevelName|array $minLevelOrList = Level::Debug, int|string|Level|LevelName $maxLevel = Level::Emergency): self
+    public function setAcceptedLevels(int|string|Level|array $minLevelOrList = Level::Debug, int|string|Level $maxLevel = Level::Emergency): self
     {
         if (is_array($minLevelOrList)) {
             $acceptedLevels = array_map(Logger::toMonologLevel(...), $minLevelOrList);

+ 5 - 6
src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler\FingersCrossed;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Psr\Log\LogLevel;
 use Monolog\LogRecord;
@@ -47,13 +46,13 @@ class ChannelLevelActivationStrategy implements ActivationStrategyInterface
     private array $channelToActionLevel;
 
     /**
-     * @param int|string|Level|LevelName|LogLevel::*                $defaultActionLevel   The default action level to be used if the record's category doesn't match any
-     * @param array<string, int|string|Level|LevelName|LogLevel::*> $channelToActionLevel An array that maps channel names to action levels.
+     * @param int|string|Level|LogLevel::*                $defaultActionLevel   The default action level to be used if the record's category doesn't match any
+     * @param array<string, int|string|Level|LogLevel::*> $channelToActionLevel An array that maps channel names to action levels.
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $defaultActionLevel
-     * @phpstan-param array<string, value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::*> $channelToActionLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $defaultActionLevel
+     * @phpstan-param array<string, value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::*> $channelToActionLevel
      */
-    public function __construct(int|string|Level|LevelName $defaultActionLevel, array $channelToActionLevel = [])
+    public function __construct(int|string|Level $defaultActionLevel, array $channelToActionLevel = [])
     {
         $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel);
         $this->channelToActionLevel = array_map(Logger::toMonologLevel(...), $channelToActionLevel);

+ 3 - 4
src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler\FingersCrossed;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 use Monolog\Logger;
 use Psr\Log\LogLevel;
@@ -27,11 +26,11 @@ class ErrorLevelActivationStrategy implements ActivationStrategyInterface
     private Level $actionLevel;
 
     /**
-     * @param int|string|Level|LevelName $actionLevel Level or name or value
+     * @param int|string|Level $actionLevel Level or name or value
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $actionLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $actionLevel
      */
-    public function __construct(int|string|Level|LevelName $actionLevel)
+    public function __construct(int|string|Level $actionLevel)
     {
         $this->actionLevel = Logger::toMonologLevel($actionLevel);
     }

+ 5 - 6
src/Monolog/Handler/FingersCrossedHandler.php

@@ -15,7 +15,6 @@ use Closure;
 use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
 use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Monolog\ResettableInterface;
 use Monolog\Formatter\FormatterInterface;
@@ -68,16 +67,16 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
      * @phpstan-param (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface $handler
      *
      * @param Closure|HandlerInterface                    $handler            Handler or factory Closure($record|null, $fingersCrossedHandler).
-     * @param int|string|Level|LevelName|LogLevel::*      $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated
+     * @param int|string|Level|LogLevel::*      $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated
      * @param int                                         $bufferSize         How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
      * @param bool                                        $bubble             Whether the messages that are handled can bubble up the stack or not
      * @param bool                                        $stopBuffering      Whether the handler should stop buffering after being triggered (default true)
-     * @param int|string|Level|LevelName|LogLevel::*|null $passthruLevel      Minimum level to always flush to handler on close, even if strategy not triggered
+     * @param int|string|Level|LogLevel::*|null $passthruLevel      Minimum level to always flush to handler on close, even if strategy not triggered
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::*|ActivationStrategyInterface $activationStrategy
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $passthruLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::*|ActivationStrategyInterface $activationStrategy
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $passthruLevel
      */
-    public function __construct(Closure|HandlerInterface $handler, int|string|Level|LevelName|ActivationStrategyInterface $activationStrategy = null, int $bufferSize = 0, bool $bubble = true, bool $stopBuffering = true, int|string|Level|LevelName|null $passthruLevel = null)
+    public function __construct(Closure|HandlerInterface $handler, int|string|Level|ActivationStrategyInterface $activationStrategy = null, int $bufferSize = 0, bool $bubble = true, bool $stopBuffering = true, int|string|Level|null $passthruLevel = null)
     {
         if (null === $activationStrategy) {
             $activationStrategy = new ErrorLevelActivationStrategy(Level::Warning);

+ 1 - 2
src/Monolog/Handler/GelfHandler.php

@@ -15,7 +15,6 @@ use Gelf\PublisherInterface;
 use Monolog\Level;
 use Monolog\Formatter\GelfMessageFormatter;
 use Monolog\Formatter\FormatterInterface;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -34,7 +33,7 @@ class GelfHandler extends AbstractProcessingHandler
     /**
      * @param PublisherInterface $publisher a gelf publisher object
      */
-    public function __construct(PublisherInterface $publisher, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(PublisherInterface $publisher, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
 

+ 1 - 2
src/Monolog/Handler/IFTTTHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -36,7 +35,7 @@ class IFTTTHandler extends AbstractProcessingHandler
      * @param string $eventName The name of the IFTTT Maker event that should be triggered
      * @param string $secretKey A valid IFTTT secret key
      */
-    public function __construct(string $eventName, string $secretKey, int|string|Level|LevelName $level = Level::Error, bool $bubble = true)
+    public function __construct(string $eventName, string $secretKey, int|string|Level $level = Level::Error, bool $bubble = true)
     {
         if (!extension_loaded('curl')) {
             throw new MissingExtensionException('The curl extension is needed to use the IFTTTHandler');

+ 1 - 2
src/Monolog/Handler/LogglyHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Level;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\LogglyFormatter;
-use Monolog\LevelName;
 use function array_key_exists;
 use CurlHandle;
 use Monolog\LogRecord;
@@ -49,7 +48,7 @@ class LogglyHandler extends AbstractProcessingHandler
      *
      * @throws MissingExtensionException If the curl extension is missing
      */
-    public function __construct(string $token, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(string $token, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         if (!extension_loaded('curl')) {
             throw new MissingExtensionException('The curl extension is needed to use the LogglyHandler');

+ 1 - 2
src/Monolog/Handler/MandrillHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Swift;
 use Swift_Message;
 
@@ -32,7 +31,7 @@ class MandrillHandler extends MailHandler
      * @param string                 $apiKey  A valid Mandrill API key
      * @param callable|Swift_Message $message An example message for real messages, only the body will be replaced
      */
-    public function __construct(string $apiKey, callable|Swift_Message $message, int|string|Level|LevelName $level = Level::Error, bool $bubble = true)
+    public function __construct(string $apiKey, callable|Swift_Message $message, int|string|Level $level = Level::Error, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
 

+ 1 - 2
src/Monolog/Handler/MongoDBHandler.php

@@ -17,7 +17,6 @@ use MongoDB\Client;
 use Monolog\Level;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\MongoDBFormatter;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -48,7 +47,7 @@ class MongoDBHandler extends AbstractProcessingHandler
      * @param string         $database   Database name
      * @param string         $collection Collection name
      */
-    public function __construct(Client|Manager $mongodb, string $database, string $collection, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(Client|Manager $mongodb, string $database, string $collection, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         if ($mongodb instanceof Client) {
             $this->collection = $mongodb->selectCollection($database, $collection);

+ 1 - 2
src/Monolog/Handler/NativeMailerHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use Monolog\Level;
 use Monolog\Formatter\LineFormatter;
-use Monolog\LevelName;
 
 /**
  * NativeMailerHandler uses the mail() function to send the emails
@@ -67,7 +66,7 @@ class NativeMailerHandler extends MailHandler
      * @param string          $from           The sender of the mail
      * @param int             $maxColumnWidth The maximum column width that the message lines will have
      */
-    public function __construct(string|array $to, string $subject, string $from, int|string|Level|LevelName $level = Level::Error, bool $bubble = true, int $maxColumnWidth = 70)
+    public function __construct(string|array $to, string $subject, string $from, int|string|Level $level = Level::Error, bool $bubble = true, int $maxColumnWidth = 70)
     {
         parent::__construct($level, $bubble);
         $this->to = (array) $to;

+ 1 - 2
src/Monolog/Handler/NewRelicHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\Formatter\NormalizerFormatter;
 use Monolog\Formatter\FormatterInterface;
@@ -33,7 +32,7 @@ class NewRelicHandler extends AbstractProcessingHandler
      * @inheritDoc
      */
     public function __construct(
-        int|string|Level|LevelName $level = Level::Error,
+        int|string|Level $level = Level::Error,
         bool $bubble = true,
 
         /**

+ 3 - 4
src/Monolog/Handler/NullHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Psr\Log\LogLevel;
 use Monolog\Logger;
 use Monolog\LogRecord;
@@ -30,11 +29,11 @@ class NullHandler extends Handler
     private Level $level;
 
     /**
-     * @param string|int|Level|LevelName $level The minimum logging level at which this handler will be triggered
+     * @param string|int|Level $level The minimum logging level at which this handler will be triggered
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function __construct(string|int|Level|LevelName $level = Level::Debug)
+    public function __construct(string|int|Level $level = Level::Debug)
     {
         $this->level = Logger::toMonologLevel($level);
     }

+ 2 - 3
src/Monolog/Handler/PHPConsoleHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Formatter\LineFormatter;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use PhpConsole\Connector;
 use PhpConsole\Handler as VendorPhpConsoleHandler;
@@ -121,7 +120,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler
      * @throws \RuntimeException
      * @phpstan-param InputOptions $options
      */
-    public function __construct(array $options = [], ?Connector $connector = null, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(array $options = [], ?Connector $connector = null, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         if (!class_exists('PhpConsole\Connector')) {
             throw new \RuntimeException('PHP Console library not found. See https://github.com/barbushin/php-console#installation');
@@ -289,7 +288,7 @@ class PHPConsoleHandler extends AbstractProcessingHandler
             }
         }
 
-        return [$tags ?? strtolower($record->levelName->value), $filteredContext];
+        return [$tags ?? $record->level->toPsrLogLevel(), $filteredContext];
     }
 
     /**

+ 1 - 2
src/Monolog/Handler/ProcessHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -59,7 +58,7 @@ class ProcessHandler extends AbstractProcessingHandler
      * @param  string|null               $cwd     "Current working directory" (CWD) for the process to be executed in.
      * @throws \InvalidArgumentException
      */
-    public function __construct(string $command, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, ?string $cwd = null)
+    public function __construct(string $command, int|string|Level $level = Level::Debug, bool $bubble = true, ?string $cwd = null)
     {
         if ($command === '') {
             throw new \InvalidArgumentException('The command argument must be a non-empty string.');

+ 3 - 4
src/Monolog/Handler/PsrHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Psr\Log\LoggerInterface;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\LogRecord;
@@ -38,7 +37,7 @@ class PsrHandler extends AbstractHandler implements FormattableHandlerInterface
     /**
      * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied
      */
-    public function __construct(LoggerInterface $logger, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(LoggerInterface $logger, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
 
@@ -56,9 +55,9 @@ class PsrHandler extends AbstractHandler implements FormattableHandlerInterface
 
         if ($this->formatter !== null) {
             $formatted = $this->formatter->format($record);
-            $this->logger->log(strtolower($record->levelName->value), (string) $formatted, $record->context);
+            $this->logger->log($record->level->toPsrLogLevel(), (string) $formatted, $record->context);
         } else {
-            $this->logger->log(strtolower($record->levelName->value), $record->message, $record->context);
+            $this->logger->log($record->level->toPsrLogLevel(), $record->message, $record->context);
         }
 
         return false === $this->bubble;

+ 13 - 14
src/Monolog/Handler/PushoverHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Monolog\Utils;
 use Psr\Log\LogLevel;
@@ -88,25 +87,25 @@ class PushoverHandler extends SocketHandler
      * @param int          $expire The expire parameter specifies how many seconds your notification will continue
      *                             to be retried for (every retry seconds).
      *
-     * @param int|string|Level|LevelName|LogLevel::* $highPriorityLevel The minimum logging level at which this handler will start
+     * @param int|string|Level|LogLevel::* $highPriorityLevel The minimum logging level at which this handler will start
      *                                                                  sending "high priority" requests to the Pushover API
-     * @param int|string|Level|LevelName|LogLevel::* $emergencyLevel    The minimum logging level at which this handler will start
+     * @param int|string|Level|LogLevel::* $emergencyLevel    The minimum logging level at which this handler will start
      *                                                                  sending "emergency" requests to the Pushover API
      *
      *
      * @phpstan-param string|array<int|string>    $users
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $highPriorityLevel
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $emergencyLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $highPriorityLevel
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $emergencyLevel
      */
     public function __construct(
         string $token,
         $users,
         ?string $title = null,
-        int|string|Level|LevelName $level = Level::Critical,
+        int|string|Level $level = Level::Critical,
         bool $bubble = true,
         bool $useSSL = true,
-        int|string|Level|LevelName $highPriorityLevel = Level::Critical,
-        int|string|Level|LevelName $emergencyLevel = Level::Emergency,
+        int|string|Level $highPriorityLevel = Level::Critical,
+        int|string|Level $emergencyLevel = Level::Emergency,
         int $retry = 30,
         int $expire = 25200,
         bool $persistent = false,
@@ -208,11 +207,11 @@ class PushoverHandler extends SocketHandler
     }
 
     /**
-     * @param int|string|Level|LevelName|LogLevel::* $level
+     * @param int|string|Level|LogLevel::* $level
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function setHighPriorityLevel(int|string|Level|LevelName $level): self
+    public function setHighPriorityLevel(int|string|Level $level): self
     {
         $this->highPriorityLevel = Logger::toMonologLevel($level);
 
@@ -220,11 +219,11 @@ class PushoverHandler extends SocketHandler
     }
 
     /**
-     * @param int|string|Level|LevelName|LogLevel::* $level
+     * @param int|string|Level|LogLevel::* $level
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function setEmergencyLevel(int|string|Level|LevelName $level): self
+    public function setEmergencyLevel(int|string|Level $level): self
     {
         $this->emergencyLevel = Logger::toMonologLevel($level);
 

+ 1 - 2
src/Monolog/Handler/RedisHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Formatter\LineFormatter;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 use Predis\Client as Predis;
 use Redis;
@@ -42,7 +41,7 @@ class RedisHandler extends AbstractProcessingHandler
      * @param string               $key     The key name to push records to
      * @param int                  $capSize Number of entries to limit list size to, 0 = unlimited
      */
-    public function __construct(Predis|Redis $redis, string $key, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, int $capSize = 0)
+    public function __construct(Predis|Redis $redis, string $key, int|string|Level $level = Level::Debug, bool $bubble = true, int $capSize = 0)
     {
         $this->redisClient = $redis;
         $this->redisKey = $key;

+ 1 - 2
src/Monolog/Handler/RedisPubSubHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Formatter\LineFormatter;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 use Predis\Client as Predis;
 use Redis;
@@ -40,7 +39,7 @@ class RedisPubSubHandler extends AbstractProcessingHandler
      * @param Predis<Predis>|Redis $redis The redis instance
      * @param string               $key   The channel key to publish records to
      */
-    public function __construct(Predis|Redis $redis, string $key, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(Predis|Redis $redis, string $key, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         $this->redisClient = $redis;
         $this->channelKey = $key;

+ 2 - 3
src/Monolog/Handler/RollbarHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Rollbar\RollbarLogger;
 use Throwable;
 use Monolog\LogRecord;
@@ -47,7 +46,7 @@ class RollbarHandler extends AbstractProcessingHandler
     /**
      * @param RollbarLogger $rollbarLogger RollbarLogger object constructed with valid token
      */
-    public function __construct(RollbarLogger $rollbarLogger, int|string|Level|LevelName $level = Level::Error, bool $bubble = true)
+    public function __construct(RollbarLogger $rollbarLogger, int|string|Level $level = Level::Error, bool $bubble = true)
     {
         $this->rollbarLogger = $rollbarLogger;
 
@@ -87,7 +86,7 @@ class RollbarHandler extends AbstractProcessingHandler
         $context = $record->context;
         $context = array_merge($context, $record->extra, [
             'level' => $this->toRollbarLevel($record->level),
-            'monolog_level' => $record->levelName,
+            'monolog_level' => $record->level->getName(),
             'channel' => $record->channel,
             'datetime' => $record->datetime->format('U'),
         ]);

+ 1 - 2
src/Monolog/Handler/RotatingFileHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use InvalidArgumentException;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -44,7 +43,7 @@ class RotatingFileHandler extends StreamHandler
      * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
      * @param bool     $useLocking     Try to lock log file before doing any writes
      */
-    public function __construct(string $filename, int $maxFiles = 0, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
+    public function __construct(string $filename, int $maxFiles = 0, int|string|Level $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
     {
         $this->filename = Utils::canonicalizePath($filename);
         $this->maxFiles = $maxFiles;

+ 1 - 2
src/Monolog/Handler/SendGridHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 
 /**
  * SendGridrHandler uses the SendGrid API v2 function to send Log emails, more information in https://sendgrid.com/docs/API_Reference/Web_API/mail.html
@@ -54,7 +53,7 @@ class SendGridHandler extends MailHandler
      * @param string|string[] $to      The recipients of the email
      * @param string          $subject The subject of the mail
      */
-    public function __construct(string $apiUser, string $apiKey, string $from, string|array $to, string $subject, int|string|Level|LevelName $level = Level::Error, bool $bubble = true)
+    public function __construct(string $apiUser, string $apiKey, string $from, string|array $to, string $subject, int|string|Level $level = Level::Error, bool $bubble = true)
     {
         if (!extension_loaded('curl')) {
             throw new MissingExtensionException('The curl extension is needed to use the SendGridHandler');

+ 1 - 2
src/Monolog/Handler/SqsHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use Aws\Sqs\SqsClient;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -32,7 +31,7 @@ class SqsHandler extends AbstractProcessingHandler
     private SqsClient $client;
     private string $queueUrl;
 
-    public function __construct(SqsClient $sqsClient, string $queueUrl, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(SqsClient $sqsClient, string $queueUrl, int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
 

+ 1 - 2
src/Monolog/Handler/StreamHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -45,7 +44,7 @@ class StreamHandler extends AbstractProcessingHandler
      *
      * @throws \InvalidArgumentException If stream is not a resource or string
      */
-    public function __construct($stream, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
+    public function __construct($stream, int|string|Level $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
     {
         parent::__construct($level, $bubble);
 

+ 1 - 2
src/Monolog/Handler/SymfonyMailerHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use Closure;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Monolog\LogRecord;
 use Monolog\Utils;
@@ -40,7 +39,7 @@ class SymfonyMailerHandler extends MailHandler
      * @param MailerInterface|TransportInterface $mailer The mailer to use
      * @param Closure|Email                      $email  An email template, the subject/body will be replaced
      */
-    public function __construct($mailer, Email|Closure $email, int|string|Level|LevelName $level = Level::Error, bool $bubble = true)
+    public function __construct($mailer, Email|Closure $email, int|string|Level $level = Level::Error, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
 

+ 1 - 2
src/Monolog/Handler/SyslogHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -38,7 +37,7 @@ class SyslogHandler extends AbstractSyslogHandler
      * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant
      * @param int        $logopts  Option flags for the openlog() call, defaults to LOG_PID
      */
-    public function __construct(string $ident, string|int $facility = LOG_USER, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, int $logopts = LOG_PID)
+    public function __construct(string $ident, string|int $facility = LOG_USER, int|string|Level $level = Level::Debug, bool $bubble = true, int $logopts = LOG_PID)
     {
         parent::__construct($facility, $level, $bubble);
 

+ 1 - 2
src/Monolog/Handler/SyslogUdpHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use DateTimeInterface;
 use Monolog\Level;
 use Monolog\Handler\SyslogUdp\UdpSocket;
-use Monolog\LevelName;
 use Monolog\Utils;
 use Monolog\LogRecord;
 
@@ -53,7 +52,7 @@ class SyslogUdpHandler extends AbstractSyslogHandler
      *
      * @phpstan-param self::RFC* $rfc
      */
-    public function __construct(string $host, int $port = 514, string|int $facility = LOG_USER, int|string|Level|LevelName $level = Level::Debug, bool $bubble = true, string $ident = 'php', int $rfc = self::RFC5424)
+    public function __construct(string $host, int $port = 514, string|int $facility = LOG_USER, int|string|Level $level = Level::Debug, bool $bubble = true, string $ident = 'php', int $rfc = self::RFC5424)
     {
         if (!extension_loaded('sockets')) {
             throw new MissingExtensionException('The sockets extension is required to use the SyslogUdpHandler');

+ 3 - 4
src/Monolog/Handler/TestHandler.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Psr\Log\LogLevel;
 use Monolog\LogRecord;
@@ -104,11 +103,11 @@ class TestHandler extends AbstractProcessingHandler
     }
 
     /**
-     * @param int|string|Level|LevelName|LogLevel::* $level Logging level value or name
+     * @param int|string|Level|LogLevel::* $level Logging level value or name
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function hasRecords(int|string|Level|LevelName $level): bool
+    public function hasRecords(int|string|Level $level): bool
     {
         return isset($this->recordsByLevel[Logger::toMonologLevel($level)->value]);
     }

+ 2 - 3
src/Monolog/Handler/ZendMonitorHandler.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\NormalizerFormatter;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\LogRecord;
 
 /**
@@ -28,7 +27,7 @@ class ZendMonitorHandler extends AbstractProcessingHandler
     /**
      * @throws MissingExtensionException
      */
-    public function __construct(int|string|Level|LevelName $level = Level::Debug, bool $bubble = true)
+    public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true)
     {
         if (!function_exists('zend_monitor_custom_event')) {
             throw new MissingExtensionException(
@@ -62,7 +61,7 @@ class ZendMonitorHandler extends AbstractProcessingHandler
     protected function write(LogRecord $record): void
     {
         $this->writeZendMonitorCustomEvent(
-            $record->level->toLevelName()->value,
+            $record->level->getName(),
             $record->message,
             $record->formatted,
             $this->toZendMonitorLevel($record->level)

+ 64 - 12
src/Monolog/Level.php

@@ -14,7 +14,19 @@ namespace Monolog;
 use Psr\Log\LogLevel;
 
 /**
- * @see LevelName
+ * Represents the log levels
+ *
+ * Monolog supports the logging levels described by RFC 5424 {@see https://datatracker.ietf.org/doc/html/rfc5424}
+ * but due to BC the severity values used internally are not 0-7.
+ *
+ * To get the level name out of a Level there are three options:
+ *
+ * - Use ->getName() to get the standard Monolog name which is full uppercased (e.g. "DEBUG")
+ * - Use ->toPsrLogLevel() to get the standard PSR-3 name which is full lowercased (e.g. "debug")
+ * - Use ->name to get the enum case's name which is capitalized (e.g. "Debug")
+ *
+ * To get the value for filtering, if the includes/isLowerThan/isHigherThan methods are
+ * not enough, you can use ->value to get the enum case's integer value.
  */
 enum Level: int
 {
@@ -68,20 +80,33 @@ enum Level: int
      */
     case Emergency = 600;
 
-    public static function fromLevelName(LevelName $name): self
+    /**
+     * @param value-of<self::NAMES>|LogLevel::*|'Debug'|'Info'|'Notice'|'Warning'|'Error'|'Critical'|'Alert'|'Emergency' $name
+     * @return static
+     */
+    public static function fromName(string $name): self
     {
         return match ($name) {
-            LevelName::Debug => self::Debug,
-            LevelName::Info => self::Info,
-            LevelName::Notice => self::Notice,
-            LevelName::Warning => self::Warning,
-            LevelName::Error => self::Error,
-            LevelName::Critical => self::Critical,
-            LevelName::Alert => self::Alert,
-            LevelName::Emergency => self::Emergency,
+            'debug', 'Debug', 'DEBUG' => self::Debug,
+            'info', 'Info', 'INFO' => self::Info,
+            'notice', 'Notice', 'NOTICE' => self::Notice,
+            'warning', 'Warning', 'WARNING' => self::Warning,
+            'error', 'Error', 'ERROR' => self::Error,
+            'critical', 'Critical', 'CRITICAL' => self::Critical,
+            'alert', 'Alert', 'ALERT' => self::Alert,
+            'emergency', 'Emergency', 'EMERGENCY' => self::Emergency,
         };
     }
 
+    /**
+     * @param value-of<self::VALUES> $value
+     * @return static
+     */
+    public static function fromValue(int $value): self
+    {
+        return self::from($value);
+    }
+
     /**
      * Returns true if the passed $level is higher or equal to $this
      */
@@ -100,9 +125,25 @@ enum Level: int
         return $this->value < $level->value;
     }
 
-    public function toLevelName(): LevelName
+    /**
+     * Returns the monolog standardized all-capitals name of the level
+     *
+     * Use this instead of $level->name which returns the enum case name (e.g. Debug vs DEBUG if you use getName())
+     *
+     * @return value-of<self::NAMES>
+     */
+    public function getName(): string
     {
-        return LevelName::fromLevel($this);
+        return match ($this) {
+            self::Debug => 'DEBUG',
+            self::Info => 'INFO',
+            self::Notice => 'NOTICE',
+            self::Warning => 'WARNING',
+            self::Error => 'ERROR',
+            self::Critical => 'CRITICAL',
+            self::Alert => 'ALERT',
+            self::Emergency => 'EMERGENCY',
+        };
     }
 
     /**
@@ -132,4 +173,15 @@ enum Level: int
         550,
         600,
     ];
+
+    public const NAMES = [
+        'DEBUG',
+        'INFO',
+        'NOTICE',
+        'WARNING',
+        'ERROR',
+        'CRITICAL',
+        'ALERT',
+        'EMERGENCY',
+    ];
 }

+ 0 - 57
src/Monolog/LevelName.php

@@ -1,57 +0,0 @@
-<?php declare(strict_types=1);
-
-/*
- * This file is part of the Monolog package.
- *
- * (c) Jordi Boggiano <j.boggiano@seld.be>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Monolog;
-
-/**
- * @see Level
- */
-enum LevelName: string
-{
-    case Debug = 'DEBUG';
-    case Info = 'INFO';
-    case Notice = 'NOTICE';
-    case Warning = 'WARNING';
-    case Error = 'ERROR';
-    case Critical = 'CRITICAL';
-    case Alert = 'ALERT';
-    case Emergency = 'EMERGENCY';
-
-    public static function fromLevel(Level $level): self
-    {
-        return match ($level) {
-            Level::Debug => self::Debug,
-            Level::Info => self::Info,
-            Level::Notice => self::Notice,
-            Level::Warning => self::Warning,
-            Level::Error => self::Error,
-            Level::Critical => self::Critical,
-            Level::Alert => self::Alert,
-            Level::Emergency => self::Emergency,
-        };
-    }
-
-    public function toLevel(): Level
-    {
-        return Level::fromLevelName($this);
-    }
-
-    public const VALUES = [
-        'DEBUG',
-        'INFO',
-        'NOTICE',
-        'WARNING',
-        'ERROR',
-        'CRITICAL',
-        'ALERT',
-        'EMERGENCY',
-    ];
-}

+ 6 - 9
src/Monolog/LogRecord.php

@@ -26,8 +26,6 @@ class LogRecord implements ArrayAccess
         'formatted' => true,
     ];
 
-    public readonly LevelName $levelName;
-
     public function __construct(
         public readonly \DateTimeImmutable $datetime,
         public readonly string $channel,
@@ -39,7 +37,6 @@ class LogRecord implements ArrayAccess
         public array $extra = [],
         public mixed $formatted = null,
     ) {
-        $this->levelName = LevelName::fromLevel($level);
     }
 
     public function offsetSet(mixed $offset, mixed $value): void
@@ -80,13 +77,13 @@ class LogRecord implements ArrayAccess
     public function &offsetGet(mixed $offset): mixed
     {
         if ($offset === 'level_name' || $offset === 'level') {
+            // avoid returning readonly props by ref as this is illegal
             if ($offset === 'level_name') {
-                $offset = 'levelName';
+                $copy = $this->level->getName();
+            } else {
+                $copy = $this->level->value;
             }
 
-            // avoid returning readonly props by ref as this is illegal
-            $copy = $this->{$offset}->value;
-
             return $copy;
         }
 
@@ -101,7 +98,7 @@ class LogRecord implements ArrayAccess
     }
 
     /**
-     * @phpstan-return array{message: string, context: mixed[], level: value-of<Level::VALUES>, level_name: value-of<LevelName::VALUES>, channel: string, datetime: \DateTimeImmutable, extra: mixed[]}
+     * @phpstan-return array{message: string, context: mixed[], level: value-of<Level::VALUES>, level_name: value-of<Level::NAMES>, channel: string, datetime: \DateTimeImmutable, extra: mixed[]}
      */
     public function toArray(): array
     {
@@ -109,7 +106,7 @@ class LogRecord implements ArrayAccess
             'message' => $this->message,
             'context' => $this->context,
             'level' => $this->level->value,
-            'level_name' => $this->levelName->value,
+            'level_name' => $this->level->getName(),
             'channel' => $this->channel,
             'datetime' => $this->datetime,
             'extra' => $this->extra,

+ 13 - 17
src/Monolog/Logger.php

@@ -368,43 +368,39 @@ class Logger implements LoggerInterface, ResettableInterface
     /**
      * Gets the name of the logging level as a string.
      *
-     * This still returns a string instead of a LevelName for BC, but new code should not rely on this method.
+     * This still returns a string instead of a Level for BC, but new code should not rely on this method.
      *
      * @throws \Psr\Log\InvalidArgumentException If level is not defined
      *
      * @phpstan-param  value-of<Level::VALUES>|Level $level
-     * @phpstan-return value-of<LevelName::VALUES>
+     * @phpstan-return value-of<Level::NAMES>
      *
-     * @deprecated Use Monolog\Level->toLevelName()->value instead
+     * @deprecated Since 3.0, use {@see toMonologLevel} or {@see \Monolog\Level->getName()} instead
      */
     public static function getLevelName(int|Level $level): string
     {
-        return self::toMonologLevel($level)->toLevelName()->value;
+        return self::toMonologLevel($level)->getName();
     }
 
     /**
      * Converts PSR-3 levels to Monolog ones if necessary
      *
-     * @param  int|string|Level|LevelName|LogLevel::* $level Level number (monolog) or name (PSR-3)
+     * @param  int|string|Level|LogLevel::* $level Level number (monolog) or name (PSR-3)
      * @throws \Psr\Log\InvalidArgumentException      If level is not defined
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public static function toMonologLevel(string|int|Level|LevelName $level): Level
+    public static function toMonologLevel(string|int|Level $level): 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));
+                    throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', Level::NAMES + Level::VALUES));
                 }
 
                 return $levelEnum;
@@ -417,12 +413,12 @@ class Logger implements LoggerInterface, ResettableInterface
                 return constant(Level::class . '::' . $upper);
             }
 
-            throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', LevelName::VALUES + Level::VALUES));
+            throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', Level::NAMES + Level::VALUES));
         }
 
         $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));
+            throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', Level::NAMES + Level::VALUES));
         }
 
         return $levelEnum;
@@ -431,9 +427,9 @@ class Logger implements LoggerInterface, ResettableInterface
     /**
      * Checks whether the Logger has a handler that listens on the given level
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function isHandling(int|string|LevelName|Level $level): bool
+    public function isHandling(int|string|Level $level): bool
     {
         $record = new LogRecord(
             datetime: new DateTimeImmutable($this->microsecondTimestamps, $this->timezone),
@@ -477,7 +473,7 @@ class Logger implements LoggerInterface, ResettableInterface
      * @param string|Stringable $message The log message
      * @param mixed[]           $context The log context
      *
-     * @phpstan-param Level|LevelName|LogLevel::* $level
+     * @phpstan-param Level|LogLevel::* $level
      */
     public function log($level, string|\Stringable $message, array $context = []): void
     {

+ 3 - 4
src/Monolog/Processor/GitProcessor.php

@@ -12,7 +12,6 @@
 namespace Monolog\Processor;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Psr\Log\LogLevel;
 use Monolog\LogRecord;
@@ -30,11 +29,11 @@ class GitProcessor implements ProcessorInterface
     private static $cache = null;
 
     /**
-     * @param int|string|Level|LevelName|LogLevel::* $level The minimum logging level at which this Processor will be triggered
+     * @param int|string|Level|LogLevel::* $level The minimum logging level at which this Processor will be triggered
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function __construct(int|string|Level|LevelName $level = Level::Debug)
+    public function __construct(int|string|Level $level = Level::Debug)
     {
         $this->level = Logger::toMonologLevel($level);
     }

+ 3 - 4
src/Monolog/Processor/IntrospectionProcessor.php

@@ -12,7 +12,6 @@
 namespace Monolog\Processor;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Psr\Log\LogLevel;
 use Monolog\LogRecord;
@@ -43,12 +42,12 @@ class IntrospectionProcessor implements ProcessorInterface
     ];
 
     /**
-     * @param string|int|Level|LevelName $level               The minimum logging level at which this Processor will be triggered
+     * @param string|int|Level $level               The minimum logging level at which this Processor will be triggered
      * @param string[]                   $skipClassesPartials
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function __construct(int|string|Level|LevelName $level = Level::Debug, array $skipClassesPartials = [], int $skipStackFramesCount = 0)
+    public function __construct(int|string|Level $level = Level::Debug, array $skipClassesPartials = [], int $skipStackFramesCount = 0)
     {
         $this->level = Logger::toMonologLevel($level);
         $this->skipClassesPartials = array_merge(['Monolog\\'], $skipClassesPartials);

+ 3 - 4
src/Monolog/Processor/MercurialProcessor.php

@@ -12,7 +12,6 @@
 namespace Monolog\Processor;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Psr\Log\LogLevel;
 use Monolog\LogRecord;
@@ -29,11 +28,11 @@ class MercurialProcessor implements ProcessorInterface
     private static $cache = null;
 
     /**
-     * @param int|string|Level|LevelName $level The minimum logging level at which this Processor will be triggered
+     * @param int|string|Level $level The minimum logging level at which this Processor will be triggered
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function __construct(int|string|Level|LevelName $level = Level::Debug)
+    public function __construct(int|string|Level $level = Level::Debug)
     {
         $this->level = Logger::toMonologLevel($level);
     }

+ 3 - 3
src/Monolog/SignalHandler.php

@@ -37,12 +37,12 @@ class SignalHandler
     }
 
     /**
-     * @param  int|string|Level|LevelName $level Level or level name
+     * @param  int|string|Level $level Level or level name
      * @return $this
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    public function registerSignalHandler(int $signo, int|string|Level|LevelName $level = LogLevel::CRITICAL, bool $callPrevious = true, bool $restartSyscalls = true, ?bool $async = true): self
+    public function registerSignalHandler(int $signo, int|string|Level $level = LogLevel::CRITICAL, bool $callPrevious = true, bool $restartSyscalls = true, ?bool $async = true): self
     {
         if (!extension_loaded('pcntl') || !function_exists('pcntl_signal')) {
             return $this;

+ 2 - 3
src/Monolog/Test/TestCase.php

@@ -12,7 +12,6 @@
 namespace Monolog\Test;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Logger;
 use Monolog\LogRecord;
 use Monolog\DateTimeImmutable;
@@ -39,9 +38,9 @@ class TestCase extends \PHPUnit\Framework\TestCase
      * @param array<mixed> $context
      * @param array<mixed> $extra
      *
-     * @phpstan-param value-of<Level::VALUES>|value-of<LevelName::VALUES>|Level|LevelName|LogLevel::* $level
+     * @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
      */
-    protected function getRecord(int|string|LevelName|Level $level = Level::Warning, string|\Stringable $message = 'test', array $context = [], string $channel = 'test', \DateTimeImmutable $datetime = new DateTimeImmutable(true), array $extra = []): LogRecord
+    protected function getRecord(int|string|Level $level = Level::Warning, string|\Stringable $message = 'test', array $context = [], string $channel = 'test', \DateTimeImmutable $datetime = new DateTimeImmutable(true), array $extra = []): LogRecord
     {
         return new LogRecord(
             message: (string) $message,

+ 1 - 2
tests/Monolog/Formatter/LogstashFormatterTest.php

@@ -12,7 +12,6 @@
 namespace Monolog\Formatter;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Test\TestCase;
 
 class LogstashFormatterTest extends TestCase
@@ -36,7 +35,7 @@ class LogstashFormatterTest extends TestCase
         $this->assertEquals("1", $message['@version']);
         $this->assertEquals('log', $message['message']);
         $this->assertEquals('meh', $message['channel']);
-        $this->assertEquals(LevelName::Error->value, $message['level']);
+        $this->assertEquals(Level::Error->getName(), $message['level']);
         $this->assertEquals(Level::Error->value, $message['monolog_level']);
         $this->assertEquals('test', $message['type']);
         $this->assertEquals('hostname', $message['host']);

+ 1 - 2
tests/Monolog/Formatter/MongoDBFormatterTest.php

@@ -15,7 +15,6 @@ use MongoDB\BSON\ObjectId;
 use MongoDB\BSON\Regex;
 use MongoDB\BSON\UTCDateTime;
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Test\TestCase;
 
 /**
@@ -75,7 +74,7 @@ class MongoDBFormatterTest extends TestCase
         $this->assertEquals('some log message', $formattedRecord['message']);
         $this->assertEquals([], $formattedRecord['context']);
         $this->assertEquals(Level::Warning->value, $formattedRecord['level']);
-        $this->assertEquals(LevelName::Warning->value, $formattedRecord['level_name']);
+        $this->assertEquals(Level::Warning->getName(), $formattedRecord['level_name']);
         $this->assertEquals('test', $formattedRecord['channel']);
         $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $formattedRecord['datetime']);
         $this->assertEquals('1453410690123', $formattedRecord['datetime']->__toString());

+ 3 - 4
tests/Monolog/Formatter/NormalizerFormatterTest.php

@@ -11,7 +11,6 @@
 
 namespace Monolog\Formatter;
 
-use Monolog\LevelName;
 use Monolog\Test\TestCase;
 use Monolog\Level;
 
@@ -38,7 +37,7 @@ class NormalizerFormatterTest extends TestCase
         ));
 
         $this->assertEquals([
-            'level_name' => LevelName::Error->value,
+            'level_name' => Level::Error->getName(),
             'level' => Level::Error->value,
             'channel' => 'meh',
             'message' => 'foo',
@@ -148,7 +147,7 @@ class NormalizerFormatterTest extends TestCase
         ]);
         $this->assertEquals([
             [
-                'level_name' => LevelName::Critical->value,
+                'level_name' => Level::Critical->getName(),
                 'level' => Level::Critical->value,
                 'channel' => 'test',
                 'message' => 'bar',
@@ -157,7 +156,7 @@ class NormalizerFormatterTest extends TestCase
                 'extra' => [],
             ],
             [
-                'level_name' => LevelName::Warning->value,
+                'level_name' => Level::Warning->getName(),
                 'level' => Level::Warning->value,
                 'channel' => 'log',
                 'message' => 'foo',

+ 4 - 6
tests/Monolog/Handler/PsrHandlerTest.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Test\TestCase;
 use Monolog\Formatter\LineFormatter;
 
@@ -24,7 +23,7 @@ class PsrHandlerTest extends TestCase
     public function logLevelProvider()
     {
         return array_map(
-            fn (Level $level) => [$level->toLevelName(), $level],
+            fn (Level $level) => [$level->toPsrLogLevel(), $level],
             Level::cases()
         );
     }
@@ -32,7 +31,7 @@ class PsrHandlerTest extends TestCase
     /**
      * @dataProvider logLevelProvider
      */
-    public function testHandlesAllLevels(LevelName $levelName, Level $level)
+    public function testHandlesAllLevels(string $levelName, Level $level)
     {
         $message = 'Hello, world! ' . $level->value;
         $context = ['foo' => 'bar', 'level' => $level->value];
@@ -40,7 +39,7 @@ class PsrHandlerTest extends TestCase
         $psrLogger = $this->createMock('Psr\Log\NullLogger');
         $psrLogger->expects($this->once())
             ->method('log')
-            ->with(strtolower($levelName->value), $message, $context);
+            ->with($levelName, $message, $context);
 
         $handler = new PsrHandler($psrLogger);
         $handler->handle($this->getRecord($level, $message, context: $context));
@@ -51,12 +50,11 @@ class PsrHandlerTest extends TestCase
         $message = 'Hello, world!';
         $context = ['foo' => 'bar'];
         $level = Level::Error;
-        $levelName = LevelName::Error;
 
         $psrLogger = $this->createMock('Psr\Log\NullLogger');
         $psrLogger->expects($this->once())
             ->method('log')
-            ->with(strtolower($levelName->value), 'dummy', $context);
+            ->with($level->toPsrLogLevel(), 'dummy', $context);
 
         $handler = new PsrHandler($psrLogger);
         $handler->setFormatter(new LineFormatter('dummy'));

+ 4 - 5
tests/Monolog/Handler/Slack/SlackRecordTest.php

@@ -12,7 +12,6 @@
 namespace Monolog\Handler\Slack;
 
 use Monolog\Level;
-use Monolog\LevelName;
 use Monolog\Test\TestCase;
 
 /**
@@ -227,7 +226,7 @@ class SlackRecordTest extends TestCase
     public function testAddsShortAttachmentWithoutContextAndExtra()
     {
         $level = Level::Error;
-        $levelName = LevelName::fromLevel($level)->value;
+        $levelName = $level->getName();
         $record = new SlackRecord(null, null, true, null, true);
         $data = $record->getSlackData($this->getRecord($level, 'test', ['test' => 1]));
 
@@ -241,7 +240,7 @@ class SlackRecordTest extends TestCase
     public function testAddsShortAttachmentWithContextAndExtra()
     {
         $level = Level::Error;
-        $levelName = LevelName::fromLevel($level)->value;
+        $levelName = $level->getName();
         $context = ['test' => 1];
         $extra = ['tags' => ['web']];
         $record = new SlackRecord(null, null, true, null, true, true);
@@ -274,7 +273,7 @@ class SlackRecordTest extends TestCase
     public function testAddsLongAttachmentWithoutContextAndExtra()
     {
         $level = Level::Error;
-        $levelName = LevelName::fromLevel($level)->value;
+        $levelName = $level->getName();
         $record = new SlackRecord(null, null, true, null);
         $data = $record->getSlackData($this->getRecord($level, 'test', ['test' => 1]));
 
@@ -296,7 +295,7 @@ class SlackRecordTest extends TestCase
     public function testAddsLongAttachmentWithContextAndExtra()
     {
         $level = Level::Error;
-        $levelName = LevelName::fromLevel($level)->value;
+        $levelName = $level->getName();
         $context = ['test' => 1];
         $extra = ['tags' => ['web']];
         $record = new SlackRecord(null, null, true, null, false, true);

+ 1 - 2
tests/Monolog/Handler/SlackWebhookHandlerTest.php

@@ -11,7 +11,6 @@
 
 namespace Monolog\Handler;
 
-use Monolog\LevelName;
 use Monolog\Test\TestCase;
 use Monolog\Level;
 use Monolog\Formatter\LineFormatter;
@@ -119,7 +118,7 @@ class SlackWebhookHandlerTest extends TestCase
                     'fields' => [
                         [
                             'title' => 'Level',
-                            'value' => LevelName::Warning->value,
+                            'value' => Level::Warning->getName(),
                             'short' => false,
                         ],
                     ],

+ 1 - 1
tests/Monolog/Handler/ZendMonitorHandlerTest.php

@@ -58,7 +58,7 @@ class ZendMonitorHandlerTest extends TestCase
         $zendMonitor->expects($this->once())
             ->method('writeZendMonitorCustomEvent')
             ->with(
-                $record->levelName->value,
+                $record->level->getName(),
                 $record->message,
                 $formatterResult,
                 \ZEND_MONITOR_EVENT_SEVERITY_WARNING