Skip to content

Commit 9ae4370

Browse files
committed
General improvements
1 parent 29c0dd7 commit 9ae4370

File tree

7 files changed

+109
-62
lines changed

7 files changed

+109
-62
lines changed

composer.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
"jean85/pretty-package-versions": "^1.5 || ^2.0",
2424
"php-http/discovery": "^1.11",
2525
"sentry/sdk": "^3.1",
26-
"symfony/config": "^3.4.44||^4.4.11||^5.0.11",
27-
"symfony/console": "^3.4.44||^4.4.11||^5.0.11",
28-
"symfony/dependency-injection": "^3.4.44||^4.4.11||^5.0.11",
29-
"symfony/event-dispatcher": "^3.4.44||^4.4.11||^5.0.11",
30-
"symfony/http-kernel": "^3.4.44||^4.4.11||^5.0.11",
26+
"symfony/config": "^3.4.44||^4.4.12||^5.0.11",
27+
"symfony/console": "^3.4.44||^4.4.12||^5.0.11",
28+
"symfony/dependency-injection": "^3.4.44||^4.4.12||^5.0.11",
29+
"symfony/event-dispatcher": "^3.4.44||^4.4.12||^5.0.11",
30+
"symfony/http-kernel": "^3.4.44||^4.4.12||^5.0.11",
3131
"symfony/psr-http-message-bridge": "^2.0",
32-
"symfony/security-core": "^3.4.44||^4.4.11||^5.0.11"
32+
"symfony/security-core": "^3.4.44||^4.4.12||^5.0.11"
3333
},
3434
"require-dev": {
3535
"doctrine/dbal": "^2.10||^3.0",
@@ -46,18 +46,18 @@
4646
"symfony/browser-kit": "^3.4.44||^4.4.12||^5.0.11",
4747
"symfony/dom-crawler": "^3.4.44||^4.4.12||^5.0.11",
4848
"symfony/framework-bundle": "^3.4.44||^4.4.12||^5.0.11",
49-
"symfony/messenger": "^4.4.11||^5.0.11",
49+
"symfony/messenger": "^4.4.12||^5.0.11",
5050
"symfony/monolog-bundle": "^3.4",
5151
"symfony/phpunit-bridge": "^5.0",
5252
"symfony/polyfill-php80": "^1.22",
5353
"symfony/twig-bundle": "^3.4.44||^4.4.12||^5.0.11",
54-
"symfony/yaml": "^3.4.44||^4.4.11||^5.0.11",
54+
"symfony/yaml": "^3.4.44||^4.4.12||^5.0.11",
5555
"vimeo/psalm": "^4.3"
5656
},
5757
"suggest": {
5858
"monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler.",
5959
"doctrine/doctrine-bundle": "Allow distributed tracing of database queries using Sentry.",
60-
"symfony/twig-bundle": "Allow distributed tracing of twig template rendering using Sentry."
60+
"symfony/twig-bundle": "Allow distributed tracing of Twig template rendering using Sentry."
6161
},
6262
"autoload": {
6363
"files": [

psalm.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<directory name="vendor" />
1414
</ignoreFiles>
1515
</projectFiles>
16+
1617
<stubs>
1718
<file name="tests/Stubs/Profile.phpstub"/>
1819
</stubs>

src/Resources/config/schema/sentry-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595

9696
<xsd:attribute name="enabled" type="xsd:boolean" />
9797
</xsd:complexType>
98+
9899
<xsd:complexType name="tracing-twig">
99100
<xsd:attribute name="enabled" type="xsd:boolean" />
100101
</xsd:complexType>

src/Resources/config/services.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575

7676
<service id="Sentry\SentryBundle\Tracing\Twig\TwigTracingExtension" class="Sentry\SentryBundle\Tracing\Twig\TwigTracingExtension">
7777
<argument type="service" id="Sentry\State\HubInterface" />
78+
7879
<tag name="twig.extension" />
7980
</service>
8081

src/Tracing/Twig/TwigTracingExtension.php

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Sentry\SentryBundle\Tracing\Twig;
66

77
use Sentry\State\HubInterface;
8+
use Sentry\Tracing\Span;
89
use Sentry\Tracing\SpanContext;
910
use SplObjectStorage;
1011
use Twig\Extension\AbstractExtension;
@@ -19,46 +20,83 @@ final class TwigTracingExtension extends AbstractExtension
1920
private $hub;
2021

2122
/**
22-
* @var SplObjectStorage<object, \Sentry\Tracing\Span>
23+
* @var SplObjectStorage<object, Span> The currently active spans
2324
*/
24-
private $events;
25+
private $spans;
2526

2627
/**
2728
* @param HubInterface $hub The current hub
2829
*/
2930
public function __construct(HubInterface $hub)
3031
{
3132
$this->hub = $hub;
32-
$this->events = new SplObjectStorage();
33+
$this->spans = new SplObjectStorage();
3334
}
3435

36+
/**
37+
* This method is called before the execution of a block, a macro or a
38+
* template.
39+
*
40+
* @param Profile $profile The profiling data
41+
*/
3542
public function enter(Profile $profile): void
3643
{
3744
$transaction = $this->hub->getTransaction();
3845

39-
if (null === $transaction || !$profile->isTemplate()) {
46+
if (null === $transaction) {
4047
return;
4148
}
4249

4350
$spanContext = new SpanContext();
44-
$spanContext->setOp('twig.template');
45-
$spanContext->setDescription($profile->getName());
51+
$spanContext->setOp('view.render');
52+
$spanContext->setDescription($this->getSpanDescription($profile));
4653

47-
$this->events[$profile] = $transaction->startChild($spanContext);
54+
$this->spans[$profile] = $transaction->startChild($spanContext);
4855
}
4956

57+
/**
58+
* This method is called when the execution of a block, a macro or a
59+
* template is finished.
60+
*
61+
* @param Profile $profile The profiling data
62+
*/
5063
public function leave(Profile $profile): void
5164
{
52-
if (empty($this->events[$profile]) || !$profile->isTemplate()) {
65+
if (!isset($this->spans[$profile])) {
5366
return;
5467
}
5568

56-
$this->events[$profile]->finish();
57-
unset($this->events[$profile]);
69+
$this->spans[$profile]->finish();
70+
71+
unset($this->spans[$profile]);
5872
}
5973

74+
/**
75+
* {@inheritdoc}
76+
*/
6077
public function getNodeVisitors(): array
6178
{
62-
return [new ProfilerNodeVisitor(static::class)];
79+
return [
80+
new ProfilerNodeVisitor(self::class),
81+
];
82+
}
83+
84+
/**
85+
* Gets a short description for the span.
86+
*
87+
* @param Profile $profile The profiling data
88+
*/
89+
private function getSpanDescription(Profile $profile): string
90+
{
91+
switch (true) {
92+
case $profile->isRoot():
93+
return $profile->getName();
94+
95+
case $profile->isTemplate():
96+
return $profile->getTemplate();
97+
98+
default:
99+
return sprintf('%s::%s(%s)', $profile->getTemplate(), $profile->getType(), $profile->getName());
100+
}
63101
}
64102
}

tests/Stubs/Profile.phpstub

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ namespace Twig\Profiler;
66
* @template-implements \IteratorAggregate<Profile, Profile>
77
*/
88
final class Profile implements \IteratorAggregate, \Serializable
9-
{}
9+
{
10+
}

tests/Tracing/Twig/TwigTracingExtensionTest.php

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,66 +30,64 @@ protected function setUp(): void
3030
$this->listener = new TwigTracingExtension($this->hub);
3131
}
3232

33-
public function testThatTwigEnterProfileIgnoresTracingWhenTransactionIsNotStarted(): void
33+
/**
34+
* @dataProvider enterDataProvider
35+
*/
36+
public function testEnter(Profile $profile, string $spanDescription): void
3437
{
35-
$this->hub->expects($this->once())
36-
->method('getTransaction')
37-
->willReturn(null);
38-
39-
$this->listener->enter(new Profile('main', Profile::TEMPLATE));
40-
}
38+
$transaction = new Transaction(new TransactionContext());
39+
$transaction->initSpanRecorder();
4140

42-
public function testThatTwigEnterProfileIgnoresTracingWhenNotATemplate(): void
43-
{
4441
$this->hub->expects($this->once())
4542
->method('getTransaction')
46-
->willReturn(new Transaction(new TransactionContext()));
47-
48-
$this->listener->enter(new Profile('main', Profile::ROOT));
49-
}
43+
->willReturn($transaction);
5044

51-
public function testThatTwigLeaveProfileIgnoresTracingWhenTransactionIsNotStarted(): void
52-
{
53-
$this->hub->expects($this->once())
54-
->method('getTransaction')
55-
->willReturn(null);
45+
$this->listener->enter($profile);
5646

57-
$profile = new Profile('main', Profile::TEMPLATE);
47+
$spans = $transaction->getSpanRecorder()->getSpans();
5848

59-
$this->listener->enter($profile);
60-
$this->listener->leave($profile);
49+
$this->assertCount(2, $spans);
50+
$this->assertNull($spans[1]->getEndTimestamp());
51+
$this->assertSame('view.render', $spans[1]->getOp());
52+
$this->assertSame($spanDescription, $spans[1]->getDescription());
6153
}
6254

63-
public function testThatTwigLeaveProfileIgnoresTracingWhenNotATemplate(): void
55+
/**
56+
* @return \Generator<mixed>
57+
*/
58+
public function enterDataProvider(): \Generator
6459
{
65-
$this->hub->expects($this->once())
66-
->method('getTransaction')
67-
->willReturn(new Transaction(new TransactionContext()));
68-
69-
$profile = new Profile('main', Profile::ROOT);
70-
71-
$this->listener->enter($profile);
72-
$this->listener->leave($profile);
60+
yield [
61+
new Profile('main.twig', Profile::ROOT),
62+
'main',
63+
];
64+
65+
yield [
66+
new Profile('main.twig', Profile::TEMPLATE),
67+
'main.twig',
68+
];
69+
70+
yield [
71+
new Profile('main.twig', Profile::BLOCK, 'content'),
72+
'main.twig::block(content)',
73+
];
74+
75+
yield [
76+
new Profile('main.twig', Profile::MACRO, 'input'),
77+
'main.twig::macro(input)',
78+
];
7379
}
7480

75-
public function testThatTwigEnterProfileAttachesAChildSpanWhenTransactionStarted(): void
81+
public function testEnterDoesNothingIfNoSpanIsSetOnHub(): void
7682
{
77-
$transaction = new Transaction(new TransactionContext());
78-
$transaction->initSpanRecorder();
79-
8083
$this->hub->expects($this->once())
8184
->method('getTransaction')
82-
->willReturn($transaction);
85+
->willReturn(null);
8386

8487
$this->listener->enter(new Profile('main', Profile::TEMPLATE));
85-
86-
$spans = $transaction->getSpanRecorder()->getSpans();
87-
88-
$this->assertCount(2, $spans);
89-
$this->assertNull($spans[1]->getEndTimestamp());
9088
}
9189

92-
public function testThatTwigLeaveProfileFinishesTheChildSpanWhenChildSpanStarted(): void
90+
public function testLeave(): void
9391
{
9492
$transaction = new Transaction(new TransactionContext());
9593
$transaction->initSpanRecorder();
@@ -108,4 +106,11 @@ public function testThatTwigLeaveProfileFinishesTheChildSpanWhenChildSpanStarted
108106
$this->assertCount(2, $spans);
109107
$this->assertNotNull($spans[1]->getEndTimestamp());
110108
}
109+
110+
public function testLeaveDoesNothingIfSpanDoesNotExistsForProfile(): void
111+
{
112+
$this->expectNotToPerformAssertions();
113+
114+
$this->listener->leave(new Profile('main', Profile::TEMPLATE));
115+
}
111116
}

0 commit comments

Comments
 (0)