[BC Break][Debug] #2042 implementation of fatal error logging
This commit is contained in:
parent
6f0a5ad314
commit
7671e5c85d
@ -48,15 +48,18 @@ class FrameworkExtension extends Extension
|
||||
// will be used and everything will still work as expected.
|
||||
$loader->load('translation.xml');
|
||||
|
||||
if ($container->getParameter('kernel.debug')) {
|
||||
$loader->load('debug.xml');
|
||||
$loader->load('debug.xml');
|
||||
|
||||
if ($container->getParameter('kernel.debug')) {
|
||||
// only HttpKernel needs the debug event dispatcher
|
||||
$definition = $container->findDefinition('http_kernel');
|
||||
$arguments = $definition->getArguments();
|
||||
$arguments[0] = new Reference('debug.event_dispatcher');
|
||||
$arguments[2] = new Reference('debug.controller_resolver');
|
||||
$definition->setArguments($arguments);
|
||||
} else {
|
||||
$container->removeDefinition('debug.deprecation_logger_listener');
|
||||
$container->setParameter('debug.container.dump', null);
|
||||
}
|
||||
|
||||
$configuration = $this->getConfiguration($configs, $container);
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parameter key="debug.stopwatch.class">Symfony\Component\Stopwatch\Stopwatch</parameter>
|
||||
<parameter key="debug.container.dump">%kernel.cache_dir%/%kernel.container_class%.xml</parameter>
|
||||
<parameter key="debug.controller_resolver.class">Symfony\Component\HttpKernel\Controller\TraceableControllerResolver</parameter>
|
||||
<parameter key="debug.deprecation_logger_listener.class">Symfony\Component\HttpKernel\EventListener\DeprecationLoggerListener</parameter>
|
||||
<parameter key="debug.errors_logger_listener.class">Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
@ -28,9 +28,17 @@
|
||||
<argument type="service" id="debug.stopwatch" />
|
||||
</service>
|
||||
|
||||
<service id="debug.deprecation_logger_listener" class="%debug.deprecation_logger_listener.class%">
|
||||
<service id="debug.deprecation_logger_listener" class="%debug.errors_logger_listener.class%">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<tag name="monolog.logger" channel="deprecation" />
|
||||
<argument>deprecation</argument>
|
||||
<argument type="service" id="logger" on-invalid="null" />
|
||||
</service>
|
||||
|
||||
<service id="debug.emergency_logger_listener" class="%debug.errors_logger_listener.class%">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<tag name="monolog.logger" channel="emergency" />
|
||||
<argument>emergency</argument>
|
||||
<argument type="service" id="logger" on-invalid="null" />
|
||||
</service>
|
||||
</services>
|
||||
|
@ -31,8 +31,9 @@ class Debug
|
||||
* class loader is also registered.
|
||||
*
|
||||
* @param integer $errorReportingLevel The level of error reporting you want
|
||||
* @param Boolean $displayErrors Display errors (for dev environment) or just log they (production usage)
|
||||
*/
|
||||
public static function enable($errorReportingLevel = null)
|
||||
public static function enable($errorReportingLevel = null, $displayErrors = true)
|
||||
{
|
||||
if (static::$enabled) {
|
||||
return;
|
||||
@ -42,10 +43,10 @@ class Debug
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
ErrorHandler::register($errorReportingLevel);
|
||||
ErrorHandler::register($errorReportingLevel, $displayErrors);
|
||||
if ('cli' !== php_sapi_name()) {
|
||||
ExceptionHandler::register();
|
||||
} elseif (!ini_get('log_errors') || ini_get('error_log')) {
|
||||
} elseif (!ini_get('log_errors') || ini_get('error_log') && $displayErrors) {
|
||||
ini_set('display_errors', 1);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ use Psr\Log\LoggerInterface;
|
||||
* ErrorHandler.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Konstantin Myakshin <koc-dp@yandex.ru>
|
||||
*/
|
||||
class ErrorHandler
|
||||
{
|
||||
@ -43,20 +44,26 @@ class ErrorHandler
|
||||
|
||||
private $reservedMemory;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
private static $logger;
|
||||
private $displayErrors;
|
||||
|
||||
/**
|
||||
* @var LoggerInterface[] Loggers for channels
|
||||
*/
|
||||
private static $loggers = array();
|
||||
|
||||
/**
|
||||
* Registers the error handler.
|
||||
*
|
||||
* @param integer $level The level at which the conversion to Exception is done (null to use the error_reporting() value and 0 to disable)
|
||||
* @param Boolean $displayErrors Display errors (for dev environment) or just log they (production usage)
|
||||
*
|
||||
* @return The registered error handler
|
||||
*/
|
||||
public static function register($level = null)
|
||||
public static function register($level = null, $displayErrors = true)
|
||||
{
|
||||
$handler = new static();
|
||||
$handler->setLevel($level);
|
||||
$handler->setDisplayErrors($displayErrors);
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
set_error_handler(array($handler, 'handle'));
|
||||
@ -71,9 +78,14 @@ class ErrorHandler
|
||||
$this->level = null === $level ? error_reporting() : $level;
|
||||
}
|
||||
|
||||
public static function setLogger(LoggerInterface $logger)
|
||||
public function setDisplayErrors($displayErrors)
|
||||
{
|
||||
self::$logger = $logger;
|
||||
$this->displayErrors = $displayErrors;
|
||||
}
|
||||
|
||||
public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
|
||||
{
|
||||
self::$loggers[$channel] = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,7 +98,7 @@ class ErrorHandler
|
||||
}
|
||||
|
||||
if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) {
|
||||
if (null !== self::$logger) {
|
||||
if (isset(self::$loggers['deprecation'])) {
|
||||
if (version_compare(PHP_VERSION, '5.4', '<')) {
|
||||
$stack = array_map(
|
||||
function ($row) {
|
||||
@ -99,13 +111,13 @@ class ErrorHandler
|
||||
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
|
||||
}
|
||||
|
||||
self::$logger->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack));
|
||||
self::$loggers['deprecation']->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (error_reporting() & $level && $this->level & $level) {
|
||||
if ($this->displayErrors && error_reporting() & $level && $this->level & $level) {
|
||||
throw new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line), 0, $level, $file, $line);
|
||||
}
|
||||
|
||||
@ -124,6 +136,20 @@ class ErrorHandler
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset(self::$loggers['emergency'])) {
|
||||
$fatal = array(
|
||||
'type' => $type,
|
||||
'file' => $error['file'],
|
||||
'line' => $error['line'],
|
||||
);
|
||||
|
||||
self::$loggers['emergency']->emerg($error['message'], $fatal);
|
||||
}
|
||||
|
||||
if (!$this->displayErrors) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get current exception handler
|
||||
$exceptionHandler = set_exception_handler(function() {});
|
||||
restore_exception_handler();
|
||||
|
@ -4,6 +4,7 @@ CHANGELOG
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
* [BC BREAK] renamed `Symfony\Component\HttpKernel\EventListener\DeprecationLoggerListener` to `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener` and changed its constructor
|
||||
* deprecated `Symfony\Component\HttpKernel\Debug\ErrorHandler`, `Symfony\Component\HttpKernel\Debug\ExceptionHandler`,
|
||||
`Symfony\Component\HttpKernel\Exception\FatalErrorException`, and `Symfony\Component\HttpKernel\Exception\FlattenException`
|
||||
* deprecated `Symfony\Component\HttpKernel\Kernel::init()``
|
||||
@ -21,7 +22,7 @@ CHANGELOG
|
||||
* added ControllerReference to create reference of Controllers (used in the FragmentRenderer class)
|
||||
* [BC BREAK] renamed TimeDataCollector::getTotalTime() to
|
||||
TimeDataCollector::getDuration()
|
||||
* updated the MemoryDataCollector to include the memory used in the
|
||||
* updated the MemoryDataCollector to include the memory used in the
|
||||
kernel.terminate event listeners
|
||||
* moved the Stopwatch classes to a new component
|
||||
* added TraceableControllerResolver
|
||||
|
@ -17,23 +17,27 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Injects the logger into the ErrorHandler, so that it can log deprecation errors.
|
||||
* Injects the logger into the ErrorHandler, so that it can log various errors.
|
||||
*
|
||||
* @author Colin Frei <colin@colinfrei.com>
|
||||
* @author Konstantin Myakshin <koc-dp@yandex.ru>
|
||||
*/
|
||||
class DeprecationLoggerListener implements EventSubscriberInterface
|
||||
class ErrorsLoggerListener implements EventSubscriberInterface
|
||||
{
|
||||
private $channel;
|
||||
|
||||
private $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger = null)
|
||||
public function __construct($channel, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->channel = $channel;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function injectLogger()
|
||||
{
|
||||
if (null !== $this->logger) {
|
||||
ErrorHandler::setLogger($this->logger);
|
||||
ErrorHandler::setLogger($this->logger, $this->channel);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user