Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Logger register shut down #5875

Merged
merged 3 commits into from

5 participants

@JustInVTime

Fatal runtime errors cause execution of the script to halt, so the registered error handler will not be called to log the error. This PR adds an option to the logger to register a shutdown function to fetch the last error. This error will be logged if it was a fatal runtime error (E_ERROR)

library/Zend/Log/Logger.php
@@ -554,6 +565,40 @@ 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 boolean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney weierophinney added this to the 2.3.0 milestone
@JustInVTime

Bummer, travis fails this test... locally it works fine, when I added the display_errors off setting. Trying suppress error with @ now

@Ocramius Ocramius commented on the diff
library/Zend/Log/Logger.php
@@ -554,6 +565,41 @@ 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)
@Ocramius Collaborator
Ocramius added a note

Maybe a silly question, but is there a specific reason for this method to be on this class?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jaapio

@Ocramius for the same reason why the other methods like registerExceptionHandler and registerErrorHandler exist in this class. But it could be in any class like the other two.

@weierophinney weierophinney self-assigned this
@weierophinney weierophinney merged commit af3a04a into from
@jaapio jaapio deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 3, 2014
  1. Added registerFatalErrorShutdownFunction and test

    JustInVTime authored
  2. Suppress error

    JustInVTime authored
  3. Removed ini_set call in shutdown function

    JustInVTime authored
This page is out of date. Refresh to see the latest.
Showing with 69 additions and 0 deletions.
  1. +46 −0 library/Zend/Log/Logger.php
  2. +23 −0 tests/ZendTest/Log/LoggerTest.php
View
46 library/Zend/Log/Logger.php
@@ -61,6 +61,13 @@ class Logger implements LoggerInterface
protected static $registeredErrorHandler = false;
/**
+ * Registered shutdown error handler
+ *
+ * @var bool
+ */
+ protected static $registeredFatalErrorShutdownFunction = false;
+
+ /**
* Registered exception handler
*
* @var bool
@@ -154,6 +161,10 @@ public function __construct($options = null)
static::registerErrorHandler($this);
}
+ if (isset($options['fatal_error_shutdownfunction']) && $options['fatal_error_shutdownfunction'] === true) {
+ static::registerFatalErrorShutdownFunction($this);
+ }
+
} elseif ($options) {
throw new Exception\InvalidArgumentException('Options must be an array or an object implementing \Traversable ');
}
@@ -554,6 +565,41 @@ 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)
@Ocramius Collaborator
Ocramius added a note

Maybe a silly question, but is there a specific reason for this method to be on this class?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ {
+ // 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
*
View
23 tests/ZendTest/Log/LoggerTest.php
@@ -410,4 +410,27 @@ public function testErrorHandlerWithStreamWriter()
$this->assertContains('test', $contents);
$this->assertContains('second', $contents);
}
+
+ /**
+ * @runInSeparateProcess
+ */
+ public function testRegisterFatalShutdownFunction()
+ {
+ $writer = new MockWriter;
+ $this->logger->addWriter($writer);
+
+ $result = Logger::registerFatalErrorShutdownFunction($this->logger);
+ $this->assertTrue($result);
+
+ // check for single error handler instance
+ $this->assertFalse(Logger::registerFatalErrorShutdownFunction($this->logger));
+
+ $self = $this;
+ register_shutdown_function(function () use ($writer, $self) {
+ $self->assertEquals($writer->events[0]['message'], 'Call to undefined method ZendTest\Log\LoggerTest::callToNonExistingMethod()');
+ });
+
+ // Temporary hide errors, because we don't want the fatal error to fail the test
+ @$this->callToNonExistingMethod();
+ }
}
Something went wrong with that request. Please try again.