Skip to content

Commit

Permalink
[HttpKernel] Use VarDumper in the Logs&Events panels of the profiler
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-grekas authored and wouterj committed Sep 17, 2016
1 parent 41a7649 commit eddecbd
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 230 deletions.
Expand Up @@ -45,7 +45,7 @@

{% for dump in collector.getDumps('html') %}
<div class="sf-dump sf-reset">
<h3>In
<span class="metadata">In
{% if dump.line %}
{% set link = dump.file|file_link(dump.line) %}
{% if link %}
Expand All @@ -56,10 +56,8 @@
{% else %}
{{ dump.name }}
{% endif %}
<small>line {{ dump.line }}</small>

<a class="text-small sf-toggle" data-toggle-selector="#sf-trace-{{ loop.index0 }}" data-toggle-alt-content="Hide code">Show code</a>
</h3>
line <a class="text-small sf-toggle" data-toggle-selector="#sf-trace-{{ loop.index0 }}">{{ dump.line }}</a>:
</span>

<div class="sf-dump-compact hidden" id="sf-trace-{{ loop.index0 }}">
<div class="trace">
Expand Down
Expand Up @@ -3,12 +3,11 @@
{% import _self as helper %}

{% block toolbar %}
{% if collector.counterrors or collector.countdeprecations or collector.countscreams %}
{% if collector.counterrors or collector.countdeprecations or collector.countwarnings %}
{% set icon %}
{% set status_color = collector.counterrors ? 'red' : collector.countdeprecations ? 'yellow' : '' %}
{% set error_count = collector.counterrors + collector.countdeprecations %}
{% set status_color = collector.counterrors ? 'red' : 'yellow' %}
{{ include('@WebProfiler/Icon/logger.svg') }}
<span class="sf-toolbar-value">{{ error_count }}</span>
<span class="sf-toolbar-value">{{ collector.counterrors ?: (collector.countdeprecations + collector.countwarnings) }}</span>
{% endset %}

{% set text %}
Expand All @@ -18,13 +17,13 @@
</div>

<div class="sf-toolbar-info-piece">
<b>Deprecated Calls</b>
<span class="sf-toolbar-status sf-toolbar-status-{{ collector.countdeprecations ? 'yellow' }}">{{ collector.countdeprecations|default(0) }}</span>
<b>Warnings</b>
<span class="sf-toolbar-status sf-toolbar-status-{{ collector.countwarnings ? 'yellow' }}">{{ collector.countwarnings|default(0) }}</span>
</div>

<div class="sf-toolbar-info-piece">
<b>Silenced Errors</b>
<span class="sf-toolbar-status">{{ collector.countscreams|default(0) }}</span>
<b>Deprecations</b>
<span class="sf-toolbar-status sf-toolbar-status-{{ collector.countdeprecations ? 'yellow' }}">{{ collector.countdeprecations|default(0) }}</span>
</div>
{% endset %}

Expand All @@ -33,12 +32,12 @@
{% endblock %}

{% block menu %}
<span class="label label-status-{{ collector.counterrors ? 'error' : collector.countdeprecations ? 'warning' }} {{ collector.logs is empty ? 'disabled' }}">
<span class="label label-status-{{ collector.counterrors ? 'error' : collector.countdeprecations or collector.countwarnings ? 'warning' }} {{ collector.logs is empty ? 'disabled' }}">
<span class="icon">{{ include('@WebProfiler/Icon/logger.svg') }}</span>
<strong>Logs</strong>
{% if collector.counterrors or collector.countdeprecations %}
{% if collector.counterrors or collector.countdeprecations or collector.countwarnings %}
<span class="count">
<span>{{ collector.counterrors ?: collector.countdeprecations }}</span>
<span>{{ collector.counterrors ?: (collector.countdeprecations + collector.countwarnings) }}</span>
</span>
{% endif %}
</span>
Expand All @@ -55,9 +54,9 @@
{# sort collected logs in groups #}
{% set deprecation_logs, debug_logs, info_and_error_logs, silenced_logs = [], [], [], [] %}
{% for log in collector.logs %}
{% if log.context.errorCount is defined and log.context.type is defined and log.context.type in ['E_DEPRECATED', 'E_USER_DEPRECATED'] %}
{% if log.scream is defined and not log.scream %}
{% set deprecation_logs = deprecation_logs|merge([log]) %}
{% elseif log.context.scream is defined and log.context.scream == true %}
{% elseif log.scream is defined and log.scream %}
{% set silenced_logs = silenced_logs|merge([log]) %}
{% elseif log.priorityName == 'DEBUG' %}
{% set debug_logs = debug_logs|merge([log]) %}
Expand All @@ -68,7 +67,7 @@

<div class="sf-tabs">
<div class="tab">
<h3 class="tab-title">Info. &amp; Errors <span class="badge">{{ info_and_error_logs|length }}</span></h3>
<h3 class="tab-title">Info. &amp; Errors <span class="badge status-{{ collector.counterrors ? 'error' : collector.countwarnings ? 'warning' }}">{{ collector.counterrors ?: info_and_error_logs|length }}</span></h3>

<div class="tab-content">
{% if info_and_error_logs is empty %}
Expand All @@ -84,7 +83,7 @@
<div class="tab">
{# 'deprecation_logs|length' is not used because deprecations are
now grouped and the group count doesn't match the message count #}
<h3 class="tab-title">Deprecations <span class="badge">{{ collector.countdeprecations|default(0) }}</span></h3>
<h3 class="tab-title">Deprecations <span class="badge status-{{ collector.countdeprecations ? 'warning' }}">{{ collector.countdeprecations|default(0) }}</span></h3>

<div class="tab-content">
{% if deprecation_logs is empty %}
Expand Down Expand Up @@ -112,7 +111,7 @@
</div>

<div class="tab">
<h3 class="tab-title">Silenced Errors <span class="badge">{{ collector.countscreams|default(0) }}</span></h3>
<h3 class="tab-title">Silenced PHP Notices<span class="badge">{{ collector.countscreams|default(0) }}</span></h3>

<div class="tab-content">
{% if silenced_logs is empty %}
Expand All @@ -138,26 +137,32 @@
<tr>
<th>{{ show_level ? 'Level' : 'Time' }}</th>
{% if channel_is_defined %}<th>Channel</th>{% endif %}
<th>Message</th>
<th class="full-width">Message</th>
</tr>
</thead>

<tbody>
{% for log in logs %}
{% set css_class = is_deprecation ? ''
: log.priorityName in ['CRITICAL', 'ERROR', 'ALERT', 'EMERGENCY'] ? 'status-error'
: log.priorityName in ['NOTICE', 'WARNING'] ? 'status-warning'
: log.priorityName == 'WARNING' ? 'status-warning'
%}
<tr class="{{ css_class }}">
<td class="font-normal text-small">
<td class="font-normal text-small" nowrap>
{% if show_level %}
<span class="colored text-bold nowrap">{{ log.priorityName }}</span>
<span class="colored text-bold">{{ log.priorityName }}</span>
{% endif %}
<span class="text-muted nowrap newline">{{ log.timestamp|date('H:i:s') }}</span>
<span class="text-muted newline">{{ log.timestamp|date('H:i:s') }}</span>
</td>

{% if channel_is_defined %}
<td class="font-normal text-small text-bold nowrap">{{ log.channel }}</td>
<td class="font-normal text-small text-bold" nowrap>
{{ log.channel }}
{% if log.errorCount is defined and log.errorCount > 1 %}
<span class="text-muted">({{ log.errorCount }} times)</span>
{% endif %}
</td>

{% endif %}

<td class="font-normal">{{ helper.render_log_message(category, loop.index, log, is_deprecation) }}</td>
Expand All @@ -168,69 +173,31 @@
{% endmacro %}

{% macro render_log_message(category, log_index, log, is_deprecation = false) %}
{{ log.message }}

{% if log.context.errorCount is defined and log.context.errorCount > 1 %}
<span class="text-small text-bold">({{ log.context.errorCount }} times)</span>
{% endif %}

{% if is_deprecation %}
{% set trace = log.context.trace|default([]) %}
{% set trace_id = 'sf-call-trace-' ~ category ~ '-' ~ log_index %}
{{ log.message }}

{% set context_id = 'context-' ~ category ~ '-' ~ log_index %}

{% if trace %}
<button class="btn-link text-small sf-toggle" data-toggle-selector="#{{ trace_id }}" data-toggle-alt-content="Hide stack trace">Show stack trace</button>
{% endif %}

{% for index, call in trace if index > 1 %}
{% if index == 2 %}
<ul class="sf-call-trace hidden" id="{{ trace_id }}">
{% endif %}
<span class="metadata">
<a class="btn btn-link text-small sf-toggle" data-toggle-selector="#{{ context_id }}" data-toggle-alt-content="Hide trace">Show trace</a>

{% if call.class is defined %}
{% set from = call.class|abbr_class ~ '::' ~ call.function|abbr_method() %}
{% elseif call.function is defined %}
{% set from = call.function|abbr_method %}
{% elseif call.file is defined %}
{% set from = call.file %}
{% else %}
{% set from = '-' %}
{% endif %}

{% set file_name = (call.file is defined and call.line is defined) ? call.file|replace({'\\': '/'})|split('/')|last %}

<li>
{{ from|raw }}
{% if file_name %}
<span class="text-small">(called from {{ call.file|format_file(call.line, file_name)|raw }})</span>
{% endif %}
</li>

{% if index == trace|length - 1 %}
</ul>
{% endif %}
{% endfor %}
{% else %}
{% if log.context is defined and log.context is not empty %}
{% set context_id = 'context-' ~ category ~ '-' ~ log_index %}
{% set context_dump = profiler_dump(log.context) %}

<div class="metadata">
<strong>Context</strong>:
<div id="{{ context_id }}" class="context sf-toggle-content sf-toggle-hidden">
{{ profiler_dump(log.context.seek('exception').seek('\0Exception\0trace'), maxDepth=2) }}
</div>
</span>
{% elseif log.context is defined and log.context is not empty %}
{{ profiler_dump_log(log.message, log.context) }}

{% if context_dump|length > 120 %}
{{ context_dump[:120] }} ...
{% set context_id = 'context-' ~ category ~ '-' ~ log_index %}

<a class="btn-link text-small sf-toggle" data-toggle-selector="#{{ context_id }}" data-toggle-alt-content="Hide full context">Show full context</a>
<span class="metadata">
<a class="btn btn-link text-small sf-toggle" data-toggle-selector="#{{ context_id }}" data-toggle-alt-content="Hide context">Show context</a>

<div id="{{ context_id }}" class="context">
{{ dump(log.context) }}
</div>
{% else %}
{{ context_dump }}
{% endif %}
<div id="{{ context_id }}" class="context sf-toggle-content sf-toggle-hidden">
{{ profiler_dump(log.context, maxDepth=1) }}
</div>
{% endif %}
</span>
{% else %}
{{ log.message }}
{% endif %}
{% endmacro %}
Expand Up @@ -190,6 +190,9 @@ table tbody ul {
.block {
display: block;
}
.full-width {
width: 100%;
}
.hidden {
display: none;
}
Expand Down Expand Up @@ -806,6 +809,8 @@ tr.status-warning td {
.tab-content > *:first-child {
margin-top: 0;
}
.tab-navigation li .badge.status-warning { background: {{ colors.warning|raw }}; color: #FFF; }
.tab-navigation li .badge.status-error { background: {{ colors.error|raw }}; color: #FFF; }

{# Toggles
========================================================================= #}
Expand Down Expand Up @@ -838,32 +843,8 @@ tr.status-warning td {
{# Logger panel
========================================================================= #}
table.logs .metadata {
color: #777;
display: block;
font-size: 12px;
padding-top: 4px;
}
table.logs .metadata strong {
color: #222;
}
table.logs .metadata .context {
background: #F5F5F5;
color: #222;
}
table.logs .metadata .context pre {
margin: 5px 0;
padding: 5px 10px;
white-space: pre-wrap;
}

table.logs .sf-call-stack {
margin: 1em 0 1em 1.5em;
}
table.logs .sf-call-stack li {
margin-bottom: 5px;
}
table.logs .sf-call-stack abbr {
border: none;
}

{# Doctrine panel
Expand All @@ -889,13 +870,16 @@ table.logs .sf-call-stack abbr {
#collector-content .sf-dump samp {
{{ mixins.monospace_font|raw }}
}
#collector-content .sf-dump h3 {
font-size: 18px;
margin: .5em 0 0;
}
#collector-content .sf-dump h3 a {
#collector-content .sf-dump a {
cursor: pointer;
}
#collector-content .sf-dump pre.sf-dump,
#collector-content .sf-dump .trace {
border: 1px solid #DDD;
background: #FFF;
padding: 10px;
margin: 0.5em 0;
}

#collector-content pre.sf-dump { color: #CC7832; }
#collector-content .sf-dump-str { color: #629755; }
Expand Down Expand Up @@ -924,21 +908,12 @@ table.logs .sf-call-stack abbr {
width: 4em;
}

#collector-content .sf-dump .trace {
border: 1px solid #DDD;
background: #FFF;
padding: 10px;
margin: 1em 0;
}
#collector-content .sf-dump .trace {
font-size: 12px;
}
#collector-content .sf-dump .trace code {
font-size: 14px;
}
#collector-content .sf-dump .trace li {
margin-bottom: 0;
padding: 5px 0;
padding: 0;
}
#collector-content .sf-dump .trace li.selected {
background: rgba(255, 255, 153, 0.5);
Expand Down
18 changes: 18 additions & 0 deletions src/Symfony/Bundle/WebProfilerBundle/Twig/WebProfilerExtension.php
Expand Up @@ -71,6 +71,7 @@ public function getFunctions()

return array(
new \Twig_SimpleFunction('profiler_dump', $profilerDump, array('is_safe' => array('html'), 'needs_environment' => true)),
new \Twig_SimpleFunction('profiler_dump_log', array($this, 'dumpLog'), array('is_safe' => array('html'), 'needs_environment' => true)),
);
}

Expand All @@ -88,6 +89,23 @@ public function dumpData(\Twig_Environment $env, Data $data, $maxDepth = 0)
return str_replace("\n</pre", '</pre', rtrim($dump));
}

public function dumpLog(\Twig_Environment $env, $message, Data $context)
{
$message = twig_escape_filter($env, $message);

if (false === strpos($message, '{')) {
return '<span class="dump-inline">'.$message.'</span>';
}

$replacements = array();
foreach ($context->getRawData()[1] as $k => $v) {
$v = '{'.twig_escape_filter($env, $k).'}';
$replacements['&quot;'.$v.'&quot;'] = $replacements[$v] = $this->dumpData($env, $context->seek($k));
}

return '<span class="dump-inline">'.strtr($message, $replacements).'</span>';
}

/**
* @deprecated since 3.2, to be removed in 4.0. Use the dumpData() method instead.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/Symfony/Bundle/WebProfilerBundle/composer.json
Expand Up @@ -29,6 +29,9 @@
"symfony/dependency-injection": "~2.8|~3.0",
"symfony/stopwatch": "~2.8|~3.0"
},
"conflict": {
"symfony/event-dispatcher": "<3.2"
},
"autoload": {
"psr-4": { "Symfony\\Bundle\\WebProfilerBundle\\": "" },
"exclude-from-classmap": [
Expand Down

0 comments on commit eddecbd

Please sign in to comment.