Skip to content

Tracing without Performance #742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"guzzlehttp/psr7": "^1.7 || ^2.0",
"jean85/pretty-package-versions": "^1.5 || ^2.0",
"sentry/sdk": "^3.4",
"sentry/sentry": "^3.19",
"sentry/sentry": "^3.20.1",
"symfony/cache-contracts": "^1.1||^2.4||^3.0",
"symfony/config": "^4.4.20||^5.0.11||^6.0",
"symfony/console": "^4.4.20||^5.0.11||^6.0",
Expand Down
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ parameters:
count: 1
path: src/Tracing/HttpClient/TraceableResponseForV6.php

-
message: "#^Constructor of class Sentry\\\\SentryBundle\\\\Twig\\\\SentryExtension has an unused parameter \\$hub\\.$#"
count: 1
path: src/Twig/SentryExtension.php

-
message: "#^Cannot access offset 'profiles_sample_rate' on mixed\\.$#"
count: 1
Expand Down
5 changes: 1 addition & 4 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->info('The sampling factor to apply to profiles. A value of 0 will deny sending any profiles, and a value of 1 will send all profiles. Profiles are sampled in relation to traces_sample_rate')
->end()
->scalarNode('traces_sampler')->end()
->arrayNode('trace_propagation_targets')
->scalarPrototype()->end()
->beforeNormalization()->castToArray()->end()
->end()
->variableNode('trace_propagation_targets')->end()
->booleanNode('attach_stacktrace')->end()
->integerNode('context_lines')->min(0)->end()
->booleanNode('enable_compression')->end()
Expand Down
6 changes: 3 additions & 3 deletions src/EventListener/TracingRequestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

namespace Sentry\SentryBundle\EventListener;

use Sentry\Tracing\Transaction;
use Sentry\Tracing\TransactionContext;
use Sentry\Tracing\TransactionSource;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\TerminateEvent;

use function Sentry\continueTrace;

/**
* This event listener acts on the master requests and starts a transaction
* to report performance data to Sentry. It gathers useful data like the
Expand All @@ -37,7 +37,7 @@ public function handleKernelRequestEvent(RequestEvent $event): void
/** @var float $requestStartTime */
$requestStartTime = $request->server->get('REQUEST_TIME_FLOAT', microtime(true));

