[Debug] add a screaming mode to ErrorHandler
This commit is contained in:
parent
48c9985e73
commit
5cc817d1bd
@ -32,5 +32,12 @@
|
||||
<argument>deprecation</argument>
|
||||
<argument type="service" id="logger" on-invalid="null" />
|
||||
</service>
|
||||
|
||||
<service id="debug.scream_logger_listener" class="%debug.errors_logger_listener.class%">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<tag name="monolog.logger" channel="scream" />
|
||||
<argument>scream</argument>
|
||||
<argument type="service" id="logger" on-invalid="null" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -3,16 +3,16 @@
|
||||
{% import _self as logger %}
|
||||
|
||||
{% block toolbar %}
|
||||
{% if collector.counterrors or collector.countdeprecations %}
|
||||
{% if collector.counterrors or collector.countdeprecations or collector.countscreams %}
|
||||
{% set icon %}
|
||||
<img width="15" height="28" alt="Logs" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAcCAYAAABoMT8aAAAA4klEQVQ4y2P4//8/AyWYYXgYwOPp6Xnc3t7+P7EYpB6k7+zZs2ADNEjRjIwDAgKWgAywIUfz8+fPVzg7O/8AGeCATQEQnAfi/SAah/wcV1dXvAYUgORANA75ehcXl+/4DHAABRIe+ZrhbgAhTHsDiEgHBA0glA6GfSDiw5mZma+A+sphBlhVVFQ88vHx+Xfu3Ll7QP5haOjjwtuAuGHv3r3NIMNABqh8+/atsaur666vr+9XUlwSHx//AGQANxCbAnEWyGQicRMQ9wBxIQM0qjiBWAFqkB00/glhayBWHwb1AgB38EJsUtxtWwAAAABJRU5ErkJggg==" />
|
||||
{% if collector.counterrors %}
|
||||
{% set status_color = "red" %}
|
||||
{% else %}
|
||||
{% elseif collector.countdeprecations %}
|
||||
{% set status_color = "yellow" %}
|
||||
{% endif %}
|
||||
{% set error_count = collector.counterrors + collector.countdeprecations %}
|
||||
<span class="sf-toolbar-status sf-toolbar-status-{{ status_color }}">{{ error_count }}</span>
|
||||
{% set error_count = collector.counterrors + collector.countdeprecations + collector.countscreams %}
|
||||
<span class="sf-toolbar-status{% if status_color is defined %}} sf-toolbar-status-{{ status_color }}{% endif %}">{{ error_count }}</span>
|
||||
{% endset %}
|
||||
{% set text %}
|
||||
{% if collector.counterrors %}
|
||||
@ -27,6 +27,12 @@
|
||||
<span class="sf-toolbar-status sf-toolbar-status-yellow">{{ collector.countdeprecations }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if collector.countscreams %}
|
||||
<div class="sf-toolbar-info-piece">
|
||||
<b>Silenced Errors</b>
|
||||
<span class="sf-toolbar-status sf-toolbar-status">{{ collector.countscreams }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endset %}
|
||||
{% include '@WebProfiler/Profiler/toolbar_item.html.twig' with { 'link': profiler_url } %}
|
||||
{% endif %}
|
||||
@ -36,8 +42,8 @@
|
||||
<span class="label">
|
||||
<span class="icon"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAgCAYAAAAMq2gFAAABjElEQVRIx2MIDw+vd3R0/GFvb/+fGtjFxeVJSUmJ1f///5nv37/PAMMMzs7OVLMEhoODgy/k5+cHJCYmagAtZAJbRG1L0DEwxCYALeOgiUXbt2+/X1NT8xTEdnd3/wi0SI4mFgHBDCBeCLXoF5BtwkCEpvNAvB8JnydCTwgQR0It+g1kWxNjUQEQOyDhAiL0gNUiWWRDjEUOyMkUZsCoRaMWjVpEvEVkFkGjFmEUqgc+fvx4hVYWIReqzi9evKileaoDslnu3LkTNLQtGk3edLPIycnpL9Bge5pb1NXVdQNosDmGRcAm7F+QgKur6783b95cBQoeRGv1kII3QPOdAoZF8+fPP4PUqnx55syZVKCEI1rLh1hsAbWEZ8aMGaUoFoFcMG3atKdIjfSPISEhawICAlaQgwMDA1f6+/sfB5rzE2Sej4/PD3C7DkjoAHHVoUOHLpSVlX3w8vL6Sa34Alr6Z8WKFaCoMARZxAHEoFZ/HBD3A/FyIF4BxMvIxCC964F4G6hZDMTxQCwJAGWE8pur5kFDAAAAAElFTkSuQmCC" alt="Logger"></span>
|
||||
<strong>Logs</strong>
|
||||
{% if collector.counterrors or collector.countdeprecations %}
|
||||
{% set error_count = collector.counterrors + collector.countdeprecations %}
|
||||
{% if collector.counterrors or collector.countdeprecations or collector.countscreams %}
|
||||
{% set error_count = collector.counterrors + collector.countdeprecations + collector.countscreams %}
|
||||
<span class="count">
|
||||
<span>{{ error_count }}</span>
|
||||
</span>
|
||||
@ -74,7 +80,7 @@
|
||||
{% if collector.logs %}
|
||||
<ul class="alt">
|
||||
{% for log in collector.logs if priority >= 0 and log.priority >= priority or priority < 0 and log.context.type|default(0) == priority %}
|
||||
<li class="{{ cycle(['odd', 'even'], loop.index) }}{% if log.priority >= 400 %} error{% elseif log.priority >= 300 %} warning{% endif %}">
|
||||
<li class="{{ cycle(['odd', 'even'], loop.index) }}{% if log.priority >= 400 %} error{% elseif log.priority >= 300 %} warning{% endif %}{% if log.context.scream is defined %} scream{% endif %}">
|
||||
{{ logger.display_message(loop.index, log) }}
|
||||
</li>
|
||||
{% else %}
|
||||
|
@ -275,6 +275,9 @@ ul.alt li.warning {
|
||||
background-color: #ffcc00;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
ul.alt li.scream, ul.alt li.scream strong {
|
||||
color: gray;
|
||||
}
|
||||
ul.sf-call-stack li {
|
||||
text-size: small;
|
||||
padding: 0 0 0 20px;
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Debug;
|
||||
|
||||
use Psr\Log\LogLevel;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Debug\Exception\ContextErrorException;
|
||||
use Symfony\Component\Debug\Exception\FatalErrorException;
|
||||
@ -44,7 +45,7 @@ class ErrorHandler
|
||||
E_ERROR => 'Error',
|
||||
E_CORE_ERROR => 'Core Error',
|
||||
E_COMPILE_ERROR => 'Compile Error',
|
||||
E_PARSE => 'Parse',
|
||||
E_PARSE => 'Parse Error',
|
||||
);
|
||||
|
||||
private $level;
|
||||
@ -108,7 +109,7 @@ class ErrorHandler
|
||||
* Sets a logger for the given channel.
|
||||
*
|
||||
* @param LoggerInterface $logger A logger interface
|
||||
* @param string $channel The channel associated with the logger (deprecation or emergency)
|
||||
* @param string $channel The channel associated with the logger (deprecation, emergency or scream)
|
||||
*/
|
||||
public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
|
||||
{
|
||||
@ -120,10 +121,6 @@ class ErrorHandler
|
||||
*/
|
||||
public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
|
||||
{
|
||||
if (0 === $this->level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) {
|
||||
if (isset(self::$loggers['deprecation'])) {
|
||||
if (self::$stackedErrorLevels) {
|
||||
@ -182,6 +179,35 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
|
||||
if (isset(self::$loggers['scream']) && !(error_reporting() & $level)) {
|
||||
if (self::$stackedErrorLevels) {
|
||||
self::$stackedErrors[] = func_get_args();
|
||||
} else {
|
||||
switch ($level) {
|
||||
case E_USER_ERROR:
|
||||
case E_RECOVERABLE_ERROR:
|
||||
$logLevel = LogLevel::ERROR;
|
||||
break;
|
||||
|
||||
case E_WARNING:
|
||||
case E_USER_WARNING:
|
||||
$logLevel = LogLevel::WARNING;
|
||||
break;
|
||||
|
||||
default:
|
||||
$logLevel = LogLevel::NOTICE;
|
||||
break;
|
||||
}
|
||||
|
||||
self::$loggers['scream']->log($logLevel, $message, array(
|
||||
'type' => $level,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
'scream' => error_reporting(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -174,6 +174,28 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
$handler->handle(E_USER_DEPRECATED, 'foo', 'foo.php', 12, 'foo');
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
|
||||
$that = $this;
|
||||
$logArgCheck = function ($level, $message, $context) use ($that) {
|
||||
$that->assertEquals('Undefined variable: undefVar', $message);
|
||||
$that->assertArrayHasKey('type', $context);
|
||||
$that->assertEquals($context['type'], E_NOTICE);
|
||||
};
|
||||
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('log')
|
||||
->will($this->returnCallback($logArgCheck))
|
||||
;
|
||||
|
||||
$handler = ErrorHandler::register(E_NOTICE);
|
||||
$handler->setLogger($logger, 'scream');
|
||||
unset($undefVar);
|
||||
@$undefVar++;
|
||||
|
||||
restore_error_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
|
||||
|
@ -46,11 +46,8 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
public function lateCollect()
|
||||
{
|
||||
if (null !== $this->logger) {
|
||||
$this->data = array(
|
||||
'error_count' => $this->logger->countErrors(),
|
||||
'logs' => $this->sanitizeLogs($this->logger->getLogs()),
|
||||
'deprecation_count' => $this->computeDeprecationCount()
|
||||
);
|
||||
$this->data = $this->computeErrorsCount();
|
||||
$this->data['logs'] = $this->sanitizeLogs($this->logger->getLogs());
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,6 +78,11 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0;
|
||||
}
|
||||
|
||||
public function countScreams()
|
||||
{
|
||||
return isset($this->data['scream_count']) ? $this->data['scream_count'] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -119,12 +121,21 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
return $context;
|
||||
}
|
||||
|
||||
private function computeDeprecationCount()
|
||||
private function computeErrorsCount()
|
||||
{
|
||||
$count = 0;
|
||||
$count = array(
|
||||
'error_count' => $this->logger->countErrors(),
|
||||
'deprecation_count' => 0,
|
||||
'scream_count' => 0,
|
||||
);
|
||||
|
||||
foreach ($this->logger->getLogs() as $log) {
|
||||
if (isset($log['context']['type']) && ErrorHandler::TYPE_DEPRECATION === $log['context']['type']) {
|
||||
$count++;
|
||||
if (isset($log['context']['type'])) {
|
||||
if (ErrorHandler::TYPE_DEPRECATION === $log['context']['type']) {
|
||||
++$count['deprecation_count'];
|
||||
} elseif (isset($log['context']['scream'])) {
|
||||
++$count['scream_count'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ class LoggerDataCollectorTest extends \PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* @dataProvider getCollectTestData
|
||||
*/
|
||||
public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount)
|
||||
public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount, $expectedScreamCount)
|
||||
{
|
||||
$logger = $this->getMock('Symfony\Component\HttpKernel\Log\DebugLoggerInterface');
|
||||
$logger->expects($this->once())->method('countErrors')->will($this->returnValue($nb));
|
||||
@ -32,6 +32,7 @@ class LoggerDataCollectorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame($nb, $c->countErrors());
|
||||
$this->assertSame($expectedLogs ? $expectedLogs : $logs, $c->getLogs());
|
||||
$this->assertSame($expectedDeprecationCount, $c->countDeprecations());
|
||||
$this->assertSame($expectedScreamCount, $c->countScreams());
|
||||
}
|
||||
|
||||
public function getCollectTestData()
|
||||
@ -41,28 +42,33 @@ class LoggerDataCollectorTest extends \PHPUnit_Framework_TestCase
|
||||
1,
|
||||
array(array('message' => 'foo', 'context' => array())),
|
||||
null,
|
||||
0
|
||||
0,
|
||||
0,
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(array('message' => 'foo', 'context' => array('foo' => fopen(__FILE__, 'r')))),
|
||||
array(array('message' => 'foo', 'context' => array('foo' => 'Resource(stream)'))),
|
||||
0
|
||||
0,
|
||||
0,
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(array('message' => 'foo', 'context' => array('foo' => new \stdClass()))),
|
||||
array(array('message' => 'foo', 'context' => array('foo' => 'Object(stdClass)'))),
|
||||
0
|
||||
0,
|
||||
0,
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(
|
||||
array('message' => 'foo', 'context' => array('type' => ErrorHandler::TYPE_DEPRECATION)),
|
||||
array('message' => 'foo2', 'context' => array('type' => ErrorHandler::TYPE_DEPRECATION))
|
||||
array('message' => 'foo2', 'context' => array('type' => ErrorHandler::TYPE_DEPRECATION)),
|
||||
array('message' => 'foo3', 'context' => array('type' => E_USER_WARNING, 'scream' => 0)),
|
||||
),
|
||||
null,
|
||||
2
|
||||
2,
|
||||
1,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user