Skip to content

Commit dac7f3b

Browse files
committed
feature #42195 [WebProfilerBundle] Redesigned the log section (javiereguiluz)
This PR was squashed before being merged into the 5.4 branch. Discussion ---------- [WebProfilerBundle] Redesigned the log section | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #42155 | License | MIT | Doc PR | - This PR is not fully polished, but it's ready for review, both code/design and UX/usability. The main missing feature is dark mode styles. ### Before The logs were divided in sections (that's the main issue reported in #42155). If the app had errors, we displayed errors section first: ![before-error](https://user-images.githubusercontent.com/73419/126186615-8407abe3-e54f-41e7-bf43-f1aaf09ebdf3.png) If there are no errors but there are deprecations, we display that section: ![before-deprecation](https://user-images.githubusercontent.com/73419/126186625-3e5915eb-a824-4497-8f95-aeaf81d003cf.png) Abut filtering data, it depends on each section. For example, some allow to filter by log channel: ![before-filter-channel](https://user-images.githubusercontent.com/73419/126186644-49f039c8-d7ce-4790-abb1-c311a57111e7.gif) And others allow to filter by priority: ![before-filter-priority](https://user-images.githubusercontent.com/73419/126186656-2447dc54-91eb-4b64-bd5d-c35e4aaedaaa.gif) ### After This PR proposes to display a single table with all the logs (and separate the "container compilation" logs because they are a bit different than the others): ![after-logs](https://user-images.githubusercontent.com/73419/126186675-d9df2990-0e3c-491a-b331-4c022b64adbe.png) **Question**: log timestamps now display milliseconds. Do you like this or is it enough with seconds? Deprecations and errors are now more highlighted on each row (this needs a bit more polishing): ![after-deprecation-error](https://user-images.githubusercontent.com/73419/126186699-220055ef-1d57-4e5c-95dc-791238dc22b3.png) Filters are now super dynamic and always available: ![after-filters](https://user-images.githubusercontent.com/73419/126186731-d147e642-d7ab-4047-845c-3943187a1f00.gif) Container logs are still available at the bottom of the page: ![after-container](https://user-images.githubusercontent.com/73419/126186743-02ced909-2871-4491-b764-46194f89287a.gif) So, what do you think? Commits ------- bcb3329279 [WebProfilerBundle] Redesigned the log section
2 parents ea1a3f9 + d4b2daf commit dac7f3b

File tree

1 file changed

+77
-1
lines changed

1 file changed

+77
-1
lines changed

DataCollector/LoggerDataCollector.php

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
2828
private $containerPathPrefix;
2929
private $currentRequest;
3030
private $requestStack;
31+
private $processedLogs;
3132

3233
public function __construct(object $logger = null, string $containerPathPrefix = null, RequestStack $requestStack = null)
3334
{
@@ -80,6 +81,81 @@ public function getLogs()
8081
return $this->data['logs'] ?? [];
8182
}
8283

84+
public function getProcessedLogs()
85+
{
86+
if (null !== $this->processedLogs) {
87+
return $this->processedLogs;
88+
}
89+
90+
$rawLogs = $this->getLogs();
91+
if ([] === $rawLogs) {
92+
return $this->processedLogs = $rawLogs;
93+
}
94+
95+
$logs = [];
96+
foreach ($this->getLogs()->getValue() as $rawLog) {
97+
$rawLogData = $rawLog->getValue();
98+
99+
if ($rawLogData['priority']->getValue() > 300) {
100+
$logType = 'error';
101+
} elseif (isset($rawLogData['scream']) && false === $rawLogData['scream']->getValue()) {
102+
$logType = 'deprecation';
103+
} elseif (isset($rawLogData['scream']) && true === $rawLogData['scream']->getValue()) {
104+
$logType = 'silenced';
105+
} else {
106+
$logType = 'regular';
107+
}
108+
109+
$logs[] = [
110+
'type' => $logType,
111+
'errorCounter' => isset($rawLogData['errorCounter']) ? $rawLogData['errorCounter']->getValue() : 1,
112+
'timestamp' => $rawLogData['timestamp_rfc3339']->getValue(),
113+
'priority' => $rawLogData['priority']->getValue(),
114+
'priorityName' => $rawLogData['priorityName']->getValue(),
115+
'channel' => $rawLogData['channel']->getValue(),
116+
'message' => $rawLogData['message'],
117+
'context' => $rawLogData['context'],
118+
];
119+
}
120+
121+
// sort logs from oldest to newest
122+
usort($logs, static function ($logA, $logB) {
123+
return $logA['timestamp'] <=> $logB['timestamp'];
124+
});
125+
126+
return $this->processedLogs = $logs;
127+
}
128+
129+
public function getFilters()
130+
{
131+
$filters = [
132+
'channel' => [],
133+
'priority' => [
134+
'Debug' => 100,
135+
'Info' => 200,
136+
'Warning' => 300,
137+
'Error' => 400,
138+
'Critical' => 500,
139+
'Alert' => 550,
140+
'Emergency' => 600,
141+
],
142+
];
143+
144+
$allChannels = [];
145+
foreach ($this->getProcessedLogs() as $log) {
146+
if ('' === trim($log['channel'])) {
147+
continue;
148+
}
149+
150+
$allChannels[] = $log['channel'];
151+
}
152+
$channels = array_unique($allChannels);
153+
sort($channels);
154+
$filters['channel'] = $channels;
155+
156+
return $filters;
157+
}
158+
83159
public function getPriorities()
84160
{
85161
return $this->data['priorities'] ?? [];
@@ -132,7 +208,7 @@ private function getContainerDeprecationLogs(): array
132208
$logs = [];
133209
foreach (unserialize($logContent) as $log) {
134210
$log['context'] = ['exception' => new SilencedErrorContext($log['type'], $log['file'], $log['line'], $log['trace'], $log['count'])];
135-
$log['timestamp'] = $bootTime;
211+
$log['timestamp'] = (new \DateTimeImmutable())->setTimestamp($bootTime)->format(\DateTimeInterface::RFC3339_EXTENDED);
136212
$log['priority'] = 100;
137213
$log['priorityName'] = 'DEBUG';
138214
$log['channel'] = null;

0 commit comments

Comments
 (0)