Skip to content

Commit 0c6eee6

Browse files
alekittoJean85ste93cry
authored
Add support for distributed tracing of the Symfony HTTP client requests (#606)
Co-authored-by: Alessandro Lai <[email protected]> Co-authored-by: Stefano Arlandini <[email protected]>
1 parent 6db5a35 commit 0c6eee6

32 files changed

+1020
-7
lines changed

.github/workflows/tests.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ jobs:
6363
- name: Setup Problem Matchers for PHPUnit
6464
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
6565

66+
- name: Update PHPUnit
67+
run: composer require --dev phpunit/phpunit ^9.3.9 --no-update
68+
if: matrix.php == '8.0' && matrix.dependencies == 'lowest'
69+
6670
- name: Install dependencies
6771
uses: ramsey/composer-install@v1
6872
with:
@@ -112,7 +116,7 @@ jobs:
112116
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
113117

114118
- name: Remove optional packages
115-
run: composer remove doctrine/dbal doctrine/doctrine-bundle symfony/messenger symfony/twig-bundle symfony/cache --dev --no-update
119+
run: composer remove doctrine/dbal doctrine/doctrine-bundle symfony/messenger symfony/twig-bundle symfony/cache symfony/http-client --dev --no-update
116120

117121
- name: Install dependencies
118122
uses: ramsey/composer-install@v1

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Add support for tracing of the Symfony HTTP client requests (#606)
6+
57
## 4.3.0 (2022-05-30)
68
- Fix compatibility issue with Symfony >= 6.1.0 (#635)
79
- Add `TracingDriverConnectionInterface::getNativeConnection()` method to get the original driver connection (#597)

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"symfony/cache": "^4.4.20||^5.0.11||^6.0",
5555
"symfony/dom-crawler": "^4.4.20||^5.0.11||^6.0",
5656
"symfony/framework-bundle": "^4.4.20||^5.0.11||^6.0",
57+
"symfony/http-client": "^4.4.20||^5.0.11||^6.0",
5758
"symfony/messenger": "^4.4.20||^5.0.11||^6.0",
5859
"symfony/monolog-bundle": "^3.4",
5960
"symfony/phpunit-bridge": "^5.2.6||^6.0",

phpstan-baseline.neon

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ parameters:
105105
count: 1
106106
path: src/DependencyInjection/SentryExtension.php
107107

108+
-
109+
message: "#^Parameter \\#2 \\$config of method Sentry\\\\SentryBundle\\\\DependencyInjection\\\\SentryExtension\\:\\:registerHttpClientTracingConfiguration\\(\\) expects array\\<string, mixed\\>, mixed given\\.$#"
110+
count: 1
111+
path: src/DependencyInjection/SentryExtension.php
112+
108113
-
109114
message: "#^Parameter \\#2 \\$config of method Sentry\\\\SentryBundle\\\\DependencyInjection\\\\SentryExtension\\:\\:registerMessengerListenerConfiguration\\(\\) expects array\\<string, mixed\\>, mixed given\\.$#"
110115
count: 1
@@ -122,7 +127,7 @@ parameters:
122127

123128
-
124129
message: "#^Parameter \\#2 \\$config of method Symfony\\\\Component\\\\DependencyInjection\\\\Extension\\\\Extension\\:\\:isConfigEnabled\\(\\) expects array, mixed given\\.$#"
125-
count: 3
130+
count: 4
126131
path: src/DependencyInjection/SentryExtension.php
127132

128133
-
@@ -235,6 +240,31 @@ parameters:
235240
count: 1
236241
path: src/Tracing/Doctrine/DBAL/TracingStatementForV3.php
237242

243+
-
244+
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\AbstractTraceableHttpClient\\:\\:request\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#"
245+
count: 1
246+
path: src/Tracing/HttpClient/AbstractTraceableHttpClient.php
247+
248+
-
249+
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\AbstractTraceableResponse\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
250+
count: 1
251+
path: src/Tracing/HttpClient/AbstractTraceableResponse.php
252+
253+
-
254+
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\TraceableHttpClientForV6\\:\\:withOptions\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#"
255+
count: 1
256+
path: src/Tracing/HttpClient/TraceableHttpClientForV6.php
257+
258+
-
259+
message: "#^Call to an undefined method Symfony\\\\Contracts\\\\HttpClient\\\\ResponseInterface\\:\\:toStream\\(\\)\\.$#"
260+
count: 1
261+
path: src/Tracing/HttpClient/TraceableResponseForV5.php
262+
263+
-
264+
message: "#^Call to an undefined method Symfony\\\\Contracts\\\\HttpClient\\\\ResponseInterface\\:\\:toStream\\(\\)\\.$#"
265+
count: 1
266+
path: src/Tracing/HttpClient/TraceableResponseForV6.php
267+
238268
-
239269
message: "#^Cannot access offset 'sample_rate' on mixed\\.$#"
240270
count: 1
@@ -410,3 +440,12 @@ parameters:
410440
count: 1
411441
path: tests/Tracing/Doctrine/DBAL/TracingStatementForV2Test.php
412442

443+
-
444+
message: "#^Parameter \\#1 \\$responses of method Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\AbstractTraceableHttpClient\\:\\:stream\\(\\) expects iterable\\<\\(int\\|string\\), Symfony\\\\Contracts\\\\HttpClient\\\\ResponseInterface\\>\\|Symfony\\\\Contracts\\\\HttpClient\\\\ResponseInterface, stdClass given\\.$#"
445+
count: 1
446+
path: tests/Tracing/HttpClient/TraceableHttpClientTest.php
447+
448+
-
449+
message: "#^Parameter \\#2 \\$responses of static method Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\AbstractTraceableResponse\\:\\:stream\\(\\) expects iterable\\<Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\AbstractTraceableResponse\\>, array\\<int, stdClass\\> given\\.$#"
450+
count: 1
451+
path: tests/Tracing/HttpClient/TraceableResponseTest.php

phpstan.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ parameters:
1212
- src/aliases.php
1313
- src/Tracing/Doctrine/DBAL/TracingStatementForV2.php
1414
- src/Tracing/Doctrine/DBAL/TracingDriverForV2.php
15+
- src/Tracing/HttpClient/TraceableHttpClientForV4.php
16+
- src/Tracing/HttpClient/TraceableHttpClientForV5.php
1517
- tests/End2End/App
1618
- tests/Tracing/Doctrine/DBAL/TracingDriverForV2Test.php
1719
- tests/EventListener/Fixtures/UserWithoutIdentifierStub.php

psalm-baseline.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@
5050
<code>$params</code>
5151
</MoreSpecificImplementedParamType>
5252
</file>
53+
<file src="src/Tracing/HttpClient/TraceableResponseForV5.php">
54+
<UndefinedInterfaceMethod occurrences="1">
55+
<code>toStream</code>
56+
</UndefinedInterfaceMethod>
57+
</file>
58+
<file src="src/Tracing/HttpClient/TraceableResponseForV6.php">
59+
<UndefinedInterfaceMethod occurrences="1">
60+
<code>toStream</code>
61+
</UndefinedInterfaceMethod>
62+
</file>
5363
<file src="src/aliases.php">
5464
<MissingDependency occurrences="1">
5565
<code>TracingDriverForV2</code>
@@ -63,4 +73,23 @@
6373
<code>PostResponseEvent</code>
6474
</UndefinedClass>
6575
</file>
76+
<file src="src/DependencyInjection/Compiler/CacheTracingPass.php">
77+
<UndefinedDocblockClass occurrences="1">
78+
<code>$container-&gt;getParameter('sentry.tracing.cache.enabled')</code>
79+
</UndefinedDocblockClass>
80+
</file>
81+
<file src="src/DependencyInjection/Compiler/HttpClientTracingPass.php">
82+
<UndefinedDocblockClass occurrences="2">
83+
<code>$container-&gt;getParameter('sentry.tracing.enabled')</code>
84+
<code>$container-&gt;getParameter('sentry.tracing.http_client.enabled')</code>
85+
</UndefinedDocblockClass>
86+
</file>
87+
<file src="src/DependencyInjection/Compiler/DbalTracingPass.php">
88+
<UndefinedDocblockClass occurrences="4">
89+
<code>$container-&gt;getParameter('sentry.tracing.enabled')</code>
90+
<code>$container-&gt;getParameter('sentry.tracing.dbal.enabled')</code>
91+
<code>$container-&gt;getParameter('sentry.tracing.dbal.connections')</code>
92+
<code>$container-&gt;getParameter('doctrine.connections')</code>
93+
</UndefinedDocblockClass>
94+
</file>
6695
</files>

psalm.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
<directory name="src" />
1212
<ignoreFiles>
1313
<file name="src/Tracing/Doctrine/DBAL/TracingStatementForV2.php" />
14+
<file name="src/Tracing/HttpClient/TraceableHttpClientForV4.php" />
15+
<file name="src/Tracing/HttpClient/TraceableHttpClientForV5.php" />
1416
<directory name="vendor" />
1517
</ignoreFiles>
1618
</projectFiles>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\DependencyInjection\Compiler;
6+
7+
use Sentry\SentryBundle\Tracing\HttpClient\TraceableHttpClient;
8+
use Sentry\State\HubInterface;
9+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
10+
use Symfony\Component\DependencyInjection\ContainerBuilder;
11+
use Symfony\Component\DependencyInjection\Reference;
12+
13+
final class HttpClientTracingPass implements CompilerPassInterface
14+
{
15+
/**
16+
* {@inheritdoc}
17+
*/
18+
public function process(ContainerBuilder $container): void
19+
{
20+
if (!$container->getParameter('sentry.tracing.enabled') || !$container->getParameter('sentry.tracing.http_client.enabled')) {
21+
return;
22+
}
23+
24+
foreach ($container->findTaggedServiceIds('http_client.client') as $id => $tags) {
25+
$container->register('.sentry.traceable.' . $id, TraceableHttpClient::class)
26+
->setDecoratedService($id)
27+
->setArgument(0, new Reference('.sentry.traceable.' . $id . '.inner'))
28+
->setArgument(1, new Reference(HubInterface::class))
29+
->addTag('kernel.reset', ['method' => 'reset']);
30+
}
31+
}
32+
}

src/DependencyInjection/Configuration.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
1515
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
1616
use Symfony\Component\Config\Definition\ConfigurationInterface;
17+
use Symfony\Component\HttpClient\HttpClient;
1718
use Symfony\Component\Messenger\MessageBusInterface;
1819

1920
final class Configuration implements ConfigurationInterface
@@ -184,6 +185,9 @@ private function addDistributedTracingSection(ArrayNodeDefinition $rootNode): vo
184185
->arrayNode('cache')
185186
->{class_exists(CacheItem::class) ? 'canBeDisabled' : 'canBeEnabled'}()
186187
->end()
188+
->arrayNode('http_client')
189+
->{class_exists(HttpClient::class) ? 'canBeDisabled' : 'canBeEnabled'}()
190+
->end()
187191
->arrayNode('console')
188192
->addDefaultsIfNotSet()
189193
->fixXmlConfig('excluded_command')

src/DependencyInjection/SentryExtension.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
use Symfony\Component\DependencyInjection\Loader;
3838
use Symfony\Component\DependencyInjection\Reference;
3939
use Symfony\Component\ErrorHandler\Error\FatalError;
40+
use Symfony\Component\HttpClient\HttpClient;
4041
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
4142

4243
final class SentryExtension extends ConfigurableExtension
@@ -74,6 +75,7 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
7475
$this->registerDbalTracingConfiguration($container, $mergedConfig['tracing']);
7576
$this->registerTwigTracingConfiguration($container, $mergedConfig['tracing']);
7677
$this->registerCacheTracingConfiguration($container, $mergedConfig['tracing']);
78+
$this->registerHttpClientTracingConfiguration($container, $mergedConfig['tracing']);
7779
}
7880

7981
/**
@@ -247,6 +249,21 @@ private function registerCacheTracingConfiguration(ContainerBuilder $container,
247249
$container->setParameter('sentry.tracing.cache.enabled', $isConfigEnabled);
248250
}
249251

252+
/**
253+
* @param array<string, mixed> $config
254+
*/
255+
private function registerHttpClientTracingConfiguration(ContainerBuilder $container, array $config): void
256+
{
257+
$isConfigEnabled = $this->isConfigEnabled($container, $config)
258+
&& $this->isConfigEnabled($container, $config['http_client']);
259+
260+
if ($isConfigEnabled && !class_exists(HttpClient::class)) {
261+
throw new LogicException('Http client tracing support cannot be enabled because the symfony/http-client Composer package is not installed.');
262+
}
263+
264+
$container->setParameter('sentry.tracing.http_client.enabled', $isConfigEnabled);
265+
}
266+
250267
/**
251268
* @param string[] $integrations
252269
* @param array<string, mixed> $config

0 commit comments

Comments
 (0)