8000 [Messenger] Improve the profiler panel · symfony/symfony@3d19578 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3d19578

Browse files
ogizanagifabpot
authored andcommitted
[Messenger] Improve the profiler panel
1 parent 64a4a2b commit 3d19578

File tree

8 files changed

+310
-102
lines changed

8 files changed

+310
-102
lines changed

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/messenger.html.twig

Lines changed: 133 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,33 @@
44

55
{% block toolbar %}
66
{% if collector.messages|length > 0 %}
7+
{% set status_color = collector.exceptionsCount ? 'red' %}
78
{% set icon %}
89
{{ include('@WebProfiler/Icon/messenger.svg') }}
910
<span class="sf-toolbar-value">{{ collector.messages|length }}</span>
1011
{% endset %}
1112

12-
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: 'messenger' }) }}
13+
{% set text %}
14+
{% for bus in collector.buses %}
15+
{% set exceptionsCount = collector.exceptionsCount(bus) %}
16+
<div class="sf-toolbar-info-piece">
17+
<b>{{ bus }}</b>
18+
<span
19+
title="{{ exceptionsCount }} message(s) with exceptions"
20+
class="sf-toolbar-status sf-toolbar-status-{{ exceptionsCount ? 'red' }}"
21+
>
22+
{{ collector.messages(bus)|length }}
23+
</span>
24+
</div>
25+
{% endfor %}
26+
{% endset %}
27+
28+
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: 'messenger', status: status_color }) }}
1329
{% endif %}
1430
{% endblock %}
1531

1632
{% block menu %}
17-
<span class="label">
33+
<span class="label {{ collector.exceptionsCount ? 'label-status-error' }}">
1834
<span class="icon">{{ include('@WebProfiler/Icon/messenger.svg') }}</span>
1935
<strong>Messages</strong>
2036

@@ -24,49 +40,128 @@
2440
</span>
2541
{% endblock %}
2642