$context = TransactionContext::fromHeaders(
$context = continueTrace(
$request->headers->get('sentry-trace', ''),
$request->headers->get('baggage', '')
);
Expand Down
2 changes: 0 additions & 2 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@
</service>

<service id="Sentry\SentryBundle\Twig\SentryExtension" class="Sentry\SentryBundle\Twig\SentryExtension">
<argument type="service" id="Sentry\State\HubInterface" />

<tag name="twig.extension" />
</service>
</services>
Expand Down
98 changes: 63 additions & 35 deletions src/Tracing/HttpClient/AbstractTraceableHttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use GuzzleHttp\Psr7\Uri;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Sentry\ClientInterface;
use Sentry\State\HubInterface;
use Sentry\Tracing\SpanContext;
use Symfony\Component\HttpClient\Response\ResponseStream;
Expand All @@ -15,6 +16,9 @@
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
use Symfony\Contracts\Service\ResetInterface;

use function Sentry\getBaggage;
use function Sentry\getTraceparent;

/**
* This is an implementation of the {@see HttpClientInterface} that decorates
* an existing http client to support distributed tracing capabilities.
Expand Down Expand Up @@ -44,49 +48,52 @@ public function __construct(HttpClientInterface $client, HubInterface $hub)
*/
public function request(string $method, string $url, array $options = []): ResponseInterface
{
$span = null;
$parent = $this->hub->getSpan();

if (null !== $parent) {
$headers = $options['headers'] ?? [];
$headers['sentry-trace'] = $parent->toTraceparent();
$uri = new Uri($url);
$headers = $options['headers'] ?? [];

$uri = new Uri($url);
$partialUri = Uri::fromParts([
'scheme' => $uri->getScheme(),
'host' => $uri->getHost(),
'port' => $uri->getPort(),
'path' => $uri->getPath(),
]);

// Check if the request destination is allow listed in the trace_propagation_targets option.
$client = $this->hub->getClient();
if (null !== $client) {
$sdkOptions = $client->getOptions();
$span = $this->hub->getSpan();
$client = $this->hub->getClient();

if (\in_array($uri->getHost(), (array) $sdkOptions->getTracePropagationTargets())) {
$headers['baggage'] = $parent->toBaggage();
}
if (null === $span) {
if (self::shouldAttachTracingHeaders($client, $uri)) {
$headers['baggage'] = getBaggage();
$headers['sentry-trace'] = getTraceparent();
}

$options['headers'] = $headers;

$context = new SpanContext();
$context->setOp('http.client');
$context->setDescription($method . ' ' . (string) $partialUri);
$context->setTags([
'http.method' => $method,
'http.url' => (string) $partialUri,
]);
$context->setData([
'http.query' => $uri->getQuery(),
'http.fragment' => $uri->getFragment(),
]);

$span = $parent->startChild($context);
return new TraceableResponse($this->client, $this->client->request($method, $url, $options), $span);
}

return new TraceableResponse($this->client, $this->client->request($method, $url, $options), $span);
$partialUri = Uri::fromParts([
'scheme' => $uri->getScheme(),
'host' => $uri->getHost(),
'port' => $uri->getPort(),
'path' => $uri->getPath(),
]);

$context = new SpanContext();
$context->setOp('http.client');
$context->setDescription($method . ' ' . (string) $partialUri);
$context->setTags([
'http.method' => $method,
'http.url' => (string) $partialUri,
]);
$context->setData([
'http.query' => $uri->getQuery(),
'http.fragment' => $uri->getFragment(),
]);

$childSpan = $span->startChild($context);

if (self::shouldAttachTracingHeaders($client, $uri)) {
$headers['baggage'] = $childSpan->toBaggage();
$headers['sentry-trace'] = $childSpan->toTraceparent();
}

$options['headers'] = $headers;

return new TraceableResponse($this->client, $this->client->request($method, $url, $options), $childSpan);
}

/**
Expand Down Expand Up @@ -119,4 +126,25 @@ public function setLogger(LoggerInterface $logger): void
$this->client->setLogger($logger);
}
}

private static function shouldAttachTracingHeaders(?ClientInterface $client, Uri $uri): bool
{
if (null !== $client) {
$sdkOptions = $client->getOptions();

// Check if the request destination is allow listed in the trace_propagation_targets option.
if (
null !== $sdkOptions->getTracePropagationTargets() &&
// Due to BC, we treat an empty array (the default) as all hosts are allow listed
(
[] === $sdkOptions->getTracePropagationTargets() ||
\in_array($uri->getHost(), $sdkOptions->getTracePropagationTargets())
)
) {
return true;
}
}

return false;
}
}
19 changes: 6 additions & 13 deletions src/Twig/SentryExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,16 @@
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

use function Sentry\getBaggage;
use function Sentry\getTraceparent;

final class SentryExtension extends AbstractExtension
{
/**
* @var HubInterface The current hub
*/
private $hub;

/**
* @param HubInterface $hub The current hub
*/
public function __construct(HubInterface $hub)
public function __construct(HubInterface $hub = null)
{
$this->hub = $hub;
}

/**
Expand All @@ -39,18 +36,14 @@ public function getFunctions(): array
*/
public function getTraceMeta(): string
{
$span = $this->hub->getSpan();

return sprintf('<meta name="sentry-trace" content="%s" />', null !== $span ? $span->toTraceparent() : '');
return sprintf('<meta name="sentry-trace" content="%s" />', getTraceparent());
}

/**
* Returns an HTML meta tag named `baggage`.
*/
public function getBaggageMeta(): string
{
$span = $this->hub->getSpan();

return sprintf('<meta name="baggage" content="%s" />', null !== $span ? $span->toBaggage() : '');
return sprintf('<meta name="baggage" content="%s" />', getBaggage());
}
}
1 change: 0 additions & 1 deletion tests/DependencyInjection/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public function testProcessConfigurationWithDefaultConfiguration(): void
'options' => [
'integrations' => [],
'prefixes' => array_merge(['%kernel.project_dir%'], array_filter(explode(\PATH_SEPARATOR, get_include_path() ?: ''))),
'trace_propagation_targets' => [],
'environment' => '%kernel.environment%',
'release' => PrettyVersions::getRootPackageVersion()->getPrettyVersion(),
'tags' => [],
Expand Down
Loading