Skip to content

Commit 390cace

Browse files
committed
Add doctrine dbal tracing support that is optional to enable
1 parent ed64c02 commit 390cace

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\DependencyInjection\Compiler;
6+
7+
use Sentry\SentryBundle\EventListener\Tracing\DbalListener;
8+
use Sentry\State\HubInterface;
9+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
10+
use Symfony\Component\DependencyInjection\ContainerBuilder;
11+
use Symfony\Component\DependencyInjection\Definition;
12+
13+
class ConnectDbalQueryListenerPass implements CompilerPassInterface
14+
{
15+
/**
16+
* @return void
17+
*/
18+
public function process(ContainerBuilder $container)
19+
{
20+
$config = $container->getExtensionConfig('sentry');
21+
22+
$registerDbalListener = isset($config[0]['register_dbal_listener'])
23+
? $config[0]['register_dbal_listener']
24+
: false;
25+
26+
if ($registerDbalListener && $container->hasDefinition('doctrine.dbal.logger')) {
27+
$container->setDefinition(
28+
'doctrine.dbal.logger',
29+
new Definition(DbalListener::class, [$container->getDefinition(HubInterface::class)])
30+
);
31+
}
32+
}
33+
}

src/DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public function getConfigTreeBuilder(): TreeBuilder
3737
->end()
3838
->end()
3939
->booleanNode('register_error_listener')->defaultTrue()->end()
40+
->booleanNode('register_dbal_listener')->defaultFalse()->end()
4041
->arrayNode('options')
4142
->addDefaultsIfNotSet()
4243
->fixXmlConfig('integration')
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\EventListener\Tracing;
6+
7+
use Doctrine\DBAL\Logging\SQLLogger;
8+
use Sentry\State\HubInterface;
9+
use Sentry\Tracing\Span;
10+
use Sentry\Tracing\SpanContext;
11+
12+
/**
13+
* Getting the logger, tied into dbal seems extremely hard. Cheating the system a bit by putting it in between the
14+
* debug stack logger.
15+
*/
16+
final class DbalListener implements SQLLogger
17+
{
18+
/**
19+
* @var HubInterface The current hub
20+
*/
21+
private $hub;
22+
23+
/**
24+
* @var Span
25+
*/
26+
private $querySpan;
27+
28+
/**
29+
* @param HubInterface $hub The current hub
30+
*/
31+
public function __construct(HubInterface $hub)
32+
{
33+
$this->hub = $hub;
34+
}
35+
36+
/**
37+
* @param string $sql
38+
*/
39+
public function startQuery($sql, ?array $params = null, ?array $types = null)
40+
{
41+
$transaction = $this->hub->getTransaction();
42+
43+
if (!$transaction) {
44+
return;
45+
}
46+
47+
$spanContext = new SpanContext();
48+
$spanContext->setOp('doctrine.query');
49+
$spanContext->setDescription($sql);
50+
51+
$this->querySpan = $transaction->startChild($spanContext);
52+
}
53+
54+
public function stopQuery()
55+
{
56+
if (!$this->querySpan instanceof Span) {
57+
return;
58+
}
59+
60+
$this->querySpan->finish();
61+
}
62+
}

src/SentryBundle.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,18 @@
44

55
namespace Sentry\SentryBundle;
66

7+
use Sentry\SentryBundle\DependencyInjection\Compiler\ConnectDbalQueryListenerPass;
8+
use Symfony\Component\DependencyInjection\ContainerBuilder;
79
use Symfony\Component\HttpKernel\Bundle\Bundle;
810

911
final class SentryBundle extends Bundle
1012
{
1113
public const SDK_IDENTIFIER = 'sentry.php.symfony';
14+
15+
public function build(ContainerBuilder $container): void
16+
{
17+
parent::build($container);
18+
19+
$container->addCompilerPass(new ConnectDbalQueryListenerPass());
20+
}
1221
}

0 commit comments

Comments
 (0)