43+
{% block head %}
44+
{{ parent() }}
45+
<style>
46+
.message-item thead th { position: relative; cursor: pointer; user-select: none; padding-right: 35px; }
47+
.message-item tbody tr td:first-child { width: 115px; }
48+
49+
.message-item .label { float: right; padding: 1px 5px; opacity: .75; margin-left: 5px; }
50+
.message-item .toggle-button { position: absolute; right: 6px; top: 6px; opacity: .5; pointer-events: none }
51+
.message-item .icon svg { height: 24px; width: 24px; }
52+
53+
.message-item .sf-toggle-off .icon-close, .sf-toggle-on .icon-open { display: none; }
54+
.message-item .sf-toggle-off .icon-open, .sf-toggle-on .icon-close { display: block; }
55+
56+
.message-bus .badge.status-some-errors { line-height: 16px; border-bottom: 2px solid #B0413E; }
57+
58+
.message-item .sf-toggle-content.sf-toggle-visible { display: table-row-group; }
59+
</style>
60+
{% endblock %}
61+
2762
{% block panel %}
63+
{% import _self as helper %}
64+
2865
<h2>Messages</h2>
2966

3067
{% if collector.messages is empty %}
3168
<div class="empty">
3269
<p>No messages have been collected.</p>
3370
</div>
3471
{% else %}
35-
<table>
36-
<thead>
37-
<tr>
38-
<th>Bus</th>
39-
<th>Message</th>
40-
<th>Result</th>
41-
</tr>
42-
</thead>
43-
<tbody>
44-
{% for message in collector.messages %}
45-
<tr>
46-
<td>{{ message.bus }}</td>
47-
<td>
48-
{% if message.result.object is defined %}
49-
{{ profiler_dump(message.message.object, maxDepth=2) }}
50-
{% else %}
51-
{{ message.message.type }}
52-
{% endif %}
53-
</td>
54-
<td>
55-
{% if message.result.object is defined %}
56-
{{ profiler_dump(message.result.object, maxDepth=2) }}
57-
{% elseif message.result.type is defined %}
58-
{{ message.result.type }}
59-
{% if message.result.value is defined %}
60-
{{ message.result.value }}
61-
{% endif %}
62-
{% endif %}
63-
{% if message.exception.type is defined %}
64-
{{ message.exception.type }}
65-
{% endif %}
66-
</td>
67-
</tr>
68-
{% endfor %}
69-
</tbody>
70-
</table>
72+
73+
<div class="sf-tabs message-bus">
74+
<div class="tab">
75+
{% set messages = collector.messages %}
76+
{% set exceptionsCount = collector.exceptionsCount %}
77+
<h3 class="tab-title">All<span class="badge {{ exceptionsCount ? exceptionsCount == messages|length ? 'status-error' : 'status-some-errors' }}">{{ messages|length }}</span></h3>
78+
79+
<div class="tab-content">
80+
<p class="text-muted">Ordered list of dispatched messages across all your buses</p>
81+
{{ helper.render_bus_messages(messages, true) }}
82+
</div>
83+
</div>
84+
85+
{% for bus in collector.buses %}
86+
<div class="tab message-bus">
87+
{% set messages = collector.messages(bus) %}
88+
{% set exceptionsCount = collector.exceptionsCount(bus) %}
89+
<h3 class="tab-title">{{ bus }}<span class="badge {{ exceptionsCount ? exceptionsCount == messages|length ? 'status-error' : 'status-some-errors' }}">{{ messages|length }}</span></h3>
90+
91+
<div class="tab-content">
92+
<p class="text-muted">Ordered list of messages dispatched on the <code>{{ bus }}</code> bus</p>
93+
{{ helper.render_bus_messages(messages) }}
94+
</div>
95+
</div>
96+
{% endfor %}
7197
{% endif %}
98+
7299
{% endblock %}
100+
101+
{% macro render_bus_messages(messages, showBus = false) %}
102+
{% set discr = random() %}
103+
{% for i, dispatchCall in messages %}
104+
<table class="message-item">
105+
<thead>
106+
<tr>
107+
<th colspan="2" class="sf-toggle"
108+
data-toggle-selector="#message-item-{{ discr }}-{{ i }}-details"
109+
data-toggle-initial="{{ loop.first ? 'display' }}"
110+
>
111+
<span class="dump-inline">{{ profiler_dump(dispatchCall.message.type) }}</span>
112+
{% if showBus %}
113+
<span class="label">{{ dispatchCall.bus }}</span>
114+
{% endif %}
115+
{% if dispatchCall.exception is defined %}
116+
<span class="label status-error">exception</span>
117+
{% endif %}
118+
<a class="toggle-button">
119+
<span class="icon icon-close">{{ include('@Twig/images/icon-minus-square.svg') }}</span>
120+
<span class="icon icon-open">{{ include('@Twig/images/icon-plus-square.svg') }}</span>
121+
</a>
122+
</th>
123+
</tr>
124+
</thead>
125+
<tbody id="message-item-{{ discr }}-{{ i }}-details" class="sf-toggle-content">
126+
{% if showBus %}
127+
<tr>
128+
<td class="text-bold">Bus</td>
129+
<td>{{ dispatchCall.bus }}</td>
130+
</tr>
131+
{% endif %}
132+
<tr>
133+
<td class="text-bold">Message</td>
134+
<td>{{ profiler_dump(dispatchCall.message.value, maxDepth=2) }}</td>
135+
</tr>
136+
<tr>
137+
<td class="text-bold">Envelope items</td>
138+
<td>
139+
{% for item in dispatchCall.envelopeItems %}
140+
{{ profiler_dump(item) }}
141+
{% else %}
142+
<span class="text-muted">No items</span>
143+
{% endfor %}
144+
</td>
145+
</tr>
146+
<tr>
147+
<td class="text-bold">Result</td>
148+
<td>
149+
{% if dispatchCall.result is defined %}
150+
{{ profiler_dump(dispatchCall.result.seek('value'), maxDepth=2) }}
151+
{% elseif dispatchCall.exception is defined %}
152+
<span class="text-danger">No result as an exception occurred</span>
153+
{% endif %}
154+
</td>
155+
</tr>
156+
{% if dispatchCall.exception is defined %}
157+
<tr>
158+
<td class="text-bold">Exception</td>
159+
<td>
160+
{{ profiler_dump(dispatchCall.exception.value, maxDepth=1) }}
161+
</td>
162+
</tr>
163+
{% endif %}
164+
</tbody>
165+
</table>
166+
{% endfor %}
167+
{% endmacro %}

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ table tbody ul {
215215
.text-muted {
216216
color: #999;
217217
}
218+
.text-danger {
219+
color: {{ colors.error|raw }};
220+
}
218221
.text-bold {
219222
font-weight: bold;
220223
}

src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
1717
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
1818
use Symfony\Component\Messenger\TraceableMessageBus;
19+
use Symfony\Component\VarDumper\Caster\ClassStub;
20+
use Symfony\Component\VarDumper\Cloner\Data;
1921

2022
/**
2123
* @author Samuel Roze <samuel.roze@gmail.com>
@@ -44,13 +46,25 @@ public function collect(Request $request, Response $response, \Exception $except
4446
*/
4547
public function lateCollect()
4648
{
47-
$this->data = array('messages' => array());
49+
$this->data = array('messages' => array(), 'buses' => array_keys($this->traceableBuses));
4850

51+
$messages = array();
4952
foreach ($this->traceableBuses as $busName => $bus) {
5053
foreach ($bus->getDispatchedMessages() as $message) {
51-
$this->data['messages'][] = $this->collectMessage($busName, $message);
54+
$debugRepresentation = $this->cloneVar($this->collectMessage($busName, $message));
55+
$messages[] = array($debugRepresentation, $message['callTime']);
5256
}
5357
}
58+
59+
// Order by call time
60+
usort($messages, function (array $a, array $b): int {
61+
return $a[1] > $b[1] ? 1 : -1;
62+
});
63+
64+
// Keep the messages clones only
65+
$this->data['messages'] = array_map(function (array $item): Data {
66+
return $item[0];
67+
}, $messages);
5468
}
5569

5670
/**
@@ -78,47 +92,51 @@ private function collectMessage(string $busName, array $tracedMessage)
7892

7993
$debugRepresentation = array(
8094
'bus' => $busName,
95+
'envelopeItems' => $tracedMessage['envelopeItems'] ?? null,
8196
'message' => array(
82-
'type' => \get_class($message),
83-
'object' => $this->cloneVar($message),
97+
'type' => new ClassStub(\get_class($message)),
98+
'value' => $message,
8499
),
85100
);
86101

87102
if (array_key_exists('result', $tracedMessage)) {
88103
$result = $tracedMessage['result'];
89-
90-
if (\is_object($result)) {
91-
$debugRepresentation['result'] = array(
92-
'type' => \get_class($result),
93-
'object' => $this->cloneVar($result),
94-
);
95-
} elseif (\is_array($result)) {
96-
$debugRepresentation['result'] = array(
97-
'type' => 'array',
98-
'object' => $this->cloneVar($result),
99-
);
100-
} else {
101-
$debugRepresentation['result'] = array(
102-
'type' => \gettype($result),
103-
'value' => $result,
104-
);
105-
}
104+
$debugRepresentation['result'] = array(
105+
'type' => \is_object($result) ? \get_class($result) : gettype($result),
106+
'value' => $result,
107+
);
106108
}
107109

108110
if (isset($tracedMessage['exception'])) {
109111
$exception = $tracedMessage['exception'];
110112

111113
$debugRepresentation['exception'] = array(
112114
'type' => \get_class($exception),
113-
'message' => $exception->getMessage(),
115+
'value' => $exception,
114116
);
115117
}
116118

117119
return $debugRepresentation;
118120
}
119121

120-
public function getMessages(): array
122+
public function getExceptionsCount(string $bus = null): int
123+
{
124+
return array_reduce($this->getMessages($bus), function (int $carry, Data $message) {
125+
return $carry += isset($message['exception']) ? 1 : 0;
126+
}, 0);
127+
}
128+
129+
public function getMessages(string $bus = null): array
130+
{
131+
$messages = $this->data['messages'] ?? array();
132+
133+
return $bus ? array_filter($messages, function (Data $message) use ($bus): bool {
134+
return $bus === $message['bus'];
135+
}) : $messages;
136+
}
137+
138+
public function getBuses(): array
121139
{
122-
return $this->data['messages'] ?? array();
140+
return $this->data['buses'];
123141
}
124142
}

0 commit comments

Comments
 (0)
0