diff --git a/src/Integration/AbstractErrorListenerIntegration.php b/src/Integration/AbstractErrorListenerIntegration.php index 36482a987..9b1cc8a0d 100644 --- a/src/Integration/AbstractErrorListenerIntegration.php +++ b/src/Integration/AbstractErrorListenerIntegration.php @@ -7,7 +7,7 @@ use Sentry\Event; use Sentry\EventHint; use Sentry\ExceptionMechanism; -use Sentry\State\EventCapturer; +use Sentry\State\EventRecorder; use Sentry\State\IsolationScope; use function Sentry\withIsolationScope; @@ -24,7 +24,7 @@ protected function captureException(\Throwable $exception): void return $this->addExceptionMechanismToEvent($event); }); - EventCapturer::captureException($exception); + EventRecorder::captureException($exception, null, $scope); }); } diff --git a/src/Monolog/ExceptionToSentryIssueHandler.php b/src/Monolog/ExceptionToSentryIssueHandler.php index 7998c9c83..5173631d5 100644 --- a/src/Monolog/ExceptionToSentryIssueHandler.php +++ b/src/Monolog/ExceptionToSentryIssueHandler.php @@ -9,7 +9,7 @@ use Monolog\Logger; use Monolog\LogRecord; use Psr\Log\LogLevel; -use Sentry\State\EventCapturer; +use Sentry\State\EventRecorder; use Sentry\State\IsolationScope; use function Sentry\withIsolationScope; @@ -56,7 +56,7 @@ public function handle($record): bool $scope->setExtra('monolog.extra', $monologExtraData); } - EventCapturer::captureException($exception); + EventRecorder::captureException($exception, null, $scope); }); return $this->bubble === false; diff --git a/src/Monolog/LogToSentryIssueHandler.php b/src/Monolog/LogToSentryIssueHandler.php index f38f03020..2866d32af 100644 --- a/src/Monolog/LogToSentryIssueHandler.php +++ b/src/Monolog/LogToSentryIssueHandler.php @@ -11,7 +11,7 @@ use Psr\Log\LogLevel; use Sentry\Event; use Sentry\EventHint; -use Sentry\State\EventCapturer; +use Sentry\State\EventRecorder; use Sentry\State\IsolationScope; use function Sentry\withIsolationScope; @@ -84,7 +84,7 @@ protected function doWrite($record): void } } - EventCapturer::captureEvent($event, $hint); + EventRecorder::captureEvent($event, $hint, $scope); }); } diff --git a/src/State/EventCapturer.php b/src/State/EventRecorder.php similarity index 61% rename from src/State/EventCapturer.php rename to src/State/EventRecorder.php index a21b44e75..dbc6c4f41 100644 --- a/src/State/EventCapturer.php +++ b/src/State/EventRecorder.php @@ -18,36 +18,44 @@ /** * @internal */ -final class EventCapturer +final class EventRecorder { private function __construct() { } - public static function captureMessage(string $message, ?Severity $level = null, ?EventHint $hint = null): ?EventId + public static function captureMessage(string $message, ?Severity $level = null, ?EventHint $hint = null, ?IsolationScope $isolationScope = null): ?EventId { - return self::capture(static function (ClientInterface $client, IsolationScope $captureScope) use ($message, $level, $hint): ?EventId { + $isolationScope = $isolationScope ?? SentrySdk::getIsolationScope(); + + return self::captureWithScope(SentrySdk::getClient($isolationScope), $isolationScope, static function (ClientInterface $client, IsolationScope $captureScope) use ($message, $level, $hint): ?EventId { return $client->captureMessage($message, $level, $captureScope, $hint); }); } - public static function captureException(\Throwable $exception, ?EventHint $hint = null): ?EventId + public static function captureException(\Throwable $exception, ?EventHint $hint = null, ?IsolationScope $isolationScope = null): ?EventId { - return self::capture(static function (ClientInterface $client, IsolationScope $captureScope) use ($exception, $hint): ?EventId { + $isolationScope = $isolationScope ?? SentrySdk::getIsolationScope(); + + return self::captureWithScope(SentrySdk::getClient($isolationScope), $isolationScope, static function (ClientInterface $client, IsolationScope $captureScope) use ($exception, $hint): ?EventId { return $client->captureException($exception, $captureScope, $hint); }); } - public static function captureEvent(Event $event, ?EventHint $hint = null): ?EventId + public static function captureEvent(Event $event, ?EventHint $hint = null, ?IsolationScope $isolationScope = null): ?EventId { - return self::capture(static function (ClientInterface $client, IsolationScope $captureScope) use ($event, $hint): ?EventId { + $isolationScope = $isolationScope ?? SentrySdk::getIsolationScope(); + + return self::captureWithScope(SentrySdk::getClient($isolationScope), $isolationScope, static function (ClientInterface $client, IsolationScope $captureScope) use ($event, $hint): ?EventId { return $client->captureEvent($event, $hint, $captureScope); }); } - public static function captureLastError(?EventHint $hint = null): ?EventId + public static function captureLastError(?EventHint $hint = null, ?IsolationScope $isolationScope = null): ?EventId { - return self::capture(static function (ClientInterface $client, IsolationScope $captureScope) use ($hint): ?EventId { + $isolationScope = $isolationScope ?? SentrySdk::getIsolationScope(); + + return self::captureWithScope(SentrySdk::getClient($isolationScope), $isolationScope, static function (ClientInterface $client, IsolationScope $captureScope) use ($hint): ?EventId { return $client->captureLastError($captureScope, $hint); }); } @@ -55,9 +63,9 @@ public static function captureLastError(?EventHint $hint = null): ?EventId /** * @param int|float|null $duration */ - public static function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?MonitorConfig $monitorConfig = null, ?string $checkInId = null): ?string + public static function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?MonitorConfig $monitorConfig = null, ?string $checkInId = null, ?IsolationScope $isolationScope = null): ?string { - $isolationScope = SentrySdk::getIsolationScope(); + $isolationScope = $isolationScope ?? SentrySdk::getIsolationScope(); $client = SentrySdk::getClient($isolationScope); if ($client instanceof NoOpClient) { @@ -84,16 +92,6 @@ public static function captureCheckIn(string $slug, CheckInStatus $status, $dura return $checkIn->getId(); } - /** - * @param callable(ClientInterface, IsolationScope): ?EventId $capture - */ - private static function capture(callable $capture): ?EventId - { - $isolationScope = SentrySdk::getIsolationScope(); - - return self::captureWithScope(SentrySdk::getClient($isolationScope), $isolationScope, $capture); - } - /** * @param callable(ClientInterface, IsolationScope): ?EventId $capture */ diff --git a/src/Tracing/Transaction.php b/src/Tracing/Transaction.php index 89086bc96..2b3cba6b1 100644 --- a/src/Tracing/Transaction.php +++ b/src/Tracing/Transaction.php @@ -9,6 +9,8 @@ use Sentry\Options; use Sentry\Profiling\Profiler; use Sentry\SentrySdk; +use Sentry\State\EventRecorder; +use Sentry\State\IsolationScope; /** * This class stores all the information about a Transaction. @@ -20,6 +22,11 @@ final class Transaction extends Span */ private $name; + /** + * @var IsolationScope + */ + private $scope; + /** * @var Transaction The transaction */ @@ -42,11 +49,12 @@ final class Transaction extends Span * * @internal */ - public function __construct(TransactionContext $context) + public function __construct(TransactionContext $context, ?IsolationScope $scope = null) { parent::__construct($context); $this->name = $context->getName(); + $this->scope = $scope ?? SentrySdk::getIsolationScope(); $this->metadata = $context->getMetadata(); $this->transaction = $this; } @@ -90,7 +98,7 @@ public function getDynamicSamplingContext(): DynamicSamplingContext return $this->metadata->getDynamicSamplingContext(); } - $samplingContext = DynamicSamplingContext::fromTransaction($this->transaction, SentrySdk::getClient()); + $samplingContext = DynamicSamplingContext::fromTransaction($this->transaction, SentrySdk::getClient($this->scope)); $this->getMetadata()->setDynamicSamplingContext($samplingContext); return $samplingContext; @@ -115,7 +123,7 @@ public function initSpanRecorder(int $maxSpans = 1000): self public function initProfiler(?Options $options = null): Profiler { if ($this->profiler === null) { - $this->profiler = new Profiler($options ?? SentrySdk::getClient()->getOptions()); + $this->profiler = new Profiler($options ?? SentrySdk::getClient($this->scope)->getOptions()); } return $this->profiler; @@ -180,6 +188,6 @@ public function finish(?float $endTimestamp = null): ?EventId } } - return \Sentry\captureEvent($event); + return EventRecorder::captureEvent($event, null, $this->scope); } } diff --git a/src/functions.php b/src/functions.php index bb234f982..84aadd28e 100644 --- a/src/functions.php +++ b/src/functions.php @@ -11,7 +11,7 @@ use Sentry\Logs\Logs; use Sentry\Metrics\TraceMetrics; use Sentry\State\BreadcrumbRecorder; -use Sentry\State\EventCapturer; +use Sentry\State\EventRecorder; use Sentry\State\GlobalScope; use Sentry\State\IsolationScope; use Sentry\State\Scope; @@ -105,7 +105,7 @@ function getClient(): ClientInterface */ function captureMessage(string $message, ?Severity $level = null, ?EventHint $hint = null): ?EventId { - return EventCapturer::captureMessage($message, $level, $hint); + return EventRecorder::captureMessage($message, $level, $hint); } /** @@ -116,7 +116,7 @@ function captureMessage(string $message, ?Severity $level = null, ?EventHint $hi */ function captureException(\Throwable $exception, ?EventHint $hint = null): ?EventId { - return EventCapturer::captureException($exception, $hint); + return EventRecorder::captureException($exception, $hint); } /** @@ -127,7 +127,7 @@ function captureException(\Throwable $exception, ?EventHint $hint = null): ?Even */ function captureEvent(Event $event, ?EventHint $hint = null): ?EventId { - return EventCapturer::captureEvent($event, $hint); + return EventRecorder::captureEvent($event, $hint); } /** @@ -137,7 +137,7 @@ function captureEvent(Event $event, ?EventHint $hint = null): ?EventId */ function captureLastError(?EventHint $hint = null): ?EventId { - return EventCapturer::captureLastError($hint); + return EventRecorder::captureLastError($hint); } /** @@ -151,7 +151,7 @@ function captureLastError(?EventHint $hint = null): ?EventId */ function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?MonitorConfig $monitorConfig = null, ?string $checkInId = null): ?string { - return EventCapturer::captureCheckIn($slug, $status, $duration, $monitorConfig, $checkInId); + return EventRecorder::captureCheckIn($slug, $status, $duration, $monitorConfig, $checkInId); } /** diff --git a/tests/State/EventCapturerTest.php b/tests/State/EventRecorderTest.php similarity index 90% rename from tests/State/EventCapturerTest.php rename to tests/State/EventRecorderTest.php index 3d8c985f4..8eb644697 100644 --- a/tests/State/EventCapturerTest.php +++ b/tests/State/EventRecorderTest.php @@ -16,11 +16,11 @@ use Sentry\Options; use Sentry\SentrySdk; use Sentry\Severity; -use Sentry\State\EventCapturer; +use Sentry\State\EventRecorder; use Sentry\State\IsolationScope; use Sentry\Util\SentryUid; -final class EventCapturerTest extends TestCase +final class EventRecorderTest extends TestCase { public function testCaptureMessagePassesIsolationScopeAndStoresLastEventId(): void { @@ -36,7 +36,7 @@ public function testCaptureMessagePassesIsolationScopeAndStoresLastEventId(): vo }), $hint) ->willReturn($eventId); - $this->assertSame($eventId, EventCapturer::captureMessage('foo', Severity::debug(), $hint)); + $this->assertSame($eventId, EventRecorder::captureMessage('foo', Severity::debug(), $hint, $isolationScope)); $this->assertSame($eventId, $isolationScope->getLastEventId()); } @@ -55,7 +55,7 @@ public function testCaptureExceptionPassesIsolationScopeAndStoresLastEventId(): }), $hint) ->willReturn($eventId); - $this->assertSame($eventId, EventCapturer::captureException($exception, $hint)); + $this->assertSame($eventId, EventRecorder::captureException($exception, $hint, $isolationScope)); $this->assertSame($eventId, $isolationScope->getLastEventId()); } @@ -73,7 +73,7 @@ public function testCaptureEventPassesIsolationScopeAndStoresLastEventId(): void })) ->willReturn($event->getId()); - $this->assertSame($event->getId(), EventCapturer::captureEvent($event, $hint)); + $this->assertSame($event->getId(), EventRecorder::captureEvent($event, $hint, $isolationScope)); $this->assertSame($event->getId(), $isolationScope->getLastEventId()); } @@ -91,7 +91,7 @@ public function testCaptureLastErrorPassesIsolationScopeAndStoresLastEventId(): }), $hint) ->willReturn($eventId); - $this->assertSame($eventId, EventCapturer::captureLastError($hint)); + $this->assertSame($eventId, EventRecorder::captureLastError($hint, $isolationScope)); $this->assertSame($eventId, $isolationScope->getLastEventId()); } @@ -109,7 +109,7 @@ public function testCaptureEventClearsLastEventIdWhenClientReturnsNull(): void })) ->willReturn(null); - $this->assertNull(EventCapturer::captureEvent($event)); + $this->assertNull(EventRecorder::captureEvent($event)); $this->assertNull($isolationScope->getLastEventId()); } @@ -150,12 +150,13 @@ public function testCaptureCheckInCreatesEventAndStoresLastEventId(): void })) ->willReturn($eventId); - $this->assertSame($checkInId, EventCapturer::captureCheckIn( + $this->assertSame($checkInId, EventRecorder::captureCheckIn( 'test-crontab', CheckInStatus::ok(), 10, $monitorConfig, - $checkInId + $checkInId, + $isolationScope )); $this->assertSame($eventId, $isolationScope->getLastEventId()); } @@ -166,7 +167,7 @@ public function testCaptureCheckInReturnsNullForNoOpClient(): void $eventId = EventId::generate(); SentrySdk::getIsolationScope()->setLastEventId($eventId); - $this->assertNull(EventCapturer::captureCheckIn('test-crontab', CheckInStatus::ok())); + $this->assertNull(EventRecorder::captureCheckIn('test-crontab', CheckInStatus::ok())); $this->assertSame($eventId, SentrySdk::getIsolationScope()->getLastEventId()); } diff --git a/tests/Tracing/TransactionTest.php b/tests/Tracing/TransactionTest.php index cfb2eb959..aff82026f 100644 --- a/tests/Tracing/TransactionTest.php +++ b/tests/Tracing/TransactionTest.php @@ -41,7 +41,9 @@ public function testFinish(): void SentrySdk::init($client); - $transaction = new Transaction($transactionContext); + $scope = SentrySdk::getIsolationScope(); + $transaction = new Transaction($transactionContext, $scope); + SentrySdk::getCurrentRuntimeContext()->setIsolationScope(new IsolationScope()); $transaction->initSpanRecorder(); $span1 = $transaction->startChild(new SpanContext()); @@ -59,7 +61,7 @@ public function testFinish(): void $this->assertSame([$span1, $span2], $eventArg->getSpans()); return true; - }), null, $this->isInstanceOf(IsolationScope::class)) + }), null, $scope) ->willReturnCallback(static function (Event $eventArg) use (&$expectedEventId): EventId { $expectedEventId = $eventArg->getId(); @@ -72,6 +74,8 @@ public function testFinish(): void $eventId = $transaction->finish(); $this->assertSame($expectedEventId, $eventId); + $this->assertSame($expectedEventId, $scope->getLastEventId()); + $this->assertNull(SentrySdk::getIsolationScope()->getLastEventId()); } public function testFinishDoesNothingIfSampledFlagIsNotTrue(): void