1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-08-09 22:56:41 +02:00

Renamed message to record

This commit is contained in:
Jordi Boggiano
2011-02-25 22:54:01 +01:00
parent efc2bd656b
commit 6c24217c56
16 changed files with 175 additions and 176 deletions

View File

@@ -11,27 +11,27 @@ Usage
$log = new Logger('name');
$log->pushHandler(new FileHandler('path/to/your.log', Logger::WARNING));
// add messages to the log
// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');
Core Concepts
-------------
Every Logger instance has a channel (name) and a stack of handlers. Whenever you add a message to the logger, it traverses the handler stack. Each handler decides whether it handled fully the message, and if so, the propagation of the message ends there.
Every Logger instance has a channel (name) and a stack of handlers. Whenever you add a record to the logger, it traverses the handler stack. Each handler decides whether it handled fully the record, and if so, the propagation of the record ends there.
This allow for flexible logging setups, for example having a FileHandler at the bottom of the stack that will log anything to disk, and on top of that add a MailHandler that will send emails only when an error message is logged. Handlers also have a bubbling property which define whether they block the message or not if they handled it. In this example, setting the MailHandler's $bubble argument to true means that all messages will propagate to the FileHandler, even the errors that are handled by the MailHandler.
This allow for flexible logging setups, for example having a FileHandler at the bottom of the stack that will log anything to disk, and on top of that add a MailHandler that will send emails only when an error message is logged. Handlers also have a bubbling property which define whether they block the record or not if they handled it. In this example, setting the MailHandler's $bubble argument to true means that all records will propagate to the FileHandler, even the errors that are handled by the MailHandler.
You can create many Loggers, each defining a channel (e.g.: db, request, router, ..) and each of them combining various handlers, which can be shared or not. The channel is reflected in the logs and allows you to easily see or filter messages.
You can create many Loggers, each defining a channel (e.g.: db, request, router, ..) and each of them combining various handlers, which can be shared or not. The channel is reflected in the logs and allows you to easily see or filter records.
Each Handler also has a Formatter, a default one with settings that make sense will be created if you don't set one. The formatters normalize and format incoming messages so that they can be used by the handlers to output useful information.
Each Handler also has a Formatter, a default one with settings that make sense will be created if you don't set one. The formatters normalize and format incoming records so that they can be used by the handlers to output useful information.
Custom severity levels are not available. Only four levels (debug, info, warning, error) are present for basic filtering purposes, but for sorting and other use cases that would require flexibility, you should add Processors to the Logger that can add extra information (tags, user ip, ..) to the messages before they are handled.
Custom severity levels are not available. Only four levels (debug, info, warning, error) are present for basic filtering purposes, but for sorting and other use cases that would require flexibility, you should add Processors to the Logger that can add extra information (tags, user ip, ..) to the records before they are handled.
Notable Features (non-exhaustive and incomplete)
------------------------------------------------
- _FingersCrossedHandler_: A very interesting handler. It takes a logger as parameter and will accumulate log messages of all levels until a message exceeds the defined severity level. At which point it delivers all messages, including those of lower severity, to the handler it wraps. This means that until an error actually happens you will not see anything in your logs, but when it happens you will have the full information, including debug and info messages. This provides you with the info you need, only when you need it.
- _FingersCrossedHandler_: A very interesting handler. It takes a logger as parameter and will accumulate log records of all levels until a record exceeds the defined severity level. At which point it delivers all records, including those of lower severity, to the handler it wraps. This means that until an error actually happens you will not see anything in your logs, but when it happens you will have the full information, including debug and info records. This provides you with the info you need, only when you need it.
Todo
----

View File

@@ -18,5 +18,5 @@ namespace Monolog\Formatter;
*/
interface FormatterInterface
{
function format($message);
function format($record);
}

View File

