Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean Carlo Machado committed May 17, 2014
Show file tree
Hide file tree
Showing 59 changed files with 589 additions and 121 deletions.
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}
},
"require": {
"php": ">=5.3.3",
"php": ">=5.3.23",
"zendframework/zend-servicemanager": "self.version",
"zendframework/zend-stdlib": "self.version"
},
Expand All @@ -38,8 +38,8 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.2-dev",
"dev-develop": "2.3-dev"
"dev-master": "2.3-dev",
"dev-develop": "2.4-dev"
}
},
"autoload-dev": {
Expand Down
6 changes: 3 additions & 3 deletions src/Filter/Priority.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ public function __construct($priority, $operator = null)
$operator = isset($priority['operator']) ? $priority['operator'] : null;
$priority = isset($priority['priority']) ? $priority['priority'] : null;
}
if (!is_int($priority)) {
if (!is_int($priority) && !ctype_digit($priority)) {
throw new Exception\InvalidArgumentException(sprintf(
'Priority must be an integer; received "%s"',
'Priority must be a number, received "%s"',
gettype($priority)
));
}

$this->priority = $priority;
$this->priority = (int) $priority;
$this->operator = $operator === null ? '<=' : $operator;
}

Expand Down
56 changes: 56 additions & 0 deletions src/Filter/Sample.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Log\Filter;

use Zend\Log\Exception;

class Sample implements FilterInterface
{
/**
* Sample rate [0-1].
*
* @var float
*/
protected $sampleRate;

/**
* Filters logging by sample rate.
*
* Sample rate must be a float number between 0 and 1 included.
* If 0.5, only half of the values will be logged.
* If 0.1 only 1 among 10 values will be logged.
*
* @param float|int $samplerate Sample rate [0-1].
* @return Priority
* @throws Exception\InvalidArgumentException
*/
public function __construct($sampleRate = 1)
{
if (! is_numeric($sampleRate)) {
throw new Exception\InvalidArgumentException(sprintf(
'Sample rate must be numeric, received "%s"',
gettype($sampleRate)
));
}

$this->sampleRate = (float) $sampleRate;
}

/**
* Returns TRUE to accept the message, FALSE to block it.
*
* @param array $event event data
* @return bool Accepted ?
*/
public function filter(array $event)
{
return (mt_rand() / mt_getrandmax()) <= $this->sampleRate;
}
}
2 changes: 1 addition & 1 deletion src/Filter/SuppressFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function __construct($suppress = false)
}
if (!is_bool($suppress)) {
throw new Exception\InvalidArgumentException(sprintf(
'Suppress must be an boolean; received "%s"', gettype($suppress)
'Suppress must be a boolean; received "%s"', gettype($suppress)
));
}

Expand Down
2 changes: 1 addition & 1 deletion src/Filter/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function __construct($validator)
}
if (!$validator instanceof ZendValidator) {
throw new Exception\InvalidArgumentException(sprintf(
'Parameter of type %s is invalid; must implements Zend\Validator\ValidatorInterface',
'Parameter of type %s is invalid; must implement Zend\Validator\ValidatorInterface',
(is_object($validator) ? get_class($validator) : gettype($validator))
));
}
Expand Down
14 changes: 8 additions & 6 deletions src/Formatter/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use DateTime;
use Traversable;
use Zend\Stdlib\ErrorHandler;

class Base implements FormatterInterface
{
Expand Down Expand Up @@ -84,21 +83,24 @@ protected function normalize($value)
$jsonFlags |= defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0;
}

ErrorHandler::start();
// Error suppression is used in several of these cases as a fix for each of
// #5383 and #4616. Without it, #4616 fails whenever recursion occurs during
// json_encode() operations; usage of a dedicated error handler callback
// causes #5383 to fail when the Logger is being used as an error handler.
// The only viable solution here is error suppression, ugly as it may be.
if ($value instanceof DateTime) {
$value = $value->format($this->getDateTimeFormat());
} elseif ($value instanceof Traversable) {
$value = json_encode(iterator_to_array($value), $jsonFlags);
$value = @json_encode(iterator_to_array($value), $jsonFlags);
} elseif (is_array($value)) {
$value = json_encode($value, $jsonFlags);
$value = @json_encode($value, $jsonFlags);
} elseif (is_object($value) && !method_exists($value, '__toString')) {
$value = sprintf('object(%s) %s', get_class($value), json_encode($value));
$value = sprintf('object(%s) %s', get_class($value), @json_encode($value));
} elseif (is_resource($value)) {
$value = sprintf('resource(%s)', get_resource_type($value));
} elseif (!is_object($value)) {
$value = gettype($value);
}
ErrorHandler::stop();

return (string) $value;
}
Expand Down
123 changes: 98 additions & 25 deletions src/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use DateTime;
use ErrorException;
use Traversable;
use Zend\ServiceManager\AbstractPluginManager;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\SplPriorityQueue;

Expand Down Expand Up @@ -60,6 +61,13 @@ class Logger implements LoggerInterface
*/
protected static $registeredErrorHandler = false;

/**
* Registered shutdown error handler
*
* @var bool
*/
protected static $registeredFatalErrorShutdownFunction = false;

/**
* Registered exception handler
*
Expand Down Expand Up @@ -114,7 +122,7 @@ class Logger implements LoggerInterface
/**
* Constructor
*
* Set options for an logger. Accepted options are:
* Set options for a logger. Accepted options are:
* - writers: array of writers to add to this logger
* - exceptionhandler: if true register this logger as exceptionhandler
* - errorhandler: if true register this logger as errorhandler
Expand All @@ -125,40 +133,72 @@ class Logger implements LoggerInterface
*/
public function __construct($options = null)
{
$this->writers = new SplPriorityQueue();
$this->writers = new SplPriorityQueue();
$this->processors = new SplPriorityQueue();

if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}

if (is_array($options)) {
if (isset($options['writers']) && is_array($options['writers'])) {
foreach ($options['writers'] as $writer) {
if (!$options) {
return;
}

if (!is_array($options)) {
throw new Exception\InvalidArgumentException('Options must be an array or an object implementing \Traversable ');
}

if (!isset($writer['name'])) {
throw new Exception\InvalidArgumentException('Options must contain a name for the writer');
}
// Inject writer plugin manager, if available
if (isset($options['writer_plugin_manager'])
&& $options['writer_plugin_manager'] instanceof AbstractPluginManager
) {
$this->setWriterPluginManager($options['writer_plugin_manager']);
}

$priority = (isset($writer['priority'])) ? $writer['priority'] : null;
$writerOptions = (isset($writer['options'])) ? $writer['options'] : null;
// Inject processor plugin manager, if available
if (isset($options['processor_plugin_manager'])
&& $options['processor_plugin_manager'] instanceof AbstractPluginManager
) {
$this->setProcessorPluginManager($options['processor_plugin_manager']);
}

$this->addWriter($writer['name'], $priority, $writerOptions);
if (isset($options['writers']) && is_array($options['writers'])) {
foreach ($options['writers'] as $writer) {
if (!isset($writer['name'])) {
throw new Exception\InvalidArgumentException('Options must contain a name for the writer');
}
}

if (isset($options['exceptionhandler']) && $options['exceptionhandler'] === true) {
static::registerExceptionHandler($this);
$priority = (isset($writer['priority'])) ? $writer['priority'] : null;
$writerOptions = (isset($writer['options'])) ? $writer['options'] : null;

$this->addWriter($writer['name'], $priority, $writerOptions);
}
}

if (isset($options['processors']) && is_array($options['processors'])) {
foreach ($options['processors'] as $processor) {
if (!isset($processor['name'])) {
throw new Exception\InvalidArgumentException('Options must contain a name for the processor');
}

$priority = (isset($processor['priority'])) ? $processor['priority'] : null;
$processorOptions = (isset($processor['options'])) ? $processor['options'] : null;

if (isset($options['errorhandler']) && $options['errorhandler'] === true) {
static::registerErrorHandler($this);
$this->addProcessor($processor['name'], $priority, $processorOptions);
}
}

} elseif ($options) {
throw new Exception\InvalidArgumentException('Options must be an array or an object implementing \Traversable ');
if (isset($options['exceptionhandler']) && $options['exceptionhandler'] === true) {
static::registerExceptionHandler($this);
}

$this->processors = new SplPriorityQueue();
if (isset($options['errorhandler']) && $options['errorhandler'] === true) {
static::registerErrorHandler($this);
}

if (isset($options['fatal_error_shutdownfunction']) && $options['fatal_error_shutdownfunction'] === true) {
static::registerFatalErrorShutdownFunction($this);
}
}

/**
Expand Down Expand Up @@ -304,9 +344,9 @@ public function setProcessorPluginManager($plugins)
}
if (!$plugins instanceof ProcessorPluginManager) {
throw new Exception\InvalidArgumentException(sprintf(
'processor plugin manager must extend %s\ProcessorPluginManager; received %s',
__NAMESPACE__,
is_object($plugins) ? get_class($plugins) : gettype($plugins)
'processor plugin manager must extend %s\ProcessorPluginManager; received %s',
__NAMESPACE__,
is_object($plugins) ? get_class($plugins) : gettype($plugins)
));
}

Expand Down Expand Up @@ -341,8 +381,8 @@ public function addProcessor($processor, $priority = 1, array $options = null)
$processor = $this->processorPlugin($processor, $options);
} elseif (!$processor instanceof Processor\ProcessorInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Processor must implement Zend\Log\ProcessorInterface; received "%s"',
is_object($processor) ? get_class($processor) : gettype($processor)
'Processor must implement Zend\Log\ProcessorInterface; received "%s"',
is_object($processor) ? get_class($processor) : gettype($processor)
));
}
$this->processors->insert($processor, $priority);
Expand Down Expand Up @@ -409,7 +449,7 @@ public function log($priority, $message, $extra = array())
'priority' => (int) $priority,
'priorityName' => $this->priorities[$priority],
'message' => (string) $message,
'extra' => $extra
'extra' => $extra,
);

foreach ($this->processors->toArray() as $processor) {
Expand Down Expand Up @@ -554,6 +594,39 @@ public static function unregisterErrorHandler()
static::$registeredErrorHandler = false;
}

/**
* Register a shutdown handler to log fatal errors
*
* @link http://www.php.net/manual/function.register-shutdown-function.php
* @param Logger $logger
* @return bool
*/
public static function registerFatalErrorShutdownFunction(Logger $logger)
{
// Only register once per instance
if (static::$registeredFatalErrorShutdownFunction) {
return false;
}

$errorPriorityMap = static::$errorPriorityMap;

register_shutdown_function(function () use ($logger, $errorPriorityMap) {
$error = error_get_last();
if (null !== $error && $error['type'] === E_ERROR) {
$logger->log($errorPriorityMap[E_ERROR],
$error['message'],
array(
'file' => $error['file'],
'line' => $error['line'],
)
);
}
});

static::$registeredFatalErrorShutdownFunction = true;
return true;
}

/**
* Register logging system as an exception handler to log PHP exceptions
*
Expand Down
29 changes: 29 additions & 0 deletions src/LoggerAbstractServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace Zend\Log;

use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\AbstractPluginManager;
use Zend\ServiceManager\ServiceLocatorInterface;

/**
Expand Down Expand Up @@ -90,6 +91,34 @@ protected function getConfig(ServiceLocatorInterface $services)

protected function processConfig(&$config, ServiceLocatorInterface $services)
{
if (isset($config['writer_plugin_manager'])
&& is_string($config['writer_plugin_manager'])
&& $services->has($config['writer_plugin_manager'])
) {
$config['writer_plugin_manager'] = $services->get($config['writer_plugin_manager']);
}

if ((!isset($config['writer_plugin_manager'])
|| ! $config['writer_plugin_manager'] instanceof AbstractPluginManager)
&& $services->has('LogWriterManager')
) {
$config['writer_plugin_manager'] = $services->get('LogWriterManager');
}

if (isset($config['processor_plugin_manager'])
&& is_string($config['processor_plugin_manager'])
&& $services->has($config['processor_plugin_manager'])
) {
$config['processor_plugin_manager'] = $services->get($config['processor_plugin_manager']);
}

if ((!isset($config['processor_plugin_manager'])
|| ! $config['processor_plugin_manager'] instanceof AbstractPluginManager)
&& $services->has('LogProcessorManager')
) {
$config['processor_plugin_manager'] = $services->get('LogProcessorManager');
}

if (!isset($config['writers'])) {
return;
}
Expand Down
Loading

0 comments on commit 5422681

Please sign in to comment.