From 41f2f5e396bb483f733fac0e17b308e271e23e02 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Fri, 14 Oct 2022 14:23:21 +0200 Subject: [PATCH 1/2] Decorate routing dispatchers to get a route span --- .../TracingCallableDispatcherTracing.php | 24 +++++++++++++ .../TracingControllerDispatcherTracing.php | 29 +++++++++++++++ .../Routing/TracingRoutingDispatcher.php | 36 +++++++++++++++++++ .../Laravel/Tracing/ServiceProvider.php | 17 +++++++++ 4 files changed, 106 insertions(+) create mode 100644 src/Sentry/Laravel/Tracing/Routing/TracingCallableDispatcherTracing.php create mode 100644 src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php create mode 100644 src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php diff --git a/src/Sentry/Laravel/Tracing/Routing/TracingCallableDispatcherTracing.php b/src/Sentry/Laravel/Tracing/Routing/TracingCallableDispatcherTracing.php new file mode 100644 index 00000000..7ccb1062 --- /dev/null +++ b/src/Sentry/Laravel/Tracing/Routing/TracingCallableDispatcherTracing.php @@ -0,0 +1,24 @@ +dispatcher = $dispatcher; + } + + public function dispatch(Route $route, $callable) + { + return $this->wrapRouteDispatch(function () use ($route, $callable) { + return $this->dispatcher->dispatch($route, $callable); + }, $route); + } +} diff --git a/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php b/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php new file mode 100644 index 00000000..1cedda2c --- /dev/null +++ b/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php @@ -0,0 +1,29 @@ +dispatcher = $dispatcher; + } + + public function dispatch(Route $route, $controller, $method) + { + return $this->wrapRouteDispatch(function () use ($route, $controller, $method) { + return $this->dispatcher->dispatch($route, $controller, $method); + }, $route); + } + + public function getMiddleware($controller, $method) + { + return $this->dispatcher->getMiddleware($controller, $method); + } +} diff --git a/src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php b/src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php new file mode 100644 index 00000000..98212973 --- /dev/null +++ b/src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php @@ -0,0 +1,36 @@ +getSpan(); + + // When there is no active transaction we can skip doing anything and just immediately return the callable + if ($parentSpan === null) { + return $dispatch(); + } + + $context = new SpanContext; + $context->setOp('http.route'); + $context->setDescription($route->getActionName()); + + $span = $parentSpan->startChild($context); + + SentrySdk::getCurrentHub()->setSpan($span); + + try { + return $dispatch(); + } finally { + $span->finish(); + + SentrySdk::getCurrentHub()->setSpan($parentSpan); + } + } +} diff --git a/src/Sentry/Laravel/Tracing/ServiceProvider.php b/src/Sentry/Laravel/Tracing/ServiceProvider.php index 1071b8fb..cd56d2d4 100644 --- a/src/Sentry/Laravel/Tracing/ServiceProvider.php +++ b/src/Sentry/Laravel/Tracing/ServiceProvider.php @@ -8,10 +8,14 @@ use Illuminate\Contracts\View\Engine; use Illuminate\Contracts\View\View; use Illuminate\Foundation\Http\Kernel as HttpKernel; +use Illuminate\Routing\Contracts\CallableDispatcher; +use Illuminate\Routing\Contracts\ControllerDispatcher; use Illuminate\View\Engines\EngineResolver; use Illuminate\View\Factory as ViewFactory; use InvalidArgumentException; use Sentry\Laravel\BaseServiceProvider; +use Sentry\Laravel\Tracing\Routing\TracingCallableDispatcherTracing; +use Sentry\Laravel\Tracing\Routing\TracingControllerDispatcherTracing; use Sentry\Serializer\RepresentationSerializer; class ServiceProvider extends BaseServiceProvider @@ -29,6 +33,8 @@ public function boot(): void $this->bindViewEngine($tracingConfig); + $this->decorateRoutingDispatchers(); + if ($this->app->bound(HttpKernelInterface::class)) { /** @var \Illuminate\Foundation\Http\Kernel $httpKernel */ $httpKernel = $this->app->make(HttpKernelInterface::class); @@ -119,4 +125,15 @@ private function wrapViewEngine(Engine $realEngine): Engine return new ViewEngineDecorator($realEngine, $viewFactory); } + + private function decorateRoutingDispatchers(): void + { + $this->app->extend(CallableDispatcher::class, static function (CallableDispatcher $dispatcher) { + return new TracingCallableDispatcherTracing($dispatcher); + }); + + $this->app->extend(ControllerDispatcher::class, static function (ControllerDispatcher $dispatcher) { + return new TracingControllerDispatcherTracing($dispatcher); + }); + } } From 35b06168d03e83c77535861bf3760c23d774c27d Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Fri, 14 Oct 2022 14:31:20 +0200 Subject: [PATCH 2/2] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d08b3d5f..8137d815 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Add tracing span for Laravel HTTP client requests (#585) - Simplify Sentry meta tag retrieval, by adding `Sentry\Laravel\Integration::sentryMeta()` (#586) - Fix tracing with nested queue jobs (mostly when running jobs in the `sync` driver) (#592) +- Add a `http.route` span, this span indicates the time that is spent inside a controller method or route closure (#593) ## 2.14.2