mirror of
https://github.com/Seldaek/monolog.git
synced 2025-08-24 13:52:53 +02:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,5 +2,4 @@ vendor
|
|||||||
composer.phar
|
composer.phar
|
||||||
phpunit.xml
|
phpunit.xml
|
||||||
composer.lock
|
composer.lock
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
@@ -1,3 +1,25 @@
|
|||||||
|
* 1.2.1 (2012-08-29)
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
* Added new $logopts arg to SyslogHandler to provide custom openlog options
|
||||||
|
* Fixed fatal error in SyslogHandler
|
||||||
|
|
||||||
|
* 1.2.0 (2012-08-18)
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
* Added AmqpHandler (for use with AMQP servers)
|
||||||
|
* Added CubeHandler
|
||||||
|
* Added NativeMailerHandler::addHeader() to send custom headers in mails
|
||||||
|
* Added the possibility to specify more than one recipient in NativeMailerHandler
|
||||||
|
* Added the possibility to specify float timeouts in SocketHandler
|
||||||
|
* Added NOTICE and EMERGENCY levels to conform with RFC 5424
|
||||||
|
* Fixed the log records to use the php default timezone instead of UTC
|
||||||
|
* Fixed BufferHandler not being flushed properly on PHP fatal errors
|
||||||
|
* Fixed normalization of exotic resource types
|
||||||
|
* Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog
|
||||||
|
|
||||||
* 1.1.0 (2012-04-23)
|
* 1.1.0 (2012-04-23)
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
@@ -113,6 +113,7 @@ Handlers
|
|||||||
for UNIX and TCP sockets. See an [example](https://github.com/Seldaek/monolog/blob/master/doc/sockets.md).
|
for UNIX and TCP sockets. See an [example](https://github.com/Seldaek/monolog/blob/master/doc/sockets.md).
|
||||||
- _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible
|
- _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible
|
||||||
server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+).
|
server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+).
|
||||||
|
- _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server.
|
||||||
|
|
||||||
Wrappers / Special Handlers
|
Wrappers / Special Handlers
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"description": "Logging for PHP 5.3",
|
"description": "Logging for PHP 5.3",
|
||||||
"keywords": ["log","logging"],
|
"keywords": ["log", "logging"],
|
||||||
"homepage": "http://github.com/Seldaek/monolog",
|
"homepage": "http://github.com/Seldaek/monolog",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -25,5 +25,10 @@
|
|||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {"Monolog": "src/"}
|
"psr-0": {"Monolog": "src/"}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.3.x-dev"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
doc/usage.md
44
doc/usage.md
@@ -94,12 +94,11 @@ Leveraging channels
|
|||||||
|
|
||||||
Channels are a great way to identify to which part of the application a record
|
Channels are a great way to identify to which part of the application a record
|
||||||
is related. This is useful in big applications (and is leveraged by
|
is related. This is useful in big applications (and is leveraged by
|
||||||
MonologBundle in Symfony2). You can then easily grep through log files for
|
MonologBundle in Symfony2).
|
||||||
example to filter this or that type of log record.
|
|
||||||
|
|
||||||
Using different loggers with the same handlers allow to identify the logger
|
Picture two loggers sharing a handler that writes to a single log file.
|
||||||
that issued the record (through the channel name) by keeping the same handlers
|
Channels would allow you to identify the logger that issued every record.
|
||||||
(for instance to use a single log file).
|
You can easily grep through the log files filtering this or that channel.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
@@ -122,3 +121,38 @@ $securityLogger = new Logger('security');
|
|||||||
$securityLogger->pushHandler($stream);
|
$securityLogger->pushHandler($stream);
|
||||||
$securityLogger->pushHandler($firephp);
|
$securityLogger->pushHandler($firephp);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Customizing log format
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
In Monolog it's easy to customize the format of the logs written into files,
|
||||||
|
sockets, mails, databases and other handlers. Most of the handlers use the
|
||||||
|
|
||||||
|
```php
|
||||||
|
$record['formatted']
|
||||||
|
```
|
||||||
|
|
||||||
|
value to be automatically put into the log device. This value depends on the
|
||||||
|
formatter settings. You can choose between predefined formatter classes or
|
||||||
|
write your own (e.g. a multiline text file for human-readable output).
|
||||||
|
|
||||||
|
To configure a predefined formatter class, just set it as the handler's field:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// the default date format is "Y-m-d H:i:s"
|
||||||
|
$dateFormat = "Y n j, g:i a";
|
||||||
|
// the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
|
||||||
|
$output = "%datetime% > %level_name% > %message% %context% %extra%\n"
|
||||||
|
// finally, create a formatter
|
||||||
|
$formatter = new LineFormatter($output, $dateFormat);
|
||||||
|
|
||||||
|
// Create a handler
|
||||||
|
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
|
||||||
|
$stream->setFormatter($formatter);
|
||||||
|
// bind it to a logger object
|
||||||
|
$securityLogger = new Logger('security');
|
||||||
|
$securityLogger->pushHandler($stream);
|
||||||
|
```
|
||||||
|
|
||||||
|
You may also reuse the same formatter between multiple handlers and share those
|
||||||
|
handlers between multiple loggers.
|
||||||
|
@@ -85,6 +85,6 @@ class LineFormatter extends NormalizerFormatter
|
|||||||
return json_encode($this->normalize($data), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
return json_encode($this->normalize($data), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stripslashes(json_encode($this->normalize($data)));
|
return str_replace('\\/', '/', json_encode($this->normalize($data)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,6 @@ class AmqpHandler extends AbstractProcessingHandler
|
|||||||
/**
|
/**
|
||||||
* @param \AMQPExchange $exchange AMQP exchange, ready for use
|
* @param \AMQPExchange $exchange AMQP exchange, ready for use
|
||||||
* @param string $exchangeName
|
* @param string $exchangeName
|
||||||
* @param string $issuer issuer name
|
|
||||||
* @param int $level
|
* @param int $level
|
||||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||||
*/
|
*/
|
||||||
|
@@ -15,20 +15,18 @@ use Monolog\Logger;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs to Cube.
|
* Logs to Cube.
|
||||||
* @link http://square.github.com/cube/
|
|
||||||
*
|
*
|
||||||
|
* @link http://square.github.com/cube/
|
||||||
* @author Wan Chen <kami@kamisama.me>
|
* @author Wan Chen <kami@kamisama.me>
|
||||||
*/
|
*/
|
||||||
class CubeHandler extends AbstractProcessingHandler
|
class CubeHandler extends AbstractProcessingHandler
|
||||||
{
|
{
|
||||||
private $udpConnection = null;
|
private $udpConnection = null;
|
||||||
private $httpConnection = null;
|
private $httpConnection = null;
|
||||||
|
|
||||||
private $scheme = null;
|
private $scheme = null;
|
||||||
private $host = null;
|
private $host = null;
|
||||||
private $port = null;
|
private $port = null;
|
||||||
private $acceptedScheme = array('http', 'udp');
|
private $acceptedSchemes = array('http', 'udp');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Cube handler
|
* Create a Cube handler
|
||||||
@@ -41,36 +39,23 @@ class CubeHandler extends AbstractProcessingHandler
|
|||||||
{
|
{
|
||||||
$urlInfos = parse_url($url);
|
$urlInfos = parse_url($url);
|
||||||
|
|
||||||
if (!$urlInfos || !isset($urlInfos['scheme'])
|
if (!isset($urlInfos['scheme']) || !isset($urlInfos['host']) || !isset($urlInfos['port'])) {
|
||||||
|| !isset($urlInfos['host']) || !isset($urlInfos['port'])) {
|
|
||||||
throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
|
throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($urlInfos['scheme'], $this->acceptedScheme)) {
|
if (!in_array($urlInfos['scheme'], $this->acceptedSchemes)) {
|
||||||
throw new \UnexpectedValueException(
|
throw new \UnexpectedValueException(
|
||||||
'Invalid ' . $urlInfos['scheme'] . ' protocol.'
|
'Invalid protocol (' . $urlInfos['scheme'] . ').'
|
||||||
. 'Valid options are ' . implode(', ', $this->acceptedScheme));
|
. ' Valid options are ' . implode(', ', $this->acceptedSchemes));
|
||||||
} else {
|
|
||||||
$this->scheme = $urlInfos['scheme'];
|
|
||||||
$this->host = $urlInfos['host'];
|
|
||||||
$this->port = $urlInfos['port'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->scheme = $urlInfos['scheme'];
|
||||||
|
$this->host = $urlInfos['host'];
|
||||||
|
$this->port = $urlInfos['port'];
|
||||||
|
|
||||||
parent::__construct($level, $bubble);
|
parent::__construct($level, $bubble);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a connection resource is available
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
private function isConnected($scheme)
|
|
||||||
{
|
|
||||||
return $this->{$scheme . 'Connection'} !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establish a connection to an UDP socket
|
* Establish a connection to an UDP socket
|
||||||
*
|
*
|
||||||
@@ -79,7 +64,7 @@ class CubeHandler extends AbstractProcessingHandler
|
|||||||
protected function connectUdp()
|
protected function connectUdp()
|
||||||
{
|
{
|
||||||
if (!extension_loaded('sockets')) {
|
if (!extension_loaded('sockets')) {
|
||||||
throw new \LogicException('The sockets extension is not loaded');
|
throw new \LogicException('The sockets extension is needed to use udp URLs with the CubeHandler');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
|
$this->udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
|
||||||
@@ -88,31 +73,29 @@ class CubeHandler extends AbstractProcessingHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
|
if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
|
||||||
throw new \LogicException('Unable to connect to the socket at '
|
throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
|
||||||
. $this->host . ':' . $this->port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establish a connection to a http server
|
* Establish a connection to a http server
|
||||||
*/
|
*/
|
||||||
protected function connectHttp()
|
protected function connectHttp()
|
||||||
{
|
{
|
||||||
$this->httpConnection =
|
if (!extension_loaded('curl')) {
|
||||||
curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
|
throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
|
||||||
|
|
||||||
if (!$this->httpConnection) {
|
if (!$this->httpConnection) {
|
||||||
throw new \LogicException('Unable to connect to '
|
throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
|
||||||
. $this->host . ':' . $this->port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
|
curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
|
||||||
curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@@ -120,47 +103,43 @@ class CubeHandler extends AbstractProcessingHandler
|
|||||||
{
|
{
|
||||||
$date = $record['datetime'];
|
$date = $record['datetime'];
|
||||||
|
|
||||||
$datas = array('time' => $date->format('Y-m-d H:i:s'));
|
$data = array('time' => $date->format('Y-m-d H:i:s'));
|
||||||
unset($record['datetime']);
|
unset($record['datetime']);
|
||||||
|
|
||||||
if (isset($record['context']['type'])) {
|
if (isset($record['context']['type'])) {
|
||||||
$datas['type'] = $record['context']['type'];
|
$data['type'] = $record['context']['type'];
|
||||||
unset($record['context']['type']);
|
unset($record['context']['type']);
|
||||||
} else {
|
} else {
|
||||||
$datas['type'] = $record['channel'];
|
$data['type'] = $record['channel'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$datas['data'] = $record['context'];
|
$data['data'] = $record['context'];
|
||||||
$datas['data']['level'] = $record['level'];
|
$data['data']['level'] = $record['level'];
|
||||||
|
|
||||||
call_user_func(
|
$this->{'write'.$this->scheme}(json_encode($data));
|
||||||
array($this, 'send'.ucwords($this->scheme)), json_encode($datas));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function writeUdp($data)
|
||||||
private function sendUdp($datas)
|
|
||||||
{
|
{
|
||||||
if (!$this->isConnected($this->scheme)) {
|
if (!$this->udpConnection) {
|
||||||
call_user_func(
|
$this->connectUdp();
|
||||||
array($this, 'connect' . ucwords($this->scheme)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_send($this->udpConnection, $datas, strlen($datas), 0);
|
socket_send($this->udpConnection, $data, strlen($data), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function writeHttp($data)
|
||||||
private function sendHttp($datas)
|
|
||||||
{
|
{
|
||||||
if (!$this->isConnected($this->scheme)) {
|
if (!$this->httpConnection) {
|
||||||
call_user_func(
|
$this->connectHttp();
|
||||||
array($this, 'connect' . ucwords($this->scheme)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$datas.']');
|
curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
|
||||||
curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array(
|
curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array(
|
||||||
'Content-Type: application/json',
|
'Content-Type: application/json',
|
||||||
'Content-Length: ' . strlen('['.$datas.']'))
|
'Content-Length: ' . strlen('['.$data.']'))
|
||||||
);
|
);
|
||||||
|
|
||||||
return curl_exec($this->httpConnection);
|
return curl_exec($this->httpConnection);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -25,6 +25,8 @@ interface HandlerInterface
|
|||||||
*
|
*
|
||||||
* This is mostly done for performance reasons, to avoid calling processors for nothing.
|
* This is mostly done for performance reasons, to avoid calling processors for nothing.
|
||||||
*
|
*
|
||||||
|
* @param array $record
|
||||||
|
*
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
public function isHandling(array $record);
|
public function isHandling(array $record);
|
||||||
|
@@ -42,7 +42,7 @@ class NativeMailerHandler extends MailHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|array $header Custom added headers
|
* @param string|array $headers Custom added headers
|
||||||
*/
|
*/
|
||||||
public function addHeader($headers)
|
public function addHeader($headers)
|
||||||
{
|
{
|
||||||
|
@@ -89,7 +89,7 @@ class SocketHandler extends AbstractProcessingHandler
|
|||||||
/**
|
/**
|
||||||
* Set connection timeout. Only has effect before we connect.
|
* Set connection timeout. Only has effect before we connect.
|
||||||
*
|
*
|
||||||
* @param integer $seconds
|
* @param float $seconds
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.fsockopen.php
|
* @see http://php.net/manual/en/function.fsockopen.php
|
||||||
*/
|
*/
|
||||||
@@ -102,14 +102,14 @@ class SocketHandler extends AbstractProcessingHandler
|
|||||||
/**
|
/**
|
||||||
* Set write timeout. Only has effect before we connect.
|
* Set write timeout. Only has effect before we connect.
|
||||||
*
|
*
|
||||||
* @param type $seconds
|
* @param float $seconds
|
||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.stream-set-timeout.php
|
* @see http://php.net/manual/en/function.stream-set-timeout.php
|
||||||
*/
|
*/
|
||||||
public function setTimeout($seconds)
|
public function setTimeout($seconds)
|
||||||
{
|
{
|
||||||
$this->validateTimeout($seconds);
|
$this->validateTimeout($seconds);
|
||||||
$this->timeout = (int) $seconds;
|
$this->timeout = (float) $seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,10 +183,15 @@ class SocketHandler extends AbstractProcessingHandler
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper to allow mocking
|
* Wrapper to allow mocking
|
||||||
|
*
|
||||||
|
* @see http://php.net/manual/en/function.stream-set-timeout.php
|
||||||
*/
|
*/
|
||||||
protected function streamSetTimeout()
|
protected function streamSetTimeout()
|
||||||
{
|
{
|
||||||
return stream_set_timeout($this->resource, $this->timeout);
|
$seconds = floor($this->timeout);
|
||||||
|
$microseconds = round(($this->timeout - $seconds)*1e6);
|
||||||
|
|
||||||
|
return stream_set_timeout($this->resource, $seconds, $microseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,11 +212,9 @@ class SocketHandler extends AbstractProcessingHandler
|
|||||||
|
|
||||||
private function validateTimeout($value)
|
private function validateTimeout($value)
|
||||||
{
|
{
|
||||||
$ok = filter_var($value, FILTER_VALIDATE_INT, array('options' => array(
|
$ok = filter_var($value, FILTER_VALIDATE_FLOAT);
|
||||||
'min_range' => 0,
|
if ($ok === false || $value < 0) {
|
||||||
)));
|
throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)");
|
||||||
if ($ok === false) {
|
|
||||||
throw new \InvalidArgumentException("Timeout must be 0 or a positive integer (got $value)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +257,11 @@ class SocketHandler extends AbstractProcessingHandler
|
|||||||
$length = strlen($data);
|
$length = strlen($data);
|
||||||
$sent = 0;
|
$sent = 0;
|
||||||
while ($this->isConnected() && $sent < $length) {
|
while ($this->isConnected() && $sent < $length) {
|
||||||
$chunk = $this->fwrite(substr($data, $sent));
|
if (0 == $sent) {
|
||||||
|
$chunk = $this->fwrite($data);
|
||||||
|
} else {
|
||||||
|
$chunk = $this->fwrite(substr($data, $sent));
|
||||||
|
}
|
||||||
if ($chunk === false) {
|
if ($chunk === false) {
|
||||||
throw new \RuntimeException("Could not write to socket");
|
throw new \RuntimeException("Could not write to socket");
|
||||||
}
|
}
|
||||||
|
@@ -60,10 +60,15 @@ class StreamHandler extends AbstractProcessingHandler
|
|||||||
if (!$this->url) {
|
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().');
|
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');
|
$errorMessage = null;
|
||||||
|
set_error_handler(function ($code, $msg) use (&$errorMessage) {
|
||||||
|
$errorMessage = preg_replace('{^fopen\(.*?\): }', '', $msg);
|
||||||
|
});
|
||||||
|
$this->stream = fopen($this->url, 'a');
|
||||||
|
restore_error_handler();
|
||||||
if (!is_resource($this->stream)) {
|
if (!is_resource($this->stream)) {
|
||||||
$this->stream = null;
|
$this->stream = null;
|
||||||
throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened; it may be invalid or not writable.', $this->url));
|
throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$errorMessage, $this->url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fwrite($this->stream, (string) $record['formatted']);
|
fwrite($this->stream, (string) $record['formatted']);
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
namespace Monolog\Handler;
|
namespace Monolog\Handler;
|
||||||
|
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
|
use Monolog\Formatter\LineFormatter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs to syslog service.
|
* Logs to syslog service.
|
||||||
@@ -64,8 +66,9 @@ class SyslogHandler extends AbstractProcessingHandler
|
|||||||
* @param mixed $facility
|
* @param mixed $facility
|
||||||
* @param integer $level The minimum logging level at which this handler will be triggered
|
* @param integer $level The minimum logging level at which this handler will be triggered
|
||||||
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
|
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
|
||||||
|
* @param int $logopts Option flags for the openlog() call, defaults to LOG_PID
|
||||||
*/
|
*/
|
||||||
public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
|
public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $logopts = LOG_PID)
|
||||||
{
|
{
|
||||||
parent::__construct($level, $bubble);
|
parent::__construct($level, $bubble);
|
||||||
|
|
||||||
@@ -87,7 +90,7 @@ class SyslogHandler extends AbstractProcessingHandler
|
|||||||
throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given');
|
throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!openlog($ident, LOG_PID, $facility)) {
|
if (!openlog($ident, $logopts, $facility)) {
|
||||||
throw new \LogicException('Can\'t open syslog for ident "'.$ident.'" and facility "'.$facility.'"');
|
throw new \LogicException('Can\'t open syslog for ident "'.$ident.'" and facility "'.$facility.'"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,4 +110,12 @@ class SyslogHandler extends AbstractProcessingHandler
|
|||||||
{
|
{
|
||||||
syslog($this->logLevels[$record['level']], (string) $record['formatted']);
|
syslog($this->logLevels[$record['level']], (string) $record['formatted']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getDefaultFormatter()
|
||||||
|
{
|
||||||
|
return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -194,7 +194,7 @@ class Logger
|
|||||||
'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)))->setTimeZone(self::$timezone),
|
'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)))->setTimeZone(self::$timezone),
|
||||||
'extra' => array(),
|
'extra' => array(),
|
||||||
);
|
);
|
||||||
// check if any message will handle this message
|
// check if any handler will handle this message
|
||||||
$handlerKey = null;
|
$handlerKey = null;
|
||||||
foreach ($this->handlers as $key => $handler) {
|
foreach ($this->handlers as $key => $handler) {
|
||||||
if ($handler->isHandling($record)) {
|
if ($handler->isHandling($record)) {
|
||||||
|
@@ -86,11 +86,8 @@ class LineFormatterTest extends \PHPUnit_Framework_TestCase
|
|||||||
'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
|
'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
|
||||||
'message' => 'foobar',
|
'message' => 'foobar',
|
||||||
));
|
));
|
||||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
|
||||||
$this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: {})","baz":[],"res":"[resource]"}'."\n", $message);
|
$this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: {})","baz":[],"res":"[resource]"}'."\n", $message);
|
||||||
} else {
|
|
||||||
$this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\Formatter\\TestFoo: {"foo":"foo"})","bar":"[object] (Monolog\\Formatter\\TestBar: {})","baz":[],"res":"[resource]"}'."\n", $message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBatchFormat()
|
public function testBatchFormat()
|
||||||
|
@@ -64,7 +64,6 @@ class AbstractProcessingHandlerTest extends TestCase
|
|||||||
'REQUEST_URI' => '',
|
'REQUEST_URI' => '',
|
||||||
'REQUEST_METHOD' => '',
|
'REQUEST_METHOD' => '',
|
||||||
'REMOTE_ADDR' => '',
|
'REMOTE_ADDR' => '',
|
||||||
'REQUEST_URI' => '',
|
|
||||||
'SERVER_NAME' => '',
|
'SERVER_NAME' => '',
|
||||||
)));
|
)));
|
||||||
$handledRecord = null;
|
$handledRecord = null;
|
||||||
|
@@ -50,8 +50,8 @@ class SocketHandlerTest extends TestCase
|
|||||||
public function testSetConnectionTimeout()
|
public function testSetConnectionTimeout()
|
||||||
{
|
{
|
||||||
$this->createHandler('localhost:1234');
|
$this->createHandler('localhost:1234');
|
||||||
$this->handler->setConnectionTimeout(10);
|
$this->handler->setConnectionTimeout(10.1);
|
||||||
$this->assertEquals(10, $this->handler->getConnectionTimeout());
|
$this->assertEquals(10.1, $this->handler->getConnectionTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,8 +66,8 @@ class SocketHandlerTest extends TestCase
|
|||||||
public function testSetTimeout()
|
public function testSetTimeout()
|
||||||
{
|
{
|
||||||
$this->createHandler('localhost:1234');
|
$this->createHandler('localhost:1234');
|
||||||
$this->handler->setTimeout(10);
|
$this->handler->setTimeout(10.25);
|
||||||
$this->assertEquals(10, $this->handler->getTimeout());
|
$this->assertEquals(10.25, $this->handler->getTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetConnectionString()
|
public function testSetConnectionString()
|
||||||
|
@@ -74,4 +74,15 @@ class StreamHandlerTest extends TestCase
|
|||||||
$handler = new StreamHandler('bogus://url');
|
$handler = new StreamHandler('bogus://url');
|
||||||
$handler->handle($this->getRecord());
|
$handler->handle($this->getRecord());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException UnexpectedValueException
|
||||||
|
* @covers Monolog\Handler\StreamHandler::__construct
|
||||||
|
* @covers Monolog\Handler\StreamHandler::write
|
||||||
|
*/
|
||||||
|
public function testWriteNonExistingResource()
|
||||||
|
{
|
||||||
|
$handler = new StreamHandler('/foo/bar/baz/'.rand(0, 10000));
|
||||||
|
$handler->handle($this->getRecord());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Monolog\Handler;
|
namespace Monolog\Handler;
|
||||||
|
use Monolog\Logger;
|
||||||
|
|
||||||
class SyslogHandlerTest extends \PHPUnit_Framework_TestCase
|
class SyslogHandlerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
@@ -26,6 +27,9 @@ class SyslogHandlerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$handler = new SyslogHandler('test', 'user');
|
$handler = new SyslogHandler('test', 'user');
|
||||||
$this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
|
$this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
|
||||||
|
|
||||||
|
$handler = new SyslogHandler('test', LOG_USER, Logger::DEBUG, true, LOG_PERROR);
|
||||||
|
$this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user