Skip to content

Commit 65b16a8

Browse files
committed
chore: add new debug middleware server.timing.doctrine
1 parent 0a899ef commit 65b16a8

3 files changed

Lines changed: 112 additions & 2 deletions

File tree

app/Http/Kernel.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class Kernel extends HttpKernel
9191
'cache' => \App\Http\Middleware\CacheMiddleware::class,
9292
'ssl' => \App\Http\Middleware\SSLMiddleware::class,
9393
'auth.user' => \App\Http\Middleware\UserAuthEndpoint::class,
94+
'server.timing.doctrine' => \App\Http\Middleware\ServerTimingDoctrine::class,
9495
];
9596

9697
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
namespace App\Http\Middleware;
4+
5+
use Closure;
6+
use Doctrine\ORM\EntityManagerInterface;
7+
use LaravelDoctrine\ORM\Facades\Registry;
8+
use models\utils\SilverstripeBaseModel;
9+
use Psr\Log\LoggerInterface;
10+
use Symfony\Component\HttpFoundation\Response;
11+
12+
class ServerTimingDoctrine
13+
{
14+
/** @var EntityManagerInterface */
15+
private EntityManagerInterface $em;
16+
17+
18+
public function __construct()
19+
{
20+
$this->em = Registry::getManager(SilverstripeBaseModel::EntityManager);
21+
}
22+
23+
public function handle($request, Closure $next): Response
24+
{
25+
$start = microtime(true);
26+
$conn = $this->em->getConnection();
27+
$cfg = $conn->getConfiguration();
28+
29+
$dbMs = 0.0;
30+
31+
// --- DBAL 2.x: DebugStack ---
32+
if (class_exists(\Doctrine\DBAL\Logging\DebugStack::class) && method_exists($cfg, 'setSQLLogger')) {
33+
$debugStack = new \Doctrine\DBAL\Logging\DebugStack();
34+
$prevLogger = $cfg->getSQLLogger() ?? null;
35+
$cfg->setSQLLogger($debugStack);
36+
37+
try {
38+
/** @var Response $response */
39+
$response = $next($request);
40+
} finally {
41+
foreach ($debugStack->queries as $q) {
42+
$dbMs += isset($q['executionMS']) ? (float) $q['executionMS'] : 0.0;
43+
}
44+
$cfg->setSQLLogger($prevLogger);
45+
}
46+
47+
// --- DBAL 3.x: Logging\Middleware (PSR-3) ---
48+
} elseif (class_exists(\Doctrine\DBAL\Logging\Middleware::class) && method_exists($cfg, 'setMiddlewares')) {
49+
50+
51+
$collector = new class implements LoggerInterface {
52+
public float $dbMs = 0.0;
53+
public function log($level, $message, array $context = []): void {
54+
if (isset($context['duration_ms'])) {
55+
$this->dbMs += (float) $context['duration_ms'];
56+
} elseif (isset($context['executionMS'])) {
57+
$this->dbMs += (float) $context['executionMS'];
58+
} elseif (isset($context['duration'])) {
59+
$this->dbMs += (float) $context['duration'];
60+
}
61+
}
62+
public function emergency($m, array $c = []):void { $this->log('emergency', $m, $c); }
63+
public function alert($m, array $c = []):void { $this->log('alert', $m, $c); }
64+
public function critical($m, array $c = []):void { $this->log('critical', $m, $c); }
65+
public function error($m, array $c = []):void { $this->log('error', $m, $c); }
66+
public function warning($m, array $c = []):void { $this->log('warning', $m, $c); }
67+
public function notice($m, array $c = []) :void { $this->log('notice', $m, $c); }
68+
public function info($m, array $c = []):void { $this->log('info', $m, $c); }
69+
public function debug($m, array $c = []):void { $this->log('debug', $m, $c); }
70+
};
71+
72+
$mw = new \Doctrine\DBAL\Logging\Middleware($collector);
73+
$prev = method_exists($cfg, 'getMiddlewares') ? $cfg->getMiddlewares() : [];
74+
$cfg->setMiddlewares(array_merge($prev, [$mw]));
75+
76+
try {
77+
/** @var Response $response */
78+
$response = $next($request);
79+
} finally {
80+
$dbMs = $collector->dbMs;
81+
$cfg->setMiddlewares($prev);
82+
}
83+
84+
// --- Fallback
85+
} else {
86+
/** @var Response $response */
87+
$response = $next($request);
88+
}
89+
90+
91+
$totalMs = (microtime(true) - $start) * 1000.0;
92+
$bootMs = defined('LARAVEL_START') ? max(($start - LARAVEL_START) * 1000.0, 0.0) : 0.0;
93+
$appMs = max($totalMs - $dbMs, 0.0);
94+
95+
// Al setear el header:
96+
$response->headers->set(
97+
'Server-Timing',
98+
sprintf('boot;dur=%.1f, db;dur=%.1f, app;dur=%.1f, total;dur=%.1f', $bootMs, $dbMs, $appMs, $totalMs)
99+
);
100+
$response->headers->set('Timing-Allow-Origin', '*');
101+
102+
return $response;
103+
}
104+
}

routes/public_api.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,12 @@
8989

9090
// summits
9191
Route::group(['prefix' => 'summits'], function () {
92-
Route::get('', ['middleware' => 'cache:' . Config::get('cache_api_response.get_summit_response_lifetime', 600), 'uses' => 'OAuth2SummitApiController@getSummits']);
92+
Route::get('', [
93+
'middleware' =>[
94+
'server.timing.doctrine',
95+
'cache:' . Config::get('cache_api_response.get_summit_response_lifetime', 1200)
96+
],
97+
'uses' => 'OAuth2SummitApiController@getSummits']);
9398

9499
Route::group(['prefix' => 'all'], function () {
95100

@@ -343,4 +348,4 @@
343348
// user stories
344349
Route::group(array('prefix' => 'user-stories'), function () {
345350
Route::get('', 'OAuth2UserStoriesApiController@getAllUserStories');
346-
});
351+
});

0 commit comments

Comments
 (0)