Custom Doctrine profiling system

Volodymyr Ustinov
2 min readMay 15, 2021

Hi everyone! Just got another idea to share with you — debugging system of queries by Doctrine ORM. This case will be useful for someone like me, that is used just some parts as Doctrine, but not whole Symfony, and want some how debug his queries.

If we will take a look at Symfony — there if very useful component like Profiler. Its really amazing. You can take a look at whole process of your requests! Doctrine section gives to you useful info about time of query, variables in query and counts of total queries. Profiler collect some other amount of info, and what if I want just log only my queries, or for some reason my project not the Symfony one, but with usage of Doctrine. Here i will show how you can combine your custom profiling system with only that info that you want to store, in my case — Doctrine queries.

If you are used Doctrine, then you should some how configure it, this is the first place where we need to add some more — sql logger. In my case i had use Doctrine tools:

$config = Setup::createAnnotationMetadataConfiguration(["/src"], true, "/../var/cache", null, false);
$config->setSQLLogger(new DebugStack());

DebugStack — own Doctrines logging tools, there is another like EchoSQLLogger, all this components implements interface SQLLogger, so can implement your own.

Profiler need such parts like implementations of DataCollectorInterface. I will be used DoctrineDataCollector. Its from package symfony/doctrine-bridge.

DoctrineDataCollector required ManagerRegistry, and this part was not exist in my system, so I did it myself:

new ManagerRegistry i did like this:

/** @var Connection $connection */
$connection = $entityManager->getConnection();
$registry = new ManagerRegistry(
$connection
);

Connection should be taken from Doctrines EntityManager.

Next we should make new DoctrineDataCollector:

$dataCollector = new DoctrineDataCollector($registry);
$dataCollector->addLogger('default', $entityManager->getConfiguration()->getSQLLogger());

You should pass SQLLogger that before we was add at configuration stage of Doctrine.

Finally we should make new Profiler and add our $dataCollector:

$profiler = new Profiler(FileProfilerStorage('file:var/profiler'));
$profiler->add($dataCollector);

Classes FileProfilerStorage, Profiler is part of package symfony/http-kernel, so you need install it.

After we need run collect data by profiler:

$profile = $profiler->collect($request, $response);
$profiler->saveProfile($profile);

Request and Response is used for collecting some data about your uri of request and response code, so we need pass it.

My project is build around component symfony/http-kernel, if your is not, probably you can somehow make your own instances of Request and Response.

Finally we can get data of our profiling like this:

$profiler->loadProfile($profile->getToken())

And the final all parts in one:

Of Course view profiler thru dump is not the best solution, but for example i think its fine.

Thank you for getting to this part of article, hope someone fill find it useful.

--

--

Volodymyr Ustinov

Hi, I’m a software engineer. My career started at 2012. My common ecosystem is backend with PHP