Skip to content

Commit aa0182c

Browse files
authored
Merge pull request #198 from getsentry/track-subrequests-with-scopes
Track subrequests with scopes
2 parents 965ca7b + 23be9d0 commit aa0182c

File tree

7 files changed

+175
-9
lines changed

7 files changed

+175
-9
lines changed

src/DependencyInjection/Configuration.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public function getConfigTreeBuilder()
116116
->children();
117117
$listenerPriorities->scalarNode('request')
118118
->defaultValue(1);
119+
$listenerPriorities->scalarNode('sub_request')
120+
->defaultValue(1);
119121
$listenerPriorities->scalarNode('console')
120122
->defaultValue(1);
121123

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\EventListener;
4+
5+
use Sentry\State\Hub;
6+
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
7+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
8+
9+
final class SubRequestListener
10+
{
11+
/**
12+
* Pushes a new {@see Scope} for each SubRequest
13+
*
14+
* @param GetResponseEvent $event
15+
*/
16+
public function onKernelRequest(GetResponseEvent $event): void
17+
{
18+
if ($event->isMasterRequest()) {
19+
return;
20+
}
21+
22+
Hub::getCurrent()->pushScope();
23+
}
24+
25+
/**
26+
* Pops a {@see Scope} for each finished SubRequest
27+
*
28+
* @param FinishRequestEvent $event
29+
*/
30+
public function onKernelFinishRequest(FinishRequestEvent $event): void
31+
{
32+
if ($event->isMasterRequest()) {
33+
return;
34+
}
35+
36+
Hub::getCurrent()->popScope();
37+
}
38+
}

src/Resources/config/services.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,10 @@
3838
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="%sentry.listener_priorities.request%" />
3939
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController" priority="%sentry.listener_priorities.request%" />
4040
</service>
41+
42+
<service id="Sentry\SentryBundle\EventListener\SubRequestListener" class="Sentry\SentryBundle\EventListener\SubRequestListener" public="false">
43+
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="%sentry.listener_priorities.sub_request%" />
44+
<tag name="kernel.event_listener" event="kernel.finish_request" method="onKernelFinishRequest" priority="%sentry.listener_priorities.sub_request%" />
45+
</service>
4146
</services>
4247
</container>

