Skip to content

Commit a5fba8a

Browse files
committed
Merge branch '2.0.x' into 1.0.x
# Conflicts: # src/Bridge/ContextInjector.php
2 parents dc395fa + 5d9767e commit a5fba8a

File tree

8 files changed

+237
-42
lines changed

8 files changed

+237
-42
lines changed

src/Bridge/ContextInjector.php

Lines changed: 14 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,24 @@
11
<?php
22
namespace Jaeger\Symfony\Bridge;
33

4-
use Jaeger\Codec\CodecInterface;
5-
use Jaeger\Codec\CodecRegistry;
4+
use Jaeger\Symfony\Context\Extractor\ContextExtractorInterface;
65
use Jaeger\Tracer\InjectableInterface;
7-
use Jaeger\Tracer\TracerInterface;
86
use Symfony\Component\Console\ConsoleEvents;
97
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10-
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
11-
use Symfony\Component\HttpKernel\HttpKernelInterface;
128
use Symfony\Component\HttpKernel\KernelEvents;
139

1410
class ContextInjector implements EventSubscriberInterface
1511
{
1612
private $injectable;
1713

18-
private $tracer;
19-
20-
/**
21-
* @var CodecInterface[]
22-
*/
23-
private $registry;
24-
25-
private $format;
26-
27-
private $envName;
28-
29-
private $headerName;
14+
private $extractor;
3015

3116
public function __construct(
3217
InjectableInterface $injectable,
33-
TracerInterface $tracer,
34-
CodecRegistry $registry,
35-
$format,
36-
$envName,
37-
$headerName
18+
ContextExtractorInterface $extractor
3819
) {
3920
$this->injectable = $injectable;
40-
$this->tracer = $tracer;
41-
$this->registry = $registry;
42-
$this->format = $format;
43-
$this->envName = $envName;
44-
$this->headerName = $headerName;
21+
$this->extractor = $extractor;
4522
}
4623

4724
public static function getSubscribedEvents()
@@ -52,26 +29,23 @@ public static function getSubscribedEvents()
5229
];
5330
}
5431

55-
public function onCommand()
32+
public function inject(): ContextInjector
5633
{
57-
if (($data = $_ENV[$this->envName] ? $_ENV[$this->envName]: null)
58-
&& $context = $this->registry[$this->format]->decode($data)) {
59-
$this->injectable->assign($context);
34+
if (null === ($context = $this->extractor->extract())) {
35+
return $this;
6036
}
61-
37+
$this->injectable->assign($context);
6238

6339
return $this;
6440
}
6541

66-
public function onRequest(GetResponseEvent $event)
42+
public function onCommand()
6743
{
68-
$request = $event->getRequest();
69-
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()
70-
&& $request->headers->has($this->headerName)
71-
&& ($context = $this->registry[$this->format]->decode($request->headers->get($this->headerName)))) {
72-
$this->injectable->assign($context);
73-
}
44+
return $this->inject();
45+
}
7446

75-
return $this;
47+
public function onRequest()
48+
{
49+
return $this->inject();
7650
}
7751
}

src/Bridge/RequestSpanListener.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ public function onRequest(GetResponseEvent $event)
9191
->addTag(new LongTag('time.micro', $startTime))
9292
->start($startTime);
9393
}
94-
9594
$this->spans->push($requestSpan);
9695

9796
return $this;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Symfony\Context\Extractor;
5+
6+
use Jaeger\Span\Context\SpanContext;
7+
8+
class ContextExtractorChain implements ContextExtractorInterface
9+
{
10+
private $queue;
11+
12+
public function __construct(\SplPriorityQueue $queue)
13+
{
14+
$this->queue = $queue;
15+
}
16+
17+
public function add(ContextExtractorInterface $extractor, int $priority = 0): ContextExtractorChain
18+
{
19+
$this->queue->insert($extractor, $priority);
20+
21+
return $this;
22+
}
23+
24+
public function extract(): ?SpanContext
25+
{
26+
$queue = clone $this->queue;
27+
while (false === $queue->isEmpty()) {
28+
if (null !== ($context = $queue->extract()->extract())) {
29+
return $context;
30+
}
31+
}
32+
33+
return null;
34+
}
35+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Symfony\Context\Extractor;
5+
6+
use Jaeger\Span\Context\SpanContext;
7+
8+
interface ContextExtractorInterface
9+
{
10+
public function extract() : ?SpanContext;
11+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Symfony\Context\Extractor;
5+
6+
use Jaeger\Codec\CodecInterface;
7+
use Jaeger\Codec\CodecRegistry;
8+
use Jaeger\Span\Context\SpanContext;
9+
use Symfony\Component\Console\ConsoleEvents;
10+
11+
class EnvContextExtractor implements ContextExtractorInterface
12+
{
13+
/**
14+
* @var CodecInterface[]
15+
*/
16+
private $registry;
17+
18+
private $format;
19+
20+
private $envName;
21+
22+
private $context;
23+
24+
public function __construct(CodecRegistry $registry, string $format, string $envName)
25+
{
26+
$this->registry = $registry;
27+
$this->format = $format;
28+
$this->envName = $envName;
29+
}
30+
31+
public function extract(): ?SpanContext
32+
{
33+
return $this->context;
34+
}
35+
36+
public static function getSubscribedEvents()
37+
{
38+
return [
39+
ConsoleEvents::COMMAND => ['onCommand', 2048],
40+
];
41+
}
42+
43+
public function onCommand()
44+
{
45+
if (null === ($data = $_ENV[$this->envName] ?? null)) {
46+
return $this;
47+
}
48+
49+
if (null === ($context = $this->registry[$this->format]->decode($data))) {
50+
return $this;
51+
}
52+
$this->context = $context;
53+
54+
return $this;
55+
}
56+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Symfony\Context\Extractor;
5+
6+
use Jaeger\Codec\CodecInterface;
7+
use Jaeger\Codec\CodecRegistry;
8+
use Jaeger\Span\Context\SpanContext;
9+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
10+
use Symfony\Component\HttpKernel\HttpKernelInterface;
11+
use Symfony\Component\HttpKernel\KernelEvents;
12+
13+
class HeaderContextExtractor implements ContextExtractorInterface
14+
{
15+
/**
16+
* @var CodecInterface[]
17+
*/
18+
private $registry;
19+
20+
private $format;
21+
22+
private $headerName;
23+
24+
private $context;
25+
26+
public function __construct(CodecRegistry $registry, string $format, string $headerName)
27+
{
28+
$this->registry = $registry;
29+
$this->format = $format;
30+
$this->headerName = $headerName;
31+
}
32+
33+
public function extract(): ?SpanContext
34+
{
35+
return $this->context;
36+
}
37+
38+
public static function getSubscribedEvents()
39+
{
40+
return [
41+
KernelEvents::REQUEST => ['onRequest', 2048],
42+
];
43+
}
44+
45+
public function onRequest(GetResponseEvent $event)
46+
{
47+
$request = $event->getRequest();
48+
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
49+
$this->context = null;
50+
51+
return $this;
52+
}
53+
54+
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()
55+
&& $request->headers->has($this->headerName)
56+
&& ($context = $this->registry[$this->format]->decode($request->headers->get($this->headerName)))) {
57+
$this->context = $context;
58+
59+
return $this;
60+
}
61+
62+
return $this;
63+
}
64+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Symfony\Resources\DependencyInjection;
5+
6+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
use Symfony\Component\DependencyInjection\Reference;
9+
10+
class ExtractorChainCompilerPass implements CompilerPassInterface
11+
{
12+
public function process(ContainerBuilder $container)
13+
{
14+
if (false === $container->hasDefinition('jaeger.context.extractor.chain')) {
15+
throw new \RuntimeException(
16+
sprintf('Required service %s is missing from container', 'jaeger.context.extractor.chain')
17+
);
18+
}
19+
20+
$definition = $container->getDefinition('jaeger.context.extractor.chain');
21+
foreach ($container->findTaggedServiceIds('jaeger.context.extractor') as $id => $tags) {
22+
foreach ($tags as $tag) {
23+
if (false === array_key_exists('alias', $tag)) {
24+
throw new \RuntimeException(
25+
sprintf('Required tag field %s is missing from definition', 'alias')
26+
);
27+
}
28+
$priority = $tag['priority'] ?? 0;
29+
$definition->addMethodCall('add', [new Reference($id), $priority]);
30+
}
31+
}
32+
}
33+
}

src/Resources/config/services.yml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ services:
1111
spl.stack:
1212
class: SplStack
1313
shared: false
14+
spl.priority.queue:
15+
class: SplPriorityQueue
16+
shared: false
1417
id.generator.random:
1518
class: Jaeger\Id\RandomIntGenerator
1619
id.generator.span: '@id.generator.random'
@@ -68,13 +71,33 @@ services:
6871
class: Jaeger\Symfony\Bridge\ContextInjector
6972
arguments:
7073
- '@jaeger.tracer'
71-
- '@jaeger.tracer'
74+
- '@jaeger.context.extractor'
75+
tags:
76+
- {name: 'kernel.event_subscriber' }
77+
jaeger.context.extractor.env:
78+
class: Jaeger\Symfony\Context\Extractor\EnvContextExtractor
79+
arguments:
7280
- '@jaeger.codec.registry'
7381
- '%env(JAEGER_CONTEXT_FORMAT)%'
7482
- '%env(JAEGER_CONTEXT_ENV)%'
83+
tags:
84+
- {name: 'kernel.event_subscriber' }
85+
- {name: 'jaeger.context.extractor'}
86+
jaeger.context.extractor.header:
87+
class: Jaeger\Symfony\Context\Extractor\HeaderContextExtractor
88+
arguments:
89+
- '@jaeger.codec.registry'
90+
- '%env(JAEGER_CONTEXT_FORMAT)%'
7591
- '%env(JAEGER_CONTEXT_HEADER)%'
7692
tags:
7793
- {name: 'kernel.event_subscriber' }
94+
- {name: 'jaeger.context.extractor'}
95+
jaeger.context.extractor.chain:
96+
class: Jaeger\Symfony\Context\Extractor\ContextExtractorChain
97+
arguments:
98+
- '@spl.priority.queue'
99+
jaeger.context.extractor:
100+
alias: '@jaeger.context.extractor.chain'
78101
request.span.listener:
79102
class: Jaeger\Symfony\Bridge\RequestSpanListener
80103
arguments:

0 commit comments

Comments
 (0)