Skip to content

Commit

Permalink
Decorate routing dispatchers to get a route span
Browse files Browse the repository at this point in the history
  • Loading branch information
stayallive committed Oct 14, 2022
1 parent e2d3819 commit dda0978
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
@@ -0,0 +1,24 @@
<?php

namespace Sentry\Laravel\Tracing\Routing;

use Illuminate\Routing\Contracts\CallableDispatcher;
use Illuminate\Routing\Route;

class TracingCallableDispatcherTracing extends TracingRoutingDispatcher implements CallableDispatcher
{
/** @var \Illuminate\Routing\Contracts\CallableDispatcher */
private $dispatcher;

public function __construct(CallableDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}

public function dispatch(Route $route, $callable)
{
return $this->wrapRouteDispatch(function () use ($route, $callable) {
return $this->dispatcher->dispatch($route, $callable);
}, $route);
}
}
@@ -0,0 +1,29 @@
<?php

namespace Sentry\Laravel\Tracing\Routing;

use Illuminate\Routing\Contracts\ControllerDispatcher;
use Illuminate\Routing\Route;

class TracingControllerDispatcherTracing extends TracingRoutingDispatcher implements ControllerDispatcher
{
/** @var \Illuminate\Routing\Contracts\ControllerDispatcher */
private $dispatcher;

public function __construct(ControllerDispatcher $dispatcher)
{
$this->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);
}
}
36 changes: 36 additions & 0 deletions src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php
@@ -0,0 +1,36 @@
<?php

namespace Sentry\Laravel\Tracing\Routing;

use Illuminate\Routing\Route;
use Sentry\SentrySdk;
use Sentry\Tracing\SpanContext;

abstract class TracingRoutingDispatcher
{
protected function wrapRouteDispatch(callable $dispatch, Route $route)
{
$parentSpan = SentrySdk::getCurrentHub()->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);
}
}
}
17 changes: 17 additions & 0 deletions src/Sentry/Laravel/Tracing/ServiceProvider.php
Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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);
});
}
}

0 comments on commit dda0978

Please sign in to comment.