From 09a27a9b8d7a3afe82449ec5831d96a9f957d09f Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Fri, 22 Nov 2024 09:09:10 +0100 Subject: [PATCH] Add new org config --- src/Dsn.php | 33 ++++++++++++++++++++++---- src/Options.php | 32 +++++++++++++++++++++++++ src/Tracing/DynamicSamplingContext.php | 7 ++++++ tests/DsnTest.php | 24 ++++++++++++++++++- 4 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/Dsn.php b/src/Dsn.php index 37aaca162..3deb5ab91 100644 --- a/src/Dsn.php +++ b/src/Dsn.php @@ -12,6 +12,13 @@ */ final class Dsn implements \Stringable { + + /** + * @var string Regex to match the organization ID in the host. + * This only applies to Sentry SaaS DSNs that contain the organization ID. + */ + private const SENTRY_ORG_REGEX = '/^o(\d+)\./'; + /** * @var string The protocol to be used to access the resource */ @@ -42,6 +49,11 @@ final class Dsn implements \Stringable */ private $path; + /** + * @var string + */ + private $org; + /** * Class constructor. * @@ -51,15 +63,17 @@ final class Dsn implements \Stringable * @param string $projectId The ID of the resource to access * @param string $path The specific resource that the web client wants to access * @param string $publicKey The public key to authenticate the SDK + * @param string $org */ - private function __construct(string $scheme, string $host, int $port, string $projectId, string $path, string $publicKey) + private function __construct(string $scheme, string $host, int $port, string $projectId, string $path, string $publicKey, ?string $org = null) { $this->scheme = $scheme; $this->host = $host; $this->port = $port; - $this->publicKey = $publicKey; - $this->path = $path; $this->projectId = $projectId; + $this->path = $path; + $this->publicKey = $publicKey; + $this->org = $org; } /** @@ -94,13 +108,19 @@ public static function createFromString(string $value): self $path = substr($parsedDsn['path'], 0, $lastSlashPosition); } + $org = null; + if (preg_match(self::SENTRY_ORG_REGEX, $parsedDsn['host'], $matches) == 1) { + $org = $matches[1]; + } + return new self( $parsedDsn['scheme'], $parsedDsn['host'], $parsedDsn['port'] ?? ($parsedDsn['scheme'] === 'http' ? 80 : 443), $projectId, $path, - $parsedDsn['user'] + $parsedDsn['user'], + $org ); } @@ -152,6 +172,11 @@ public function getPublicKey(): string return $this->publicKey; } + public function getOrg(): ?string + { + return $this->org; + } + /** * Returns the URL of the API for the envelope endpoint. */ diff --git a/src/Options.php b/src/Options.php index dd2930547..266a1865d 100644 --- a/src/Options.php +++ b/src/Options.php @@ -424,6 +424,20 @@ public function getDsn(): ?Dsn return $this->options['dsn']; } + public function getOrg(): ?string + { + return $this->options['org']; + } + + public function setOrg(string $org): self + { + $options = array_merge($this->options, ['org' => $org]); + + $this->options = $this->resolver->resolve($options); + + return $this; + } + /** * Gets the name of the server the SDK is running on (e.g. the hostname). */ @@ -636,6 +650,20 @@ public function setTracePropagationTargets(array $tracePropagationTargets): self return $this; } + public function isStrictTracePropagationEnabled(): bool + { + return $this->options['strict_trace_propagation']; + } + + public function setStrictTracePropagationEnabled(bool $enabled): self + { + $options = array_merge($this->options, ['strict_trace_propagation' => $enabled]); + + $this->options = $this->resolver->resolve($options); + + return $this; + } + /** * Gets a list of default tags for events. * @@ -1131,6 +1159,7 @@ private function configureOptions(OptionsResolver $resolver): void 'spotlight_url' => 'http://localhost:8969', 'release' => $_SERVER['SENTRY_RELEASE'] ?? $_SERVER['AWS_LAMBDA_FUNCTION_VERSION'] ?? null, 'dsn' => $_SERVER['SENTRY_DSN'] ?? null, + 'org' => null, 'server_name' => gethostname(), 'ignore_exceptions' => [], 'ignore_transactions' => [], @@ -1150,6 +1179,7 @@ private function configureOptions(OptionsResolver $resolver): void return null; }, 'trace_propagation_targets' => null, + 'strict_trace_propagation' => false, 'tags' => [], 'error_types' => null, 'max_breadcrumbs' => self::DEFAULT_MAX_BREADCRUMBS, @@ -1191,12 +1221,14 @@ private function configureOptions(OptionsResolver $resolver): void $resolver->setAllowedTypes('spotlight_url', 'string'); $resolver->setAllowedTypes('release', ['null', 'string']); $resolver->setAllowedTypes('dsn', ['null', 'string', 'bool', Dsn::class]); + $resolver->setAllowedTypes('org', ['null', 'string']); $resolver->setAllowedTypes('server_name', 'string'); $resolver->setAllowedTypes('before_send', ['callable']); $resolver->setAllowedTypes('before_send_transaction', ['callable']); $resolver->setAllowedTypes('ignore_exceptions', 'string[]'); $resolver->setAllowedTypes('ignore_transactions', 'string[]'); $resolver->setAllowedTypes('trace_propagation_targets', ['null', 'string[]']); + $resolver->setAllowedTypes('strict_trace_propagation', ['null', 'bool']); $resolver->setAllowedTypes('tags', 'string[]'); $resolver->setAllowedTypes('error_types', ['null', 'int']); $resolver->setAllowedTypes('max_breadcrumbs', 'int'); diff --git a/src/Tracing/DynamicSamplingContext.php b/src/Tracing/DynamicSamplingContext.php index cf159ed59..d1236ed66 100644 --- a/src/Tracing/DynamicSamplingContext.php +++ b/src/Tracing/DynamicSamplingContext.php @@ -172,6 +172,9 @@ public static function fromTransaction(Transaction $transaction, HubInterface $h if ($options->getDsn() !== null && $options->getDsn()->getPublicKey() !== null) { $samplingContext->set('public_key', $options->getDsn()->getPublicKey()); } + if ($options->getDsn() !== null && $options->getDsn()->getOrg() !== null) { + $samplingContext->set('org', $options->getDsn()->getOrg()); + } if ($options->getRelease() !== null) { $samplingContext->set('release', $options->getRelease()); @@ -204,6 +207,10 @@ public static function fromOptions(Options $options, Scope $scope): self $samplingContext->set('public_key', $options->getDsn()->getPublicKey()); } + if ($options->getDsn() !== null && $options->getDsn()->getOrg() !== null) { + $samplingContext->set('org', $options->getDsn()->getOrg()); + } + if ($options->getRelease() !== null) { $samplingContext->set('release', $options->getRelease()); } diff --git a/tests/DsnTest.php b/tests/DsnTest.php index 724d00538..259621327 100644 --- a/tests/DsnTest.php +++ b/tests/DsnTest.php @@ -22,7 +22,8 @@ public function testCreateFromString( int $expectedPort, string $expectedPublicKey, string $expectedProjectId, - string $expectedPath + string $expectedPath, + ?string $expectedOrg, ): void { $dsn = Dsn::createFromString($value); @@ -32,6 +33,7 @@ public function testCreateFromString( $this->assertSame($expectedPublicKey, $dsn->getPublicKey()); $this->assertSame($expectedProjectId, $dsn->getProjectId(true)); $this->assertSame($expectedPath, $dsn->getPath()); + $this->assertSame($expectedOrg, $dsn->getOrg()); } public static function createFromStringDataProvider(): \Generator @@ -44,6 +46,7 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '/sentry', + null, ]; yield [ @@ -54,6 +57,18 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '', + null, + ]; + + yield [ + 'http://public@o1.example.com/1', + 'http', + 'o1.example.com', + 80, + 'public', + '1', + '', + '1', ]; yield [ @@ -64,6 +79,7 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '', + null, ]; yield [ @@ -74,6 +90,7 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '', + null, ]; yield [ @@ -84,6 +101,7 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '', + null, ]; yield [ @@ -94,6 +112,7 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '', + null, ]; yield [ @@ -104,6 +123,7 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '', + null, ]; yield [ @@ -114,6 +134,7 @@ public static function createFromStringDataProvider(): \Generator 'public', '1', '', + null, ]; } @@ -240,6 +261,7 @@ public static function toStringDataProvider(): array return [ ['http://public@example.com/sentry/1'], ['http://public@example.com/1'], + ['http://public@01.example.com/1'], ['http://public@example.com:8080/sentry/1'], ['https://public@example.com/sentry/1'], ['https://public@example.com:4343/sentry/1'],