mirror of
https://github.com/Seldaek/monolog.git
synced 2025-07-29 17:30:14 +02:00
Major refactoring to follow the Logbook model
This commit is contained in:
31
README.mdown
31
README.mdown
@@ -5,28 +5,20 @@ Usage
|
||||
-----
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Log;
|
||||
use Monolog\Writer\FileWriter;
|
||||
use Monolog\Formatter\SimpleFormatter;
|
||||
use Monolog\Handler\FileHandler;
|
||||
|
||||
// create a log with writers/formatters
|
||||
$writer = new FileWriter('path/to/your.log');
|
||||
$writer->setFormatter(new SimpleFormatter());
|
||||
$log = new Log('name', Logger::WARN, $writer);
|
||||
// create a log channel
|
||||
$log = new Logger('name');
|
||||
$log->pushHandler(new FileHandler('path/to/your.log', Logger::WARNING));
|
||||
|
||||
// create a logger with one or more logs
|
||||
$logger = new Logger(array($log));
|
||||
|
||||
// write to all logs
|
||||
$logger->addWarning('Foo');
|
||||
|
||||
// write only to the 'name' log
|
||||
$logger->addError('Bar', 'name');
|
||||
// add messages to the log
|
||||
$log->addWarning('Foo');
|
||||
$log->addError('Bar');
|
||||
|
||||
Todo
|
||||
----
|
||||
|
||||
- Log rotation for FileWriter
|
||||
- Log rotation for RotatingFileHandler
|
||||
- FirePHP writer
|
||||
- Syslog writer
|
||||
|
||||
@@ -43,4 +35,9 @@ Monolog is licensed under the MIT License - see the LICENSE file for details
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any flavor of PHP5.3 should do
|
||||
Any flavor of PHP 5.3 should do
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
|
||||
This library is heavily inspired by Python's Logbook library, although it has been adapted to fit in PHP.
|
||||
|
@@ -13,5 +13,5 @@ namespace Monolog\Formatter;
|
||||
|
||||
interface FormatterInterface
|
||||
{
|
||||
function format($log, $message);
|
||||
function format($message);
|
||||
}
|
||||
|
23
src/Monolog/Formatter/JsonFormatter.php
Normal file
23
src/Monolog/Formatter/JsonFormatter.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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;
|
||||
|
||||
class JsonFormatter implements FormatterInterface
|
||||
{
|
||||
public function format($message)
|
||||
{
|
||||
$message['message'] = json_encode($message['message']);
|
||||
return $message;
|
||||
}
|
||||
}
|
@@ -13,9 +13,9 @@ namespace Monolog\Formatter;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class SimpleFormatter implements FormatterInterface
|
||||
class LineFormatter implements FormatterInterface
|
||||
{
|
||||
const SIMPLE_FORMAT = "[%date%] %log%.%level%: %message%\n";
|
||||
const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message%\n";
|
||||
const SIMPLE_DATE = "Y-m-d H:i:s";
|
||||
|
||||
protected $format;
|
||||
@@ -27,25 +27,26 @@ class SimpleFormatter implements FormatterInterface
|
||||
$this->dateFormat = $dateFormat ?: self::SIMPLE_DATE;
|
||||
}
|
||||
|
||||
public function format($log, $message)
|
||||
public function format($message)
|
||||
{
|
||||
$defaults = array(
|
||||
'log' => $log,
|
||||
'level' => Logger::getLevelName($message['level']),
|
||||
'date' => date($this->dateFormat),
|
||||
);
|
||||
$vars = $message;
|
||||
$vars['datetime'] = $vars['datetime']->format($this->dateFormat);
|
||||
|
||||
if (is_array($message['message'])) {
|
||||
$vars = array_merge($defaults, $message['message']);
|
||||
} else {
|
||||
$vars = $defaults;
|
||||
$vars['message'] = $message['message'];
|
||||
unset($vars['message']);
|
||||
$vars = array_merge($vars, $message['message']);
|
||||
}
|
||||
|
||||
$message = $this->format;
|
||||
$output = $this->format;
|
||||
foreach ($vars as $var => $val) {
|
||||
$message = str_replace('%'.$var.'%', $val, $message);
|
||||
if (!is_array($val)) {
|
||||
$output = str_replace('%'.$var.'%', $val, $output);
|
||||
}
|
||||
}
|
||||
foreach ($vars['extra'] as $var => $val) {
|
||||
$output = str_replace('%extra.'.$var.'%', $val, $output);
|
||||
}
|
||||
$message['message'] = $output;
|
||||
return $message;
|
||||
}
|
||||
}
|
121
src/Monolog/Handler/AbstractHandler.php
Normal file
121
src/Monolog/Handler/AbstractHandler.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?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\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
|
||||
abstract class AbstractHandler implements HandlerInterface
|
||||
{
|
||||
protected $level;
|
||||
protected $bubble;
|
||||
protected $parent;
|
||||
|
||||
protected $formatter;
|
||||
protected $processor;
|
||||
|
||||
public function __construct($level = Logger::DEBUG, $bubble = false)
|
||||
{
|
||||
$this->level = $level;
|
||||
$this->bubble = $bubble;
|
||||
}
|
||||
|
||||
public function handle($message)
|
||||
{
|
||||
if ($message['level'] < $this->level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->processor) {
|
||||
$message = call_user_func($this->processor, $message, $this);
|
||||
}
|
||||
|
||||
if (!$this->formatter) {
|
||||
$this->formatter = $this->getDefaultFormatter();
|
||||
}
|
||||
$message = $this->formatter->format($message);
|
||||
|
||||
$this->write($message);
|
||||
return false === $this->bubble;
|
||||
}
|
||||
|
||||
abstract public function write($message);
|
||||
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
public function setProcessor($callback)
|
||||
{
|
||||
$this->processor = $callback;
|
||||
}
|
||||
|
||||
public function getProcessor()
|
||||
{
|
||||
return $this->processor;
|
||||
}
|
||||
|
||||
public function setFormatter($formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
public function getFormatter()
|
||||
{
|
||||
return $this->formatter;
|
||||
}
|
||||
|
||||
public function setLevel($level)
|
||||
{
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
public function getLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
public function setBubble($bubble)
|
||||
{
|
||||
$this->bubble = $bubble;
|
||||
}
|
||||
|
||||
public function getBubble()
|
||||
{
|
||||
return $this->bubble;
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent handler
|
||||
*
|
||||
* @param Monolog\Handler\HandlerInterface
|
||||
*/
|
||||
public function setParent(HandlerInterface $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new LineFormatter();
|
||||
}
|
||||
}
|
29
src/Monolog/Handler/HandlerInterface.php
Normal file
29
src/Monolog/Handler/HandlerInterface.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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\Handler;
|
||||
|
||||
interface HandlerInterface
|
||||
{
|
||||
public function handle($message);
|
||||
|
||||
public function setLevel($level);
|
||||
|
||||
public function getLevel();
|
||||
|
||||
public function setBubble($bubble);
|
||||
|
||||
public function getBubble();
|
||||
|
||||
public function getParent();
|
||||
|
||||
public function setParent(HandlerInterface $parent);
|
||||
}
|
29
src/Monolog/Handler/NullHandler.php
Normal file
29
src/Monolog/Handler/NullHandler.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class NullHandler extends AbstractHandler
|
||||
{
|
||||
public function handle($message)
|
||||
{
|
||||
if ($message['level'] < $this->level) {
|
||||
return false;
|
||||
}
|
||||
return false === $this->bubble;
|
||||
}
|
||||
|
||||
public function write($message)
|
||||
{
|
||||
}
|
||||
}
|
@@ -9,20 +9,13 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Monolog\Writer;
|
||||
namespace Monolog\Handler;
|
||||
|
||||
class FileWriter extends StreamWriter
|
||||
class RotatingFileHandler extends StreamHandler
|
||||
{
|
||||
protected $rotation;
|
||||
protected $maxAge;
|
||||
|
||||
public function __construct($file, $rotation = null, $maxAge = null)
|
||||
{
|
||||
parent::__construct($file);
|
||||
$this->rotation = $rotation;
|
||||
$this->maxAge = $maxAge;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
parent::close();
|
53
src/Monolog/Handler/StreamHandler.php
Normal file
53
src/Monolog/Handler/StreamHandler.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?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\Handler;
|
||||
|
||||
use Monolog\Formatter\SimpleFormatter;
|
||||
use Monolog\Logger;
|
||||
|
||||
class StreamHandler extends AbstractHandler
|
||||
{
|
||||
protected $stream;
|
||||
protected $url;
|
||||
|
||||
public function __construct($stream, $level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
if (is_resource($stream)) {
|
||||
$this->stream = $stream;
|
||||
} else {
|
||||
$this->url = $stream;
|
||||
}
|
||||
}
|
||||
|
||||
public function write($message)
|
||||
{
|
||||
if (null === $this->stream) {
|
||||
if (!$this->url) {
|
||||
throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
|
||||
}
|
||||
$this->stream = fopen($this->url, 'a');
|
||||
if (!is_resource($this->stream)) {
|
||||
throw new \UnexpectedValueException('The stream could not be opened, "'.$this->url.'" may be an invalid url.');
|
||||
}
|
||||
}
|
||||
fwrite($this->stream, (string) $message['message']);
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
if (null !== $this->stream) {
|
||||
fclose($this->stream);
|
||||
$this->stream = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
<?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\Writer\WriterInterface;
|
||||
|
||||
class Log
|
||||
{
|
||||
protected $level;
|
||||
protected $name;
|
||||
protected $writers;
|
||||
|
||||
public function __construct($name, $level = Logger::WARNING, $writers = array())
|
||||
{
|
||||
$this->name = $name;
|
||||
// TODO move level down to the writers
|
||||
$this->level = $level;
|
||||
$this->writers = is_array($writers) ? $writers : array($writers);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addWriter(WriterInterface $writer)
|
||||
{
|
||||
$this->writers[] = $writer;
|
||||
}
|
||||
|
||||
public function addMessage($level, $message)
|
||||
{
|
||||
if ($level < $this->level) {
|
||||
return;
|
||||
}
|
||||
foreach ($this->writers as $writer) {
|
||||
$writer->write($this->name, $level, $message);
|
||||
}
|
||||
}
|
||||
|
||||
public function setLevel($level)
|
||||
{
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
public function getLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
}
|
@@ -11,6 +11,9 @@
|
||||
|
||||
namespace Monolog;
|
||||
|
||||
use Monolog\Handler\HandlerInterface;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
|
||||
class Logger
|
||||
{
|
||||
/**
|
||||
@@ -42,104 +45,124 @@ class Logger
|
||||
400 => 'ERROR',
|
||||
);
|
||||
|
||||
protected $logs;
|
||||
protected $name;
|
||||
|
||||
public function __construct($logs = array())
|
||||
/**
|
||||
* The handler instance at the top of the handler stack
|
||||
*
|
||||
* @var Monolog\Handler\HandlerInterface
|
||||
*/
|
||||
protected $handler;
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->logs = array();
|
||||
if (!is_array($logs)) {
|
||||
$logs = array($logs);
|
||||
}
|
||||
foreach ($logs as $log) {
|
||||
$this->logs[$log->getName()] = $log;
|
||||
}
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function addLog(Log $log)
|
||||
public function pushHandler(HandlerInterface $handler)
|
||||
{
|
||||
$this->logs[$log->getName()] = $log;
|
||||
if ($this->handler) {
|
||||
$handler->setParent($this->handler);
|
||||
}
|
||||
$this->handler = $handler;
|
||||
}
|
||||
|
||||
public function addMessage($level, $message, $log = null)
|
||||
public function popHandler()
|
||||
{
|
||||
if (null === $this->handler) {
|
||||
throw new \LogicException('You tried to pop from an empty handler stack.');
|
||||
}
|
||||
$top = $this->handler;
|
||||
$this->handler = $top->getParent();
|
||||
return $top;
|
||||
}
|
||||
|
||||
public function addMessage($level, $message)
|
||||
{
|
||||
if (null === $this->handler) {
|
||||
$this->pushHandler(new StreamHandler('php://stderr', self::DEBUG));
|
||||
}
|
||||
$message = array(
|
||||
'message' => $message,
|
||||
'level' => $level,
|
||||
'level_name' => $this->getLevelName($level),
|
||||
'channel' => $this->name,
|
||||
'datetime' => new \DateTime(),
|
||||
'extra' => array(),
|
||||
);
|
||||
if (null === $log) {
|
||||
$logs = $this->logs;
|
||||
} else {
|
||||
$logs = is_array($log) ? array_flip($log) : array($log => true);
|
||||
}
|
||||
foreach ($logs as $log => $dummy) {
|
||||
$this->logs[$log]->log($level, $message);
|
||||
$handled = false;
|
||||
$handler = $this->handler;
|
||||
while ($handler && true !== $handled) {
|
||||
$handled = (bool) $handler->handle($message);
|
||||
$handler = $handler->getParent();
|
||||
}
|
||||
return $handled;
|
||||
}
|
||||
|
||||
public function addDebug($message, $log = null)
|
||||
public function addDebug($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::DEBUG, $message, $log);
|
||||
$this->addMessage(self::DEBUG, $message, $channel);
|
||||
}
|
||||
|
||||
public function addInfo($message, $log = null)
|
||||
public function addInfo($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::INFO, $message, $log);
|
||||
$this->addMessage(self::INFO, $message, $channel);
|
||||
}
|
||||
|
||||
public function addWarning($message, $log = null)
|
||||
public function addWarning($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::WARNING, $message, $log);
|
||||
$this->addMessage(self::WARNING, $message, $channel);
|
||||
}
|
||||
|
||||
public function addError($message, $log = null)
|
||||
public function addError($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::ERROR, $message, $log);
|
||||
$this->addMessage(self::ERROR, $message, $channel);
|
||||
}
|
||||
|
||||
public static function getLevelName($level)
|
||||
public function getLevelName($level)
|
||||
{
|
||||
return self::$levels[$level];
|
||||
}
|
||||
|
||||
// ZF Logger Compat
|
||||
|
||||
public function debug($message, $log = null)
|
||||
public function debug($message, $channel = null)
|
||||
{
|
||||
$this->addMessage(self::DEBUG, $message, $log);
|
||||
$this->addMessage(self::DEBUG, $message, $channel);
|
||||
}
|
||||
|
||||
public function info($message, $log = null)
|
||||
public function info($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::INFO, $message, $log);
|
||||
$this->addMessage(self::INFO, $message, $channel);
|
||||
}
|
||||
|
||||
public function notice($message, $log = null)
|
||||
public function notice($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::INFO, $message, $log);
|
||||
$this->addMessage(self::INFO, $message, $channel);
|
||||
}
|
||||
|
||||
public function warn($message, $log = null)
|
||||
public function warn($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::WARNING, $message, $log);
|
||||
$this->addMessage(self::WARNING, $message, $channel);
|
||||
}
|
||||
|
||||
public function err($message, $log = null)
|
||||
public function err($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::ERROR, $message, $log);
|
||||
$this->addMessage(self::ERROR, $message, $channel);
|
||||
}
|
||||
|
||||
public function crit($message, $log = null)
|
||||
public function crit($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::ERROR, $message, $log);
|
||||
$this->addMessage(self::ERROR, $message, $channel);
|
||||
}
|
||||
|
||||
public function alert($message, $log = null)
|
||||
public function alert($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::ERROR, $message, $log);
|
||||
$this->addMessage(self::ERROR, $message, $channel);
|
||||
}
|
||||
|
||||
public function emerg($message, $log = null)
|
||||
public function emerg($message, $channel = 'default')
|
||||
{
|
||||
$this->addMessage(self::ERROR, $message, $log);
|
||||
$this->addMessage(self::ERROR, $message, $channel);
|
||||
}
|
||||
}
|
28
src/Monolog/Processor/WebProcessor.php
Normal file
28
src/Monolog/Processor/WebProcessor.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?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;
|
||||
|
||||
class WebProcessor
|
||||
{
|
||||
public function __invoke($message, $handler)
|
||||
{
|
||||
$message['extra'] = array_merge(
|
||||
$message['extra'],
|
||||
array(
|
||||
'url' => $_SERVER['REQUEST_URI'],
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
'method' => $_SERVER['REQUEST_METHOD'],
|
||||
)
|
||||
);
|
||||
return $message;
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?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\Writer;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
|
||||
class NullWriter implements WriterInterface
|
||||
{
|
||||
public function write($log, $message)
|
||||
{
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
public function setFormatter(FormatterInterface $formatter)
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
<?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\Writer;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
|
||||
class StreamWriter implements WriterInterface
|
||||
{
|
||||
protected $formatter;
|
||||
protected $stream;
|
||||
protected $url;
|
||||
|
||||
public function __construct($streamUrl)
|
||||
{
|
||||
if (is_resource($streamUrl)) {
|
||||
$this->stream = $streamUrl;
|
||||
} else {
|
||||
$this->url = $streamUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public function write($log, $message)
|
||||
{
|
||||
if (null === $this->stream) {
|
||||
$this->stream = fopen($this->url, 'a');
|
||||
}
|
||||
if ($this->formatter) {
|
||||
$message = $this->formatter->format($log, $message);
|
||||
}
|
||||
fwrite($this->stream, (string) $message['message']);
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
fclose($this->stream);
|
||||
$this->stream = null;
|
||||
}
|
||||
|
||||
public function setFormatter(FormatterInterface $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (null !== $this->stream) {
|
||||
$this->close();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
<?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\Writer;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
|
||||
interface WriterInterface
|
||||
{
|
||||
function setFormatter(FormatterInterface $formatter);
|
||||
function write($log, $message);
|
||||
function close();
|
||||
}
|
30
tests/Monolog/Formatter/JsonFormatterTest.php
Normal file
30
tests/Monolog/Formatter/JsonFormatterTest.php
Normal file
@@ -0,0 +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;
|
||||
|
||||
class JsonFormatterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testFormat()
|
||||
{
|
||||
$formatter = new JsonFormatter();
|
||||
$message = $formatter->format(array(
|
||||
'level_name' => 'WARNING',
|
||||
'channel' => 'log',
|
||||
'message' => array('foo'),
|
||||
'datetime' => new \DateTime,
|
||||
'extra' => array(),
|
||||
));
|
||||
$this->assertEquals(json_encode(array('foo')), $message['message']);
|
||||
}
|
||||
}
|
47
tests/Monolog/Formatter/LineFormatterTest.php
Normal file
47
tests/Monolog/Formatter/LineFormatterTest.php
Normal file
@@ -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\Formatter;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class LineFormatterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testDefFormatWithString()
|
||||
{
|
||||
$formatter = new LineFormatter(null, 'Y-m-d');
|
||||
$message = $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']);
|
||||
}
|
||||
|
||||
public function testDefFormatWithArray()
|
||||
{
|
||||
$formatter = new LineFormatter(null, 'Y-m-d');
|
||||
$message = $formatter->format(array(
|
||||
'level_name' => 'ERROR',
|
||||
'channel' => 'meh',
|
||||
'datetime' => new \DateTime,
|
||||
'extra' => array(),
|
||||
'message' => array(
|
||||
'channel' => 'log',
|
||||
'level_name' => 'WARNING',
|
||||
'message' => 'foo',
|
||||
)
|
||||
));
|
||||
$this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo'."\n", $message['message']);
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?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;
|
||||
|
||||
class SimpleFormatterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testDefFormatWithString()
|
||||
{
|
||||
$formatter = new SimpleFormatter(null, 'Y-m-d');
|
||||
$message = $formatter->format('log', array('level' => Logger::WARNING, 'message' => 'foo'));
|
||||
$this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo'."\n", $message);
|
||||
}
|
||||
|
||||
public function testDefFormatWithArray()
|
||||
{
|
||||
$formatter = new SimpleFormatter(null, 'Y-m-d');
|
||||
$message = $formatter->format('xx', array(
|
||||
'level' => Logger::ERROR,
|
||||
'message' => array(
|
||||
'log' => 'log',
|
||||
'level' => 'WARNING',
|
||||
'message' => 'foo',
|
||||
)
|
||||
));
|
||||
$this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo'."\n", $message);
|
||||
}
|
||||
}
|
54
tests/Monolog/Handler/AbstractHandlerTest.php
Normal file
54
tests/Monolog/Handler/AbstractHandlerTest.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?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\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class AbstractHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testHandle()
|
||||
{
|
||||
$handler = new TestHandler();
|
||||
$this->assertTrue($handler->handle($this->getMessage()));
|
||||
}
|
||||
|
||||
public function testHandleLowerLevelMessage()
|
||||
{
|
||||
$handler = new TestHandler();
|
||||
$this->assertFalse($handler->handle($this->getMessage(Logger::DEBUG)));
|
||||
}
|
||||
|
||||
public function testHandleBubbling()
|
||||
{
|
||||
$handler = new TestHandler(Logger::DEBUG, true);
|
||||
$this->assertFalse($handler->handle($this->getMessage()));
|
||||
}
|
||||
|
||||
protected function getMessage($level = Logger::WARNING)
|
||||
{
|
||||
return array(
|
||||
'level' => $level,
|
||||
'level_name' => 'WARNING',
|
||||
'channel' => 'log',
|
||||
'message' => 'foo',
|
||||
'datetime' => new \DateTime,
|
||||
'extra' => array(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TestHandler extends AbstractHandler
|
||||
{
|
||||
public function write($message)
|
||||
{
|
||||
}
|
||||
}
|
51
tests/Monolog/Handler/NullHandlerTest.php
Normal file
51
tests/Monolog/Handler/NullHandlerTest.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?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\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class NullHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testHandle()
|
||||
{
|
||||
$handler = new NullHandler();
|
||||
$this->assertTrue($handler->handle($this->getMessage()));
|
||||
}
|
||||
|
||||
public function testHandleLowerLevelMessage()
|
||||
{
|
||||
$handler = new NullHandler(Logger::WARNING);
|
||||
$this->assertFalse($handler->handle($this->getMessage(Logger::DEBUG)));
|
||||
}
|
||||
|
||||
public function testHandleBubbling()
|
||||
{
|
||||
$handler = new NullHandler(Logger::DEBUG, true);
|
||||
$this->assertFalse($handler->handle($this->getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* No-op test for coverage
|
||||
*/
|
||||
public function testWrite()
|
||||
{
|
||||
$handler = new NullHandler();
|
||||
$handler->write($this->getMessage());
|
||||
}
|
||||
|
||||
protected function getMessage($level = Logger::WARNING)
|
||||
{
|
||||
return array(
|
||||
'level' => $level,
|
||||
);
|
||||
}
|
||||
}
|
61
tests/Monolog/Handler/StreamHandlerTest.php
Normal file
61
tests/Monolog/Handler/StreamHandlerTest.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?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\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class StreamHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testWrite()
|
||||
{
|
||||
$handle = fopen('php://memory', 'a+');
|
||||
$handler = new StreamHandler($handle);
|
||||
$handler->write(array('message' => 'test'));
|
||||
$handler->write(array('message' => 'test2'));
|
||||
$handler->write(array('message' => 'test3'));
|
||||
fseek($handle, 0);
|
||||
$this->assertEquals('testtest2test3', fread($handle, 100));
|
||||
}
|
||||
|
||||
public function testClose()
|
||||
{
|
||||
$handle = fopen('php://memory', 'a+');
|
||||
$handler = new StreamHandler($handle);
|
||||
$this->assertTrue(is_resource($handle));
|
||||
$handler->close();
|
||||
$this->assertFalse(is_resource($handle));
|
||||
}
|
||||
|
||||
public function testWriteCreatesTheStreamResource()
|
||||
{
|
||||
$handler = new StreamHandler('php://memory');
|
||||
$handler->write(array('message' => 'test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testWriteMissingResource()
|
||||
{
|
||||
$handler = new StreamHandler(null);
|
||||
$handler->write(array('message' => 'test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException UnexpectedValueException
|
||||
*/
|
||||
public function testWriteInvalidResource()
|
||||
{
|
||||
$handler = new StreamHandler('bogus://url');
|
||||
@$handler->write(array('message' => 'test'));
|
||||
}
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
<?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;
|
||||
|
||||
class LogTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testLog()
|
||||
{
|
||||
$logger = new Log('bob');
|
||||
$writer1 = $this->getMock('Monolog\Writer\NullWriter', array('write'));
|
||||
$writer1->expects($this->once())
|
||||
->method('write')
|
||||
->with('bob', Logger::WARNING, 'test');
|
||||
$writer2 = $this->getMock('Monolog\Writer\NullWriter', array('write'));
|
||||
$writer2->expects($this->once())
|
||||
->method('write')
|
||||
->with('bob', Logger::WARNING, 'test');
|
||||
$logger->addWriter($writer1);
|
||||
$logger->addWriter($writer2);
|
||||
$logger->addMessage(Logger::WARNING, 'test');
|
||||
}
|
||||
|
||||
public function testLogLowLevel()
|
||||
{
|
||||
$logger = new Log('bob');
|
||||
$logger->setLevel(Logger::ERROR);
|
||||
$this->assertEquals(Logger::ERROR, $logger->getLevel());
|
||||
|
||||
$writer1 = $this->getMock('Monolog\Writer\NullWriter', array('write'));
|
||||
$writer1->expects($this->never())
|
||||
->method('write');
|
||||
$logger->addWriter($writer1);
|
||||
$logger->addMessage(Logger::WARNING, 'test');
|
||||
}
|
||||
}
|
@@ -13,33 +13,57 @@ namespace Monolog;
|
||||
|
||||
class LoggerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testLogAll()
|
||||
public function testLog()
|
||||
{
|
||||
$logger = new Logger();
|
||||
$log1 = $this->getMock('Monolog\Log', array('log'), array('a'));
|
||||
$log1->expects($this->once())
|
||||
->method('log');
|
||||
$log2 = $this->getMock('Monolog\Log', array('log'), array('b'));
|
||||
$log2->expects($this->once())
|
||||
->method('log');
|
||||
$logger->addLog($log1);
|
||||
$logger->addLog($log2);
|
||||
$logger->warn('test');
|
||||
$logger = new Logger(__METHOD__);
|
||||
|
||||
$handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
|
||||
$handler->expects($this->once())
|
||||
->method('handle');
|
||||
$logger->pushHandler($handler);
|
||||
|
||||
$logger->addWarning('test');
|
||||
}
|
||||
|
||||
public function testLogFiltered()
|
||||
/**
|
||||
* @dataProvider logValues
|
||||
*/
|
||||
public function testLogUntilHandled($bubble)
|
||||
{
|
||||
$logger = new Logger();
|
||||
$log1 = $this->getMock('Monolog\Log', array('log'), array('a'));
|
||||
$log1->expects($this->exactly(2))
|
||||
->method('log');
|
||||
$log2 = $this->getMock('Monolog\Log', array('log'), array('b'));
|
||||
$log2->expects($this->never())
|
||||
->method('log');
|
||||
$logger->addLog($log1);
|
||||
$logger->addLog($log2);
|
||||
$logger = new Logger(__METHOD__);
|
||||
|
||||
$logger->warn('test', 'a');
|
||||
$logger->warn('test', array('a'));
|
||||
$bottomHandler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
|
||||
$bottomHandler->expects($bubble ? $this->once() : $this->never())
|
||||
->method('handle');
|
||||
$logger->pushHandler($bottomHandler);
|
||||
|
||||
$topHandler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
|
||||
$topHandler->expects($this->once())
|
||||
->method('handle')
|
||||
->will($this->returnValue(!$bubble));
|
||||
$logger->pushHandler($topHandler);
|
||||
|
||||
$logger->addWarning('test');
|
||||
}
|
||||
|
||||
public function logValues()
|
||||
{
|
||||
return array(array(true), array(false));
|
||||
}
|
||||
|
||||
public function testPushPopHandler()
|
||||
{
|
||||
$logger = new Logger(__METHOD__);
|
||||
$handler1 = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
|
||||
$handler2 = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
|
||||
$handler3 = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
|
||||
|
||||
$logger->pushHandler($handler1);
|
||||
$logger->pushHandler($handler2);
|
||||
$logger->pushHandler($handler3);
|
||||
|
||||
$this->assertEquals($handler3, $logger->popHandler());
|
||||
$this->assertEquals($handler2, $logger->popHandler());
|
||||
$this->assertEquals($handler1, $logger->popHandler());
|
||||
}
|
||||
}
|
||||
|
@@ -1,37 +0,0 @@
|
||||
<?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\Writer;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class StreamWritterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testWrite()
|
||||
{
|
||||
$handle = fopen('php://memory', 'a+');
|
||||
$writer = new StreamWriter($handle);
|
||||
$writer->write('log', array('level' => Logger::WARNING, 'message' => 'test'));
|
||||
$writer->write('log', array('level' => Logger::WARNING, 'message' => 'test2'));
|
||||
$writer->write('log', array('level' => Logger::WARNING, 'message' => 'test3'));
|
||||
fseek($handle, 0);
|
||||
$this->assertEquals('testtest2test3', fread($handle, 100));
|
||||
}
|
||||
|
||||
public function testClose()
|
||||
{
|
||||
$handle = fopen('php://memory', 'a+');
|
||||
$writer = new StreamWriter($handle);
|
||||
$this->assertTrue(is_resource($handle));
|
||||
$writer->close();
|
||||
$this->assertFalse(is_resource($handle));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user