test/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public function testConfigurationDefaults(): void
5252
'dsn' => null,
5353
'listener_priorities' => [
5454
'request' => 1,
55+
'sub_request' => 1,
5556
'console' => 1,
5657
],
5758
'options' => [

test/DependencyInjection/SentryExtensionTest.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
use Sentry\Integration\IntegrationInterface;
1010
use Sentry\Options;
1111
use Sentry\SentryBundle\DependencyInjection\SentryExtension;
12-
use Sentry\SentryBundle\EventListener\ConsoleListener;
13-
use Sentry\SentryBundle\EventListener\RequestListener;
1412
use Symfony\Component\DependencyInjection\Alias;
1513
use Symfony\Component\DependencyInjection\Container;
1614
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -21,8 +19,6 @@
2119

2220
class SentryExtensionTest extends TestCase
2321
{
24-
private const REQUEST_LISTENER_TEST_PUBLIC_ALIAS = 'sentry.request_listener.public_alias';
25-
private const CONSOLE_LISTENER_TEST_PUBLIC_ALIAS = 'sentry.console_listener.public_alias';
2622
private const OPTIONS_TEST_PUBLIC_ALIAS = 'sentry.options.public_alias';
2723

2824
public function testDataProviderIsMappingTheRightNumberOfOptions(): void
@@ -62,9 +58,25 @@ public function testOptionsDefaultValues(): void
6258
$this->assertSame(['var/cache', $vendorDir], $options->getInAppExcludedPaths());
6359

6460
$this->assertSame(1, $container->getParameter('sentry.listener_priorities.request'));
61+
$this->assertSame(1, $container->getParameter('sentry.listener_priorities.sub_request'));
6562
$this->assertSame(1, $container->getParameter('sentry.listener_priorities.console'));
6663
}
6764

65+
public function testListenerPriorities(): void
66+
{
67+
$container = $this->getContainer([
68+
'listener_priorities' => [
69+
'request' => 123,
70+
'sub_request' => 456,
71+
'console' => 789,
72+
],
73+
]);
74+
75+
$this->assertSame(123, $container->getParameter('sentry.listener_priorities.request'));
76+
$this->assertSame(456, $container->getParameter('sentry.listener_priorities.sub_request'));
77+
$this->assertSame(789, $container->getParameter('sentry.listener_priorities.console'));
78+
}
79+
6880
/**
6981
* @dataProvider optionsValueProvider
7082
*/
@@ -326,8 +338,6 @@ private function getContainer(array $configuration = []): Container
326338
$containerBuilder->set('request_stack', $mockRequestStack);
327339
$containerBuilder->set('event_dispatcher', $mockEventDispatcher);
328340
$containerBuilder->setAlias(self::OPTIONS_TEST_PUBLIC_ALIAS, new Alias(Options::class, true));
329-
$containerBuilder->setAlias(self::REQUEST_LISTENER_TEST_PUBLIC_ALIAS, new Alias(RequestListener::class, true));
330-
$containerBuilder->setAlias(self::CONSOLE_LISTENER_TEST_PUBLIC_ALIAS, new Alias(ConsoleListener::class, true));
331341

332342
$beforeSend = new Definition('callable');
333343
$beforeSend->setFactory([CallbackMock::class, 'createCallback']);
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Test\EventListener;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Sentry\SentryBundle\EventListener\SubRequestListener;
7+
use Sentry\State\Hub;
8+
use Sentry\State\HubInterface;
9+
use Sentry\State\Scope;
10+
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
11+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
12+
13+
class SubRequestListenerTest extends TestCase
14+
{
15+
private $currentHub;
16+
17+
protected function setUp()
18+
{
19+
parent::setUp();
20+
21+
$this->currentHub = $this->prophesize(HubInterface::class);
22+
23+
Hub::setCurrent($this->currentHub->reveal());
24+
}
25+
26+
public function testOnKernelRequestWithMasterRequest(): void
27+
{
28+
$listener = new SubRequestListener();
29+
30+
$subRequestEvent = $this->prophesize(GetResponseEvent::class);
31+
$subRequestEvent->isMasterRequest()
32+
->willReturn(true);
33+
34+
$this->currentHub->pushScope()
35+
->shouldNotBeCalled();
36+
37+
$listener->onKernelRequest($subRequestEvent->reveal());
38+
}
39+
40+
public function testOnKernelRequestWithSubRequest(): void
41+
{
42+
$listener = new SubRequestListener();
43+
44+
$subRequestEvent = $this->prophesize(GetResponseEvent::class);
45+
$subRequestEvent->isMasterRequest()
46+
->willReturn(false);
47+
48+
$this->currentHub->pushScope()
49+
->shouldBeCalledTimes(1)
50+
->willReturn(new Scope());
51+
52+
$listener->onKernelRequest($subRequestEvent->reveal());
53+
}
54+
55+
public function testOnKernelFinishRequestWithMasterRequest(): void
56+
{
57+
$listener = new SubRequestListener();
58+
59+
$subRequestEvent = $this->prophesize(FinishRequestEvent::class);
60+
$subRequestEvent->isMasterRequest()
61+
->willReturn(true);
62+
63+
$this->currentHub->popScope()
64+
->shouldNotBeCalled();
65+
66+
$listener->onKernelFinishRequest($subRequestEvent->reveal());
67+
}
68+
69+
public function testOnKernelFinishRequestWithSubRequest(): void
70+
{
71+
$listener = new SubRequestListener();
72+
73+
$subRequestEvent = $this->prophesize(FinishRequestEvent::class);
74+
$subRequestEvent->isMasterRequest()
75+
->willReturn(false);
76+
77+
$this->currentHub->popScope()
78+
->shouldBeCalledTimes(1)
79+
->willReturn(true);
80+
81+
$listener->onKernelFinishRequest($subRequestEvent->reveal());
82+
}
83+
}

test/SentryBundleTest.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
use Sentry\SentryBundle\DependencyInjection\SentryExtension;
77
use Sentry\SentryBundle\EventListener\ConsoleListener;
88
use Sentry\SentryBundle\EventListener\RequestListener;
9+
use Sentry\SentryBundle\EventListener\SubRequestListener;
10+
use Symfony\Component\Console\ConsoleEvents;
911
use Symfony\Component\DependencyInjection\ContainerBuilder;
1012
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1113
use Symfony\Component\HttpKernel\Kernel;
14+
use Symfony\Component\HttpKernel\KernelEvents;
1215

1316
class SentryBundleTest extends TestCase
1417
{
@@ -21,7 +24,7 @@ public function testContainerHasConsoleListenerConfiguredCorrectly(): void
2124
$expectedTag = [
2225
'kernel.event_listener' => [
2326
[
24-
'event' => 'console.command',
27+
'event' => ConsoleEvents::COMMAND,
2528
'method' => 'onConsoleCommand',
2629
'priority' => '%sentry.listener_priorities.console%',
2730
],
@@ -40,12 +43,12 @@ public function testContainerHasRequestListenerConfiguredCorrectly(): void
4043
$expectedTag = [
4144
'kernel.event_listener' => [
4245
[
43-
'event' => 'kernel.request',
46+
'event' => KernelEvents::REQUEST,
4447
'method' => 'onKernelRequest',
4548
'priority' => '%sentry.listener_priorities.request%',
4649
],
4750
[
48-
'event' => 'kernel.controller',
51+
'event' => KernelEvents::CONTROLLER,
4952
'method' => 'onKernelController',
5053
'priority' => '%sentry.listener_priorities.request%',
5154
],
@@ -55,6 +58,30 @@ public function testContainerHasRequestListenerConfiguredCorrectly(): void
5558
$this->assertSame($expectedTag, $consoleListener->getTags());
5659
}
5760

61+
public function testContainerHasSubRequestListenerConfiguredCorrectly(): void
62+
{
63+
$container = $this->getContainer();
64+
65+
$consoleListener = $container->getDefinition(SubRequestListener::class);
66+
67+
$expectedTag = [
68+
'kernel.event_listener' => [
69+
[
70+
'event' => KernelEvents::REQUEST,
71+
'method' => 'onKernelRequest',
72+
'priority' => '%sentry.listener_priorities.sub_request%',
73+
],
74+
[
75+
'event' => KernelEvents::FINISH_REQUEST,
76+
'method' => 'onKernelFinishRequest',
77+
'priority' => '%sentry.listener_priorities.sub_request%',
78+
],
79+
],
80+
];
81+
82+
$this->assertSame($expectedTag, $consoleListener->getTags());
83+
}
84+
5885
private function getContainer(array $configuration = []): ContainerBuilder
5986
{
6087
$containerBuilder = new ContainerBuilder();

0 commit comments

Comments
 (0)