@@ -1,30 +1,30 @@
<?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\Formatter;
use Monolog\Logger;
/**
* Encodes whatever message data is passed to it as json
*
* This can be useful to log to databases or remote APIs
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class JsonFormatter implements FormatterInterface
{
public function format($message)
{
$message['message'] = json_encode($message);
return $message;
}
}
<?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\Formatter;
use Monolog\Logger;
/**
* Encodes whatever record data is passed to it as json
*
* This can be useful to log to databases or remote APIs
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class JsonFormatter implements FormatterInterface
{
public function format($record)
{
$record['message'] = json_encode($record);
return $record;
}
}

View File

@@ -14,7 +14,7 @@ namespace Monolog\Formatter;
use Monolog\Logger;
/**
* Formats incoming messages into a one-line string
* Formats incoming records into a one-line string
*
* This is especially useful for logging to files
*
@@ -34,9 +34,9 @@ class LineFormatter implements FormatterInterface
$this->dateFormat = $dateFormat ?: self::SIMPLE_DATE;
}
public function format($message)
public function format($record)
{
$vars = $message;
$vars = $record;
$vars['datetime'] = $vars['datetime']->format($this->dateFormat);
$output = $this->format;
@@ -55,7 +55,7 @@ class LineFormatter implements FormatterInterface
foreach ($vars['extra'] as $var => $val) {
$output = str_replace('%extra.'.$var.'%', $val, $output);
}
$message['message'] = $output;
return $message;
$record['message'] = $output;
return $record;
}
}

View File

@@ -17,7 +17,7 @@ use Monolog\Formatter\LineFormatter;
/**
* Base Handler class providing the Handler structure
*
* Classes extending it should (in most cases) only implement write($message)
* Classes extending it should (in most cases) only implement write($record)
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
@@ -35,34 +35,33 @@ abstract class AbstractHandler implements HandlerInterface
$this->bubble = $bubble;
}
public function isHandling($message)
public function isHandling($record)
{
return $message['level'] >= $this->level;
return $record['level'] >= $this->level;
}
public function handle($message)
public function handle($record)
{
if ($message['level'] < $this->level) {
if ($record['level'] < $this->level) {
return false;
}
$originalMessage = $message;
if ($this->processors) {
foreach ($this->processors as $processor) {
$message = call_user_func($processor, $message, $this);
$record = call_user_func($processor, $record, $this);
}
}
if (!$this->formatter) {
$this->formatter = $this->getDefaultFormatter();
}
$message = $this->formatter->format($message);
$record = $this->formatter->format($record);
$this->write($message);
$this->write($record);
return false === $this->bubble;
}
abstract public function write($message);
abstract public function write($record);
public function close()
{

View File

@@ -14,11 +14,11 @@ namespace Monolog\Handler;
use Monolog\Logger;
/**
* Buffers all messages until a certain level is reached
* Buffers all records until a certain level is reached
*
* The advantage of this approach is that you don't get any clutter in your log files.
* Only requests which actually trigger an error (or whatever your actionLevel is) will be
* in the logs, but they will contain all messages, not only those above the level threshold.
* in the logs, but they will contain all records, not only those above the level threshold.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
@@ -31,7 +31,7 @@ class FingersCrossedHandler extends AbstractHandler
protected $buffer = array();
/**
* @param callback|HandlerInterface $handler Handler or factory callback($message, $fingersCrossedHandler).
* @param callback|HandlerInterface $handler Handler or factory callback($record, $fingersCrossedHandler).
* @param int $actionLevel The level at which this handler is triggered.
* @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
* @param Boolean $bubble
@@ -45,39 +45,39 @@ class FingersCrossedHandler extends AbstractHandler
}
/**
* Handles a message
* Handles a record
*
* Messages are buffered until one of them matches the actionLevel. From then
* on, unless reset() is called, all messages are passed to the wrapped handler.
* Records are buffered until one of them matches the actionLevel. From then
* on, unless reset() is called, all records are passed to the wrapped handler.
*
* @param array $message Message
* @return Boolean Whether the message was handled
* @param array $record Records
* @return Boolean Whether the record was handled
*/
public function handle($message)
public function handle($record)
{
if ($this->buffering) {
$this->buffer[] = $message;
$this->buffer[] = $record;
if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) {
array_shift($this->buffer);
}
if ($message['level'] >= $this->actionLevel) {
if ($record['level'] >= $this->actionLevel) {
$this->buffering = false;
if (!$this->handler instanceof AbstractHandler) {
$this->handler = $this->handler($message, $this);
$this->handler = $this->handler($record, $this);
}
foreach ($this->buffer as $message) {
$this->handler->handle($message);
foreach ($this->buffer as $record) {
$this->handler->handle($record);
}
$this->buffer = array();
}
} else {
$this->handler->handle($message);
$this->handler->handle($record);
}
return false === $this->bubble;
}
/**
* Resets the state of the handler. Stops forwarding messages to the wrapped handler.
* Resets the state of the handler. Stops forwarding records to the wrapped handler.
*/
public function reset()
{
@@ -87,7 +87,7 @@ class FingersCrossedHandler extends AbstractHandler
/**
* Implemented to comply with the AbstractHandler rqeuirements. Can not be called.
*/
public function write($message)
public function write($record)
{
throw new \LogicException('This method should not be called directly on the FingersCrossedHandler.');
}

View File

@@ -18,7 +18,7 @@ namespace Monolog\Handler;
*/
interface HandlerInterface
{
public function isHandling($message);
public function isHandling($record);
public function handle($message);
public function handle($record);
}

View File

@@ -16,22 +16,22 @@ use Monolog\Logger;
/**
* Blackhole
*
* Any message it can handle will be thrown away. This can be used
* Any record it can handle will be thrown away. This can be used
* to put on top of an existing stack to override it temporarily.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class NullHandler extends AbstractHandler
{
public function handle($message)
public function handle($record)
{
if ($message['level'] < $this->level) {
if ($record['level'] < $this->level) {
return false;
}
return false === $this->bubble;
}
public function write($message)
public function write($record)
{
}
}

View File

@@ -36,7 +36,7 @@ class StreamHandler extends AbstractHandler
}
}
public function write($message)
public function write($record)
{
if (null === $this->stream) {
if (!$this->url) {
@@ -47,7 +47,7 @@ class StreamHandler extends AbstractHandler
throw new \UnexpectedValueException('The stream could not be opened, "'.$this->url.'" may be an invalid url.');
}
}
fwrite($this->stream, (string) $message['message']);
fwrite($this->stream, (string) $record['message']);
}
public function close()

View File

@@ -16,78 +16,78 @@ use Monolog\Logger;
/**
* Used for testing purposes.
*
* It records all messages and gives you access to them for verification.
* It records all records and gives you access to them for verification.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class TestHandler extends AbstractHandler
{
protected $messages;
protected $messagesByLevel;
protected $records;
protected $recordsByLevel;
public function getMessages()
public function getRecords()
{
return $this->messages;
return $this->records;
}
public function hasError($message)
public function hasError($record)
{
return $this->hasMessage($message, Logger::ERROR);
return $this->hasRecord($record, Logger::ERROR);
}
public function hasWarning($message)
public function hasWarning($record)
{
return $this->hasMessage($message, Logger::WARNING);
return $this->hasRecord($record, Logger::WARNING);
}
public function hasInfo($message)
public function hasInfo($record)
{
return $this->hasMessage($message, Logger::INFO);
return $this->hasRecord($record, Logger::INFO);
}
public function hasDebug($message)
public function hasDebug($record)
{
return $this->hasMessage($message, Logger::DEBUG);
return $this->hasRecord($record, Logger::DEBUG);
}
public function hasErrorMessages()
public function hasErrorrecords()
{
return isset($this->messagesByLevel[Logger::ERROR]);
return isset($this->recordsByLevel[Logger::ERROR]);
}
public function hasWarningMessages()
public function hasWarningrecords()
{
return isset($this->messagesByLevel[Logger::WARNING]);
return isset($this->recordsByLevel[Logger::WARNING]);
}
public function hasInfoMessages()
public function hasInforecords()
{
return isset($this->messagesByLevel[Logger::INFO]);
return isset($this->recordsByLevel[Logger::INFO]);
}
public function hasDebugMessages()
public function hasDebugrecords()
{
return isset($this->messagesByLevel[Logger::DEBUG]);
return isset($this->recordsByLevel[Logger::DEBUG]);
}
protected function hasMessage($message, $level = null)
protected function hasRecord($record, $level = null)
{
if (null === $level) {
$messages = $this->messages;
$records = $this->records;
} else {
$messages = $this->messagesByLevel[$level];
$records = $this->recordsByLevel[$level];
}
foreach ($messages as $msg) {
if ($msg['message'] === $message) {
foreach ($records as $msg) {
if ($msg['message'] === $record) {
return true;
}
}
return false;
}
public function write($message)
public function write($record)
{
$this->messagesByLevel[$message['level']][] = $message;
$this->messages[] = $message;
$this->recordsByLevel[$record['level']][] = $record;
$this->records[] = $record;
}
}

View File

@@ -18,7 +18,7 @@ use Monolog\Handler\StreamHandler;
* Monolog log channel
*
* It contains a stack of Handlers and a stack of Processors,
* and uses them to store messages that are added to it.
* and uses them to store records that are added to it.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
@@ -95,13 +95,13 @@ class Logger
return array_shift($this->processors);
}
public function addMessage($level, $message)
public function addRecord($level, $record)
{
if (!$this->handlers) {
$this->pushHandler(new StreamHandler('php://stderr', self::DEBUG));
}
$message = array(
'message' => $message,
$record = array(
'message' => $record,
'level' => $level,
'level_name' => self::getLevelName($level),
'channel' => $this->name,
@@ -111,7 +111,7 @@ class Logger
// check if any message will handle this message
$handlerKey = null;
foreach ($this->handlers as $key => $handler) {
if ($handler->isHandling($message)) {
if ($handler->isHandling($record)) {
$handlerKey = $key;
break;
}
@@ -122,33 +122,33 @@ class Logger
}
// found at least one, process message and dispatch it
foreach ($this->processors as $processor) {
$message = call_user_func($processor, $message, $this);
$record = call_user_func($processor, $record, $this);
}
while (isset($this->handlers[$handlerKey]) &&
false === $this->handlers[$handlerKey]->handle($message)) {
false === $this->handlers[$handlerKey]->handle($record)) {
$handlerKey++;
}
return true;
}
public function addDebug($message)
public function addDebug($record)
{
return $this->addMessage(self::DEBUG, $message);
return $this->addRecord(self::DEBUG, $record);
}
public function addInfo($message)
public function addInfo($record)
{
return $this->addMessage(self::INFO, $message);
return $this->addRecord(self::INFO, $record);
}
public function addWarning($message)
public function addWarning($record)
{
return $this->addMessage(self::WARNING, $message);
return $this->addRecord(self::WARNING, $record);
}
public function addError($message)
public function addError($record)
{
return $this->addMessage(self::ERROR, $message);
return $this->addRecord(self::ERROR, $record);
}
public static function getLevelName($level)
@@ -158,43 +158,43 @@ class Logger
// ZF Logger Compat
public function debug($message)
public function debug($record)
{
return $this->addMessage(self::DEBUG, $message);
return $this->addRecord(self::DEBUG, $record);
}
public function info($message)
public function info($record)
{
return $this->addMessage(self::INFO, $message);
return $this->addRecord(self::INFO, $record);
}
public function notice($message)
public function notice($record)
{
return $this->addMessage(self::INFO, $message);
return $this->addRecord(self::INFO, $record);
}
public function warn($message)
public function warn($record)
{
return $this->addMessage(self::WARNING, $message);
return $this->addRecord(self::WARNING, $record);
}
public function err($message)
public function err($record)
{
return $this->addMessage(self::ERROR, $message);
return $this->addRecord(self::ERROR, $record);
}
public function crit($message)
public function crit($record)
{
return $this->addMessage(self::ERROR, $message);
return $this->addRecord(self::ERROR, $record);
}
public function alert($message)
public function alert($record)
{
return $this->addMessage(self::ERROR, $message);
return $this->addRecord(self::ERROR, $record);
}
public function emerg($message)
public function emerg($record)
{
return $this->addMessage(self::ERROR, $message);
return $this->addRecord(self::ERROR, $record);
}
}

View File

@@ -12,22 +12,22 @@
namespace Monolog\Processor;
/**
* Injects url/method and remote IP of the current web request in all messages
* Injects url/method and remote IP of the current web request in all records
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class WebProcessor
{
public function __invoke($message, $handler)
public function __invoke($record, $handler)
{
$message['extra'] = array_merge(
$message['extra'],
$record['extra'] = array_merge(
$record['extra'],
array(
'url' => $_SERVER['REQUEST_URI'],
'ip' => $_SERVER['REMOTE_ADDR'],
'method' => $_SERVER['REQUEST_METHOD'],
)
);
return $message;
return $record;
}
}

View File

@@ -18,13 +18,13 @@ class JsonFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormat()
{
$formatter = new JsonFormatter();
$message = $formatter->format($msg = array(
$record = $formatter->format($msg = array(
'level_name' => 'WARNING',
'channel' => 'log',
'message' => array('foo'),
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertEquals(json_encode($msg), $message['message']);
$this->assertEquals(json_encode($msg), $record['message']);
}
}

View File

@@ -18,20 +18,20 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase
public function testDefFormatWithString()
{
$formatter = new LineFormatter(null, 'Y-m-d');
$message = $formatter->format(array(
$record = $formatter->format(array(
'level_name' => 'WARNING',
'channel' => 'log',
'message' => 'foo',
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo '."\n", $message['message']);
$this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo '."\n", $record['message']);
}
public function testDefFormatWithArray()
{
$formatter = new LineFormatter(null, 'Y-m-d');
$message = $formatter->format(array(
$record = $formatter->format(array(
'level_name' => 'ERROR',
'channel' => 'meh',
'datetime' => new \DateTime,
@@ -41,19 +41,19 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase
'baz' => 'qux',
)
));
$this->assertEquals('['.date('Y-m-d').'] meh.ERROR: message(foo: bar, baz: qux) '."\n", $message['message']);
$this->assertEquals('['.date('Y-m-d').'] meh.ERROR: message(foo: bar, baz: qux) '."\n", $record['message']);
}
public function testDefFormatExtras()
{
$formatter = new LineFormatter(null, 'Y-m-d');
$message = $formatter->format(array(
$record = $formatter->format(array(
'level_name' => 'ERROR',
'channel' => 'meh',
'datetime' => new \DateTime,
'extra' => array('ip' => '127.0.0.1'),
'message' => 'log',
));
$this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log extra(ip: 127.0.0.1)'."\n", $message['message']);
$this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log extra(ip: 127.0.0.1)'."\n", $record['message']);
}
}

View File

@@ -19,45 +19,45 @@ class FingersCrossedHandlerTest extends \PHPUnit_Framework_TestCase
{
$test = new TestHandler();
$handler = new FingersCrossedHandler($test);
$handler->handle($this->getMessage(Logger::DEBUG));
$handler->handle($this->getMessage(Logger::INFO));
$this->assertFalse($test->hasDebugMessages());
$this->assertFalse($test->hasInfoMessages());
$handler->handle($this->getMessage(Logger::WARNING));
$this->assertTrue($test->hasInfoMessages());
$this->assertTrue(count($test->getMessages()) === 3);
$handler->handle($this->getRecord(Logger::DEBUG));
$handler->handle($this->getRecord(Logger::INFO));
$this->assertFalse($test->hasDebugRecords());
$this->assertFalse($test->hasInfoRecords());
$handler->handle($this->getRecord(Logger::WARNING));
$this->assertTrue($test->hasInfoRecords());
$this->assertTrue(count($test->getRecords()) === 3);
}
public function testHandleStopsBufferingAfterTrigger()
{
$test = new TestHandler();
$handler = new FingersCrossedHandler($test);
$handler->handle($this->getMessage(Logger::WARNING));
$handler->handle($this->getMessage(Logger::DEBUG));
$this->assertTrue($test->hasWarningMessages());
$this->assertTrue($test->hasDebugMessages());
$handler->handle($this->getRecord(Logger::WARNING));
$handler->handle($this->getRecord(Logger::DEBUG));
$this->assertTrue($test->hasWarningRecords());
$this->assertTrue($test->hasDebugRecords());
}
public function testHandleBufferLimit()
{
$test = new TestHandler();
$handler = new FingersCrossedHandler($test, Logger::WARNING, 2);
$handler->handle($this->getMessage(Logger::DEBUG));
$handler->handle($this->getMessage(Logger::DEBUG));
$handler->handle($this->getMessage(Logger::INFO));
$handler->handle($this->getMessage(Logger::WARNING));
$this->assertTrue($test->hasWarningMessages());
$this->assertTrue($test->hasInfoMessages());
$this->assertFalse($test->hasDebugMessages());
$handler->handle($this->getRecord(Logger::DEBUG));
$handler->handle($this->getRecord(Logger::DEBUG));
$handler->handle($this->getRecord(Logger::INFO));
$handler->handle($this->getRecord(Logger::WARNING));
$this->assertTrue($test->hasWarningRecords());
$this->assertTrue($test->hasInfoRecords());
$this->assertFalse($test->hasDebugRecords());
}
protected function getMessage($level = Logger::WARNING)
protected function getRecord($level = Logger::WARNING)
{
return array(
'level' => $level,
'level_name' => Logger::getLevelName($level),
'channel' => 'log',
'message' => 'foo',
'Record' => 'foo',
'datetime' => new \DateTime,
'extra' => array(),
);

View File

@@ -18,13 +18,13 @@ class NullHandlerTest extends \PHPUnit_Framework_TestCase
public function testHandle()
{
$handler = new NullHandler();
$this->assertTrue($handler->handle($this->getMessage()));
$this->assertTrue($handler->handle($this->getRecord()));
}
public function testHandleLowerLevelMessage()
public function testHandleLowerLevelRecord()
{
$handler = new NullHandler(Logger::WARNING);
$this->assertFalse($handler->handle($this->getMessage(Logger::DEBUG)));
$this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
}
/**
@@ -33,10 +33,10 @@ class NullHandlerTest extends \PHPUnit_Framework_TestCase
public function testWrite()
{
$handler = new NullHandler();
$handler->write($this->getMessage());
$handler->write($this->getRecord());
}
protected function getMessage($level = Logger::WARNING)
protected function getRecord($level = Logger::WARNING)
{
return array(
'level' => $level,