diff --git a/CHANGELOG.md b/CHANGELOG.md index 55e98384..41e37db3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,17 @@ ## Unreleased -- Add support for tracing of the Symfony HTTP client requests (#606) -- Support logging the impersonator user, if any (#647) +- feat: Add support for tracing of the Symfony HTTP client requests (#606) +- feat: Support logging the impersonator user, if any (#647) - ref: Use constant for the SDK version (#662) +## 4.4.0 (2022-10-20) + +- feat: Add support for Dynamic Sampling (#665) + ## 4.3.1 (2022-10-10) -fix: Update span ops (#655) +- fix: Update span ops (#655) ## 4.3.0 (2022-05-30) diff --git a/composer.json b/composer.json index 537f5239..fd3fac4a 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "php": "^7.2||^8.0", "jean85/pretty-package-versions": "^1.5 || ^2.0", "php-http/discovery": "^1.11", - "sentry/sdk": "^3.2", + "sentry/sdk": "^3.3", "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", diff --git a/src/EventListener/TracingConsoleListener.php b/src/EventListener/TracingConsoleListener.php index 563bf610..5efbaf26 100644 --- a/src/EventListener/TracingConsoleListener.php +++ b/src/EventListener/TracingConsoleListener.php @@ -9,6 +9,7 @@ use Sentry\Tracing\SpanContext; use Sentry\Tracing\Transaction; use Sentry\Tracing\TransactionContext; +use Sentry\Tracing\TransactionSource; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleTerminateEvent; @@ -61,6 +62,7 @@ public function handleConsoleCommandEvent(ConsoleCommandEvent $event): void $transactionContext = new TransactionContext(); $transactionContext->setOp('console.command'); $transactionContext->setName($this->getSpanName($command)); + $transactionContext->setSource(TransactionSource::task()); $span = $this->hub->startTransaction($transactionContext); } else { diff --git a/src/EventListener/TracingRequestListener.php b/src/EventListener/TracingRequestListener.php index b10cee9f..4ed7264d 100644 --- a/src/EventListener/TracingRequestListener.php +++ b/src/EventListener/TracingRequestListener.php @@ -6,6 +6,7 @@ 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; @@ -36,9 +37,13 @@ public function handleKernelRequestEvent(RequestEvent $event): void /** @var float $requestStartTime */ $requestStartTime = $request->server->get('REQUEST_TIME_FLOAT', microtime(true)); - $context = TransactionContext::fromSentryTrace($request->headers->get('sentry-trace', '')); + $context = TransactionContext::fromHeaders( + $request->headers->get('sentry-trace', ''), + $request->headers->get('baggage', '') + ); $context->setOp('http.server'); $context->setName(sprintf('%s %s%s%s', $request->getMethod(), $request->getSchemeAndHttpHost(), $request->getBaseUrl(), $request->getPathInfo())); + $context->setSource(TransactionSource::url()); $context->setStartTimestamp($requestStartTime); $context->setTags($this->getTags($request)); diff --git a/src/Twig/SentryExtension.php b/src/Twig/SentryExtension.php index 8a405c44..8bb9a072 100644 --- a/src/Twig/SentryExtension.php +++ b/src/Twig/SentryExtension.php @@ -30,6 +30,7 @@ public function getFunctions(): array { return [ new TwigFunction('sentry_trace_meta', [$this, 'getTraceMeta'], ['is_safe' => ['html']]), + new TwigFunction('sentry_baggage_meta', [$this, 'getBaggageMeta'], ['is_safe' => ['html']]), ]; } @@ -42,4 +43,14 @@ public function getTraceMeta(): string return sprintf('', null !== $span ? $span->toTraceparent() : ''); } + + /** + * Returns an HTML meta tag named `baggage`. + */ + public function getBaggageMeta(): string + { + $span = $this->hub->getSpan(); + + return sprintf('', null !== $span ? $span->toBaggage() : ''); + } } diff --git a/tests/EventListener/TracingConsoleListenerTest.php b/tests/EventListener/TracingConsoleListenerTest.php index ab26c9fd..313200af 100644 --- a/tests/EventListener/TracingConsoleListenerTest.php +++ b/tests/EventListener/TracingConsoleListenerTest.php @@ -12,6 +12,7 @@ use Sentry\Tracing\Span; use Sentry\Tracing\Transaction; use Sentry\Tracing\TransactionContext; +use Sentry\Tracing\TransactionSource; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleTerminateEvent; @@ -71,6 +72,7 @@ public function handleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHubData $transactionContext = new TransactionContext(); $transactionContext->setOp('console.command'); $transactionContext->setName(''); + $transactionContext->setSource(TransactionSource::task()); yield [ new Command(), @@ -80,6 +82,7 @@ public function handleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHubData $transactionContext = new TransactionContext(); $transactionContext->setOp('console.command'); $transactionContext->setName('app:command'); + $transactionContext->setSource(TransactionSource::task()); yield [ new Command('app:command'), diff --git a/tests/EventListener/TracingRequestListenerTest.php b/tests/EventListener/TracingRequestListenerTest.php index cfc57c40..f5cc839c 100644 --- a/tests/EventListener/TracingRequestListenerTest.php +++ b/tests/EventListener/TracingRequestListenerTest.php @@ -10,11 +10,13 @@ use Sentry\Options; use Sentry\SentryBundle\EventListener\TracingRequestListener; use Sentry\State\HubInterface; +use Sentry\Tracing\DynamicSamplingContext; use Sentry\Tracing\SpanId; use Sentry\Tracing\SpanStatus; use Sentry\Tracing\TraceId; use Sentry\Tracing\Transaction; use Sentry\Tracing\TransactionContext; +use Sentry\Tracing\TransactionSource; use Symfony\Bridge\PhpUnit\ClockMock; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -85,11 +87,15 @@ public function testHandleKernelRequestEvent(Options $options, Request $request, */ public function handleKernelRequestEventDataProvider(): \Generator { + $samplingContext = DynamicSamplingContext::fromHeader(''); + $samplingContext->freeze(); + $transactionContext = new TransactionContext(); $transactionContext->setTraceId(new TraceId('566e3688a61d4bc888951642d6f14a19')); $transactionContext->setParentSpanId(new SpanId('566e3688a61d4bc8')); $transactionContext->setParentSampled(true); $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -100,6 +106,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => '', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); yield 'request.headers.sentry-trace EXISTS' => [ new Options(), @@ -117,8 +124,47 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext, ]; + $samplingContext = DynamicSamplingContext::fromHeader('sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-public_key=public,sentry-sample_rate=1'); + $samplingContext->freeze(); + + $transactionContext = new TransactionContext(); + $transactionContext->setTraceId(new TraceId('566e3688a61d4bc888951642d6f14a19')); + $transactionContext->setParentSpanId(new SpanId('566e3688a61d4bc8')); + $transactionContext->setParentSampled(true); + $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); + $transactionContext->setOp('http.server'); + $transactionContext->setStartTimestamp(1613493597.010275); + $transactionContext->setTags([ + 'net.host.port' => '80', + 'http.method' => 'GET', + 'http.url' => 'http://www.example.com/', + 'http.flavor' => '1.1', + 'route' => '', + 'net.host.name' => 'www.example.com', + ]); + $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); + + yield 'request.headers.sentry-trace and headers.baggage EXISTS' => [ + new Options(), + Request::create( + 'http://www.example.com', + 'GET', + [], + [], + [], + [ + 'REQUEST_TIME_FLOAT' => 1613493597.010275, + 'HTTP_sentry-trace' => '566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-1', + 'HTTP_baggage' => 'sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-public_key=public,sentry-sample_rate=1', + ] + ), + $transactionContext, + ]; + $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -141,6 +187,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://127.0.0.1/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -171,6 +218,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/path'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -194,6 +242,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/path'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -217,6 +266,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -240,6 +290,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -263,6 +314,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -286,6 +338,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -309,6 +362,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ @@ -332,6 +386,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://:/'); + $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setTags([ diff --git a/tests/Twig/SentryExtensionTest.php b/tests/Twig/SentryExtensionTest.php index 5dd06c52..fe7f4894 100644 --- a/tests/Twig/SentryExtensionTest.php +++ b/tests/Twig/SentryExtensionTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\TestCase; use Sentry\SentryBundle\Twig\SentryExtension; use Sentry\State\HubInterface; +use Sentry\Tracing\DynamicSamplingContext; use Sentry\Tracing\Span; use Sentry\Tracing\SpanId; use Sentry\Tracing\TraceId; @@ -71,6 +72,42 @@ public function traceMetaFunctionDataProvider(): \Generator ]; } + /** + * @dataProvider baggageMetaFunctionDataProvider + */ + public function testBaggageMetaFunction(?Span $span, string $expectedTemplate): void + { + $this->hub->expects($this->once()) + ->method('getSpan') + ->willReturn($span); + + $environment = new Environment(new ArrayLoader(['foo.twig' => '{{ sentry_baggage_meta() }}'])); + $environment->addExtension(new SentryExtension($this->hub)); + + $this->assertSame($expectedTemplate, $environment->render('foo.twig')); + } + + /** + * @return \Generator + */ + public function baggageMetaFunctionDataProvider(): \Generator + { + yield [ + null, + '', + ]; + + $samplingContext = DynamicSamplingContext::fromHeader('sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-public_key=public,sentry-sample_rate=1'); + $transactionContext = new TransactionContext(); + $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); + $transaction = new Transaction($transactionContext); + + yield [ + $transaction, + '', + ]; + } + private static function isTwigBundlePackageInstalled(): bool { return class_exists(TwigBundle::class);