Browse Source

Add psr/log compatibility

Jordi Boggiano 13 năm trước cách đây
mục cha
commit
7913cd2c4d

+ 2 - 1
composer.json

@@ -13,7 +13,8 @@
         }
     ],
     "require": {
-        "php": ">=5.3.0"
+        "php": ">=5.3.0",
+        "psr/log": "~1.0"
     },
     "require-dev": {
         "mlehner/gelf-php": "1.0.*"

+ 80 - 2
src/Monolog/Logger.php

@@ -13,6 +13,8 @@ namespace Monolog;
 
 use Monolog\Handler\HandlerInterface;
 use Monolog\Handler\StreamHandler;
+use Psr\Log\LoggerInterface;
+use Psr\Log\InvalidArgumentException;
 
 /**
  * Monolog log channel
@@ -22,7 +24,7 @@ use Monolog\Handler\StreamHandler;
  *
  * @author Jordi Boggiano <j.boggiano@seld.be>
  */
-class Logger
+class Logger implements LoggerInterface
 {
     /**
      * Detailed debug information
@@ -206,6 +208,7 @@ class Logger
         if (null === $handlerKey) {
             return false;
         }
+
         // found at least one, process message and dispatch it
         foreach ($this->processors as $processor) {
             $record = call_user_func($processor, $record);
@@ -323,7 +326,7 @@ class Logger
     public static function getLevelName($level)
     {
         if (!isset(static::$levels[$level])) {
-            throw new \InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
+            throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
         }
 
         return static::$levels[$level];
@@ -350,6 +353,25 @@ class Logger
         return false;
     }
 
+    /**
+     * Adds a log record at an arbitrary level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param  mixed   $level   The log level
+     * @param  string  $message The log message
+     * @param  array   $context The log context
+     * @return Boolean Whether the record has been processed
+     */
+    public function log($level, $message, array $context = array())
+    {
+        if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) {
+            $level = constant(__CLASS__.'::'.strtoupper($level));
+        }
+
+        return $this->addRecord($level, $message, $context);
+    }
+
     /**
      * Adds a log record at the DEBUG level.
      *
@@ -406,6 +428,20 @@ class Logger
         return $this->addRecord(static::WARNING, $message, $context);
     }
 
+    /**
+     * Adds a log record at the WARNING level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param  string  $message The log message
+     * @param  array   $context The log context
+     * @return Boolean Whether the record has been processed
+     */
+    public function warning($message, array $context = array())
+    {
+        return $this->addRecord(static::WARNING, $message, $context);
+    }
+
     /**
      * Adds a log record at the ERROR level.
      *
@@ -420,6 +456,20 @@ class Logger
         return $this->addRecord(static::ERROR, $message, $context);
     }
 
+    /**
+     * Adds a log record at the ERROR level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param  string  $message The log message
+     * @param  array   $context The log context
+     * @return Boolean Whether the record has been processed
+     */
+    public function error($message, array $context = array())
+    {
+        return $this->addRecord(static::ERROR, $message, $context);
+    }
+
     /**
      * Adds a log record at the CRITICAL level.
      *
@@ -434,6 +484,20 @@ class Logger
         return $this->addRecord(static::CRITICAL, $message, $context);
     }
 
+    /**
+     * Adds a log record at the CRITICAL level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param  string  $message The log message
+     * @param  array   $context The log context
+     * @return Boolean Whether the record has been processed
+     */
+    public function critical($message, array $context = array())
+    {
+        return $this->addRecord(static::CRITICAL, $message, $context);
+    }
+
     /**
      * Adds a log record at the ALERT level.
      *
@@ -461,4 +525,18 @@ class Logger
     {
         return $this->addRecord(static::EMERGENCY, $message, $context);
     }
+
+    /**
+     * Adds a log record at the EMERGENCY level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param  string  $message The log message
+     * @param  array   $context The log context
+     * @return Boolean Whether the record has been processed
+     */
+    public function emergency($message, array $context = array())
+    {
+        return $this->addRecord(static::EMERGENCY, $message, $context);
+    }
 }

+ 42 - 0
src/Monolog/Processor/PsrLogMessageProcessor.php

@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * 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\Processor;
+
+/**
+ * Processes a record's message according to PSR-3 rules
+ *
+ * It replaces {foo} with the value from $context['foo']
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class PsrLogMessageProcessor
+{
+    /**
+     * @param  array $record
+     * @return array
+     */
+    public function __invoke(array $record)
+    {
+        if (false === strpos($record['message'], '{')) {
+            return $record;
+        }
+
+        $replacements = array();
+        foreach ($record['context'] as $key => $val) {
+            $replacements['{'.$key.'}'] = $val;
+        }
+
+        $record['message'] = strtr($record['message'], $replacements);
+
+        return $record;
+    }
+}

+ 47 - 0
tests/Monolog/PsrLogCompatTest.php

@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * 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;
+
+use Monolog\Handler\TestHandler;
+use Monolog\Formatter\LineFormatter;
+use Monolog\Processor\PsrLogMessageProcessor;
+use Psr\Log\Test\LoggerInterfaceTest;
+
+class PsrLogCompatTest extends LoggerInterfaceTest
+{
+    private $handler;
+
+    public function getLogger()
+    {
+        $logger = new Logger('foo');
+        $logger->pushHandler($handler = new TestHandler);
+        $logger->pushProcessor(new PsrLogMessageProcessor);
+        $handler->setFormatter(new LineFormatter('%level_name% %message%'));
+
+        $this->handler = $handler;
+
+        return $logger;
+    }
+
+    public function getLogs()
+    {
+        $convert = function ($record) {
+            $lower = function ($match) {
+                return strtolower($match[0]);
+            };
+
+            return preg_replace_callback('{^[A-Z]+}', $lower, $record['formatted']);
+        };
+
+        return array_map($convert, $this->handler->getRecords());
+    }
+}