Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'feature/log-processors' of git://github.com/stefankleff…

…/zf2 into feature/log-processors

Conflicts:
	library/Zend/Log/Logger.php
	tests/ZendTest/Log/LoggerTest.php
  • Loading branch information...
commit 363fa154ed5a205e90a5d0872935bca46a777ab5 2 parents d717c1e + 3542b17
@weierophinney weierophinney authored
View
120 library/Zend/Log/Logger.php
@@ -60,6 +60,13 @@ class Logger implements LoggerInterface
protected $writers;
/**
+ * Processors
+ *
+ * @var SplPriorityQueue
+ */
+ protected $processors;
+
+ /**
* Writer plugins
*
* @var WriterPluginManager
@@ -67,6 +74,13 @@ class Logger implements LoggerInterface
protected $writerPlugins;
/**
+ * Processor plugins
+ *
+ * @var ProcessorPluginManager
+ */
+ protected $processorPlugins;
+
+ /**
* Registered error handler
*
* @var boolean
@@ -125,6 +139,8 @@ public function __construct(array $options = null)
}
}
+
+ $this->processors = new SplPriorityQueue();
}
/**
@@ -242,6 +258,90 @@ public function setWriters(SplPriorityQueue $writers)
return $this;
}
+
+ /**
+ * Get processor plugin manager
+ *
+ * @return ProcessorPluginManager
+ */
+ public function getProcessorPluginManager()
+ {
+ if (null === $this->processorPlugins) {
+ $this->setProcessorPluginManager(new ProcessorPluginManager());
+ }
+ return $this->processorPlugins;
+ }
+
+ /**
+ * Set processor plugin manager
+ *
+ * @param string|ProcessorPluginManager $plugins
+ * @return Logger
+ * @throws Exception\InvalidArgumentException
+ */
+ public function setProcessorPluginManager($plugins)
+ {
+ if (is_string($plugins)) {
+ $plugins = new $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)
+ ));
+ }
+
+ $this->processorPlugins = $plugins;
+ return $this;
+ }
+
+ /**
+ * Get processor instance
+ *
+ * @param string $name
+ * @param array|null $options
+ * @return Processor\ProcessorInterface
+ */
+ public function processorPlugin($name, array $options = null)
+ {
+ return $this->getProcessorPluginManager()->get($name, $options);
+ }
+
+ /**
+ * Add a processor to a logger
+ *
+ * @param string|Processor\ProcessorInterface $processor
+ * @param int $priority
+ * @param array|null $options
+ * @return Logger
+ * @throws Exception\InvalidArgumentException
+ */
+ public function addProcessor($processor, $priority = 1, array $options = null)
+ {
+ if (is_string($processor)) {
+ $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)
+ ));
+ }
+ $this->processors->insert($processor, $priority);
+
+ return $this;
+ }
+
+ /**
+ * Get processors
+ *
+ * @return SplPriorityQueue
+ */
+ public function getProcessors()
+ {
+ return $this->processors;
+ }
+
/**
* Add a message as a log entry
*
@@ -286,14 +386,20 @@ public function log($priority, $message, $extra = array())
$message = var_export($message, true);
}
+ $event = array(
+ 'timestamp' => $timestamp,
+ 'priority' => (int) $priority,
+ 'priorityName' => $this->priorities[$priority],
+ 'message' => (string) $message,
+ 'extra' => $extra
+ );
+
+ foreach($this->processors->toArray() as $processor) {
+ $event = $processor->process($event);
+ }
+
foreach ($this->writers->toArray() as $writer) {
- $writer->write(array(
- 'timestamp' => $timestamp,
- 'priority' => (int) $priority,
- 'priorityName' => $this->priorities[$priority],
- 'message' => (string) $message,
- 'extra' => $extra
- ));
+ $writer->write($event);
}
return $this;
View
84 library/Zend/Log/Processor/Backtrace.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+*
+* @link http://github.com/zendframework/zf2 for the canonical source repository
+* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+* @license http://framework.zend.com/license/new-bsd New BSD License
+* @package Zend_Log
+*/
+
+namespace Zend\Log\Processor;
+
+/**
+ * @category Zend
+ * @package Zend_Log
+ * @subpackage Processor
+ */
+class Backtrace implements ProcessorInterface
+{
+ /**
+ * Maximum stack level of backtrace (PHP > 5.4.0)
+ * @var int
+ */
+ protected $traceLimit = 10;
+
+ /**
+ * Classes within this namespace in the stack are ignored
+ * @var string
+ */
+ protected $ignoredNamespace = 'Zend\\Log';
+
+ /**
+ * Adds the origin of the log() call to the event extras
+ *
+ * @param array $event event data
+ * @return array event data
+ */
+ public function process(array $event)
+ {
+ $trace = $this->getBacktrace();
+
+ array_shift($trace); // ignore $this->getBacktrace();
+ array_shift($trace); // ignore $this->process()
+
+ $i = 0;
+ while (isset($trace[$i]['class']) && false !== strpos($trace[$i]['class'], $this->ignoredNamespace)) {
+ $i++;
+ }
+
+ $origin = array(
+ 'file' => isset($trace[$i-1]['file']) ? $trace[$i-1]['file'] : null,
+ 'line' => isset($trace[$i-1]['line']) ? $trace[$i-1]['line'] : null,
+ 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null,
+ 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
+ );
+
+ if(!isset($event['extra'])) {
+ $event['extra'] = $origin;
+ } else {
+ $event['extra'] = array_merge($origin, $event['extra']);
+ }
+
+ return $event;
+ }
+
+ /**
+ * Provide backtrace as slim as posible
+ *
+ * @return array:
+ */
+ protected function getBacktrace()
+ {
+ if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
+ return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $this->traceLimit);
+ }
+
+ if (version_compare(PHP_VERSION, '5.3.6') >= 0) {
+ return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ }
+
+ return debug_backtrace();
+ }
+
+}
View
27 library/Zend/Log/Processor/ProcessorInterface.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Log
+ */
+
+namespace Zend\Log\Processor;
+
+/**
+ * @category Zend
+ * @package Zend_Log
+ */
+interface ProcessorInterface
+{
+ /**
+ * Processes a log message before it is given to the writers
+ *
+ * @param array $event
+ * @return WriterInterface
+ */
+ public function process(array $event);
+
+}
View
59 library/Zend/Log/Processor/RequestId.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+*
+* @link http://github.com/zendframework/zf2 for the canonical source repository
+* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+* @license http://framework.zend.com/license/new-bsd New BSD License
+* @package Zend_Log
+*/
+
+namespace Zend\Log\Processor;
+
+use Zend\Console\Console;
+
+/**
+ * @category Zend
+ * @package Zend_Log
+ * @subpackage Processor
+ */
+class RequestId implements ProcessorInterface
+{
+
+ /**
+ * Adds a identfier for the request to the log.
+ * This enables to filter the log for messages belonging to a specific request
+ *
+ * @param array $event event data
+ * @return array event data
+ */
+ public function process(array $event)
+ {
+ if(!isset($event['extra'])) {
+ $event['extra'] = array();
+ }
+
+ $event['extra']['requestId'] = $this->getIdentifier();
+ return $event;
+ }
+
+ /**
+ * Provide unique identifier for a request
+ *
+ * @return array:
+ */
+ protected function getIdentifier()
+ {
+ $requestTime = (version_compare(PHP_VERSION, '5.4.0') >= 0) ? $_SERVER['REQUEST_TIME_FLOAT'] : $_SERVER['REQUEST_TIME'];
+
+ if(Console::isConsole()) {
+ return md5($requestTime);
+ }
+
+ if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+ return md5($requestTime . $_SERVER['HTTP_X_FORWARDED_FOR']);
+ }
+
+ return md5($requestTime . $_SERVER['REMOTE_ADDR']);
+ }
+}
View
60 library/Zend/Log/ProcessorPluginManager.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Log
+ */
+
+namespace Zend\Log;
+
+use Zend\ServiceManager\AbstractPluginManager;
+
+/**
+ * @category Zend
+ * @package Zend_Log
+ */
+class ProcessorPluginManager extends AbstractPluginManager
+{
+ /**
+ * Default set of writers
+ *
+ * @var array
+ */
+ protected $invokableClasses = array(
+ 'backtrace' => 'Zend\Log\Processor\Backtrace',
+ 'requestid' => 'Zend\Log\Processor\RequestId',
+ );
+
+ /**
+ * Allow many writers of the same type
+ *
+ * @var bool
+ */
+ protected $shareByDefault = false;
+
+ /**
+ * Validate the plugin
+ *
+ * Checks that the processor loaded is an instance of Processor\ProcessorInterface.
+ *
+ * @param mixed $plugin
+ * @return void
+ * @throws Exception\InvalidArgumentException if invalid
+ */
+ public function validatePlugin($plugin)
+ {
+ if ($plugin instanceof Processor\ProcessorInterface) {
+ // we're okay
+ return;
+ }
+
+ throw new Exception\InvalidArgumentException(sprintf(
+ 'Plugin of type %s is invalid; must implement %s\Processor\ProcessorInterface',
+ (is_object($plugin) ? get_class($plugin) : gettype($plugin)),
+ __NAMESPACE__
+ ));
+ }
+}
View
34 tests/ZendTest/Log/LoggerTest.php
@@ -10,6 +10,8 @@
namespace ZendTest\Log;
+use Zend\Log\Processor\Backtrace;
+
use Zend\Log\Logger;
use Zend\Log\Writer\Mock as MockWriter;
use Zend\Log\Filter\Mock as MockFilter;
@@ -292,4 +294,36 @@ public function testOptionsWithWriterOptions()
$this->assertInstanceOf('Zend\Log\Writer\Stream', $writers[0]);
$this->assertEquals('foo', $writers[0]->getLogSeparator());
}
+
+ public function testAddProcessor()
+ {
+ $processor = new Backtrace();
+ $this->logger->addProcessor($processor);
+
+ $processors = $this->logger->getProcessors()->toArray();
+ $this->assertEquals($processor, $processors[0]);
+ }
+
+ public function testAddProcessorByName()
+ {
+ $this->logger->addProcessor('backtrace');
+
+ $processors = $this->logger->getProcessors()->toArray();
+ $this->assertInstanceOf('Zend\Log\Processor\Backtrace', $processors[0]);
+
+ $writer = new MockWriter;
+ $this->logger->addWriter($writer);
+ $this->logger->log(Logger::ERR, 'foo');
+ }
+
+ public function testProcessorOutputAdded()
+ {
+ $processor = new Backtrace();
+ $this->logger->addProcessor($processor);
+ $writer = new MockWriter;
+ $this->logger->addWriter($writer);
+
+ $this->logger->log(Logger::ERR, 'foo');
+ $this->assertEquals(__FILE__, $writer->events[0]['extra']['file']);
+ }
}
View
43 tests/ZendTest/Log/Processor/BacktraceTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Log
+ */
+
+namespace ZendTest\Log\Processor;
+
+use Zend\Log\Processor\Backtrace;
+
+/**
+ * @category Zend
+ * @package Zend_Log
+ * @subpackage UnitTests
+ * @group Zend_Log
+ */
+class BacktraceTest extends \PHPUnit_Framework_TestCase
+{
+
+ public function testProcess()
+ {
+ $processor = new Backtrace();
+
+ $event = array(
+ 'timestamp' => '',
+ 'priority' => 1,
+ 'priorityName' => 'ALERT',
+ 'message' => 'foo',
+ 'extra' => array()
+ );
+
+ $event = $processor->process($event);
+
+ $this->assertArrayHasKey('file', $event['extra']);
+ $this->assertArrayHasKey('line', $event['extra']);
+ $this->assertArrayHasKey('class', $event['extra']);
+ $this->assertArrayHasKey('function', $event['extra']);
+ }
+}
View
44 tests/ZendTest/Log/Processor/RequestIdTest.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Log
+ */
+
+namespace ZendTest\Log\Processor;
+
+use Zend\Log\Processor\RequestId;
+
+/**
+ * @category Zend
+ * @package Zend_Log
+ * @subpackage UnitTests
+ * @group Zend_Log
+ */
+class RequestIdTest extends \PHPUnit_Framework_TestCase
+{
+
+ public function testProcess()
+ {
+ $processor = new RequestId();
+
+ $event = array(
+ 'timestamp' => '',
+ 'priority' => 1,
+ 'priorityName' => 'ALERT',
+ 'message' => 'foo',
+ 'extra' => array()
+ );
+
+ $eventA = $processor->process($event);
+ $this->assertArrayHasKey('requestId', $eventA['extra']);
+
+ $eventB = $processor->process($event);
+ $this->assertArrayHasKey('requestId', $eventB['extra']);
+
+ $this->assertEquals($eventA['extra']['requestId'], $eventB['extra']['requestId']);
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.