Skip to content

Commit 2c1da9a

Browse files
authored
Add TextMapPropagator to instrumentation context (#1401)
1 parent c632d96 commit 2c1da9a

File tree

6 files changed

+96
-5
lines changed

6 files changed

+96
-5
lines changed

examples/instrumentation/configure_instrumentation.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
use OpenTelemetry\API\Globals;
99
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\ExtensionHookManager;
1010
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\Instrumentation;
11-
use OpenTelemetry\API\Logs\NoopLoggerProvider;
12-
use OpenTelemetry\API\Metrics\Noop\NoopMeterProvider;
1311
use OpenTelemetry\Config\SDK\Configuration;
1412
use OpenTelemetry\Config\SDK\Configuration\Context;
1513
use OpenTelemetry\Example\Example;
@@ -25,7 +23,7 @@
2523
Configuration::parseFile(__DIR__ . '/otel-sdk.yaml')->create(new Context())->setAutoShutdown(true)->buildAndRegisterGlobal();
2624
$configuration = \OpenTelemetry\Config\SDK\Instrumentation::parseFile(__DIR__ . '/otel-sdk.yaml')->create();
2725
$hookManager = new ExtensionHookManager();
28-
$context = new \OpenTelemetry\API\Instrumentation\AutoInstrumentation\Context(Globals::tracerProvider(), new NoopMeterProvider(), new NoopLoggerProvider());
26+
$context = new \OpenTelemetry\API\Instrumentation\AutoInstrumentation\Context(Globals::tracerProvider(), Globals::meterProvider(), Globals::loggerProvider(), Globals::propagator());
2927

3028
foreach (ServiceLoader::load(Instrumentation::class) as $instrumentation) {
3129
$instrumentation->register($hookManager, $configuration, $context);

src/API/Instrumentation/AutoInstrumentation/Context.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use OpenTelemetry\API\Metrics\Noop\NoopMeterProvider;
1111
use OpenTelemetry\API\Trace\NoopTracerProvider;
1212
use OpenTelemetry\API\Trace\TracerProviderInterface;
13+
use OpenTelemetry\Context\Propagation\NoopTextMapPropagator;
14+
use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
1315

1416
/**
1517
* Context used for component creation.
@@ -20,6 +22,7 @@ public function __construct(
2022
public readonly TracerProviderInterface $tracerProvider = new NoopTracerProvider(),
2123
public readonly MeterProviderInterface $meterProvider = new NoopMeterProvider(),
2224
public readonly LoggerProviderInterface $loggerProvider = new NoopLoggerProvider(),
25+
public readonly TextMapPropagatorInterface $propagator = new NoopTextMapPropagator(),
2326
) {
2427
}
2528
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenTelemetry\SDK\Propagation;
6+
7+
use Closure;
8+
use OpenTelemetry\Context\ContextInterface;
9+
use OpenTelemetry\Context\Propagation\PropagationGetterInterface;
10+
use OpenTelemetry\Context\Propagation\PropagationSetterInterface;
11+
use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
12+
13+
/**
14+
* @internal
15+
*/
16+
final class LateBindingTextMapPropagator implements TextMapPropagatorInterface
17+
{
18+
19+
/**
20+
* @param TextMapPropagatorInterface|Closure(): TextMapPropagatorInterface $propagator
21+
*/
22+
public function __construct(
23+
private TextMapPropagatorInterface|Closure $propagator,
24+
) {
25+
}
26+
27+
public function fields(): array
28+
{
29+
if (!$this->propagator instanceof TextMapPropagatorInterface) {
30+
$this->propagator = ($this->propagator)();
31+
}
32+
33+
return $this->propagator->fields();
34+
}
35+
36+
public function inject(mixed &$carrier, ?PropagationSetterInterface $setter = null, ?ContextInterface $context = null): void
37+
{
38+
if (!$this->propagator instanceof TextMapPropagatorInterface) {
39+
$this->propagator = ($this->propagator)();
40+
}
41+
42+
$this->propagator->inject($carrier, $setter, $context);
43+
}
44+
45+
public function extract($carrier, ?PropagationGetterInterface $getter = null, ?ContextInterface $context = null): ContextInterface
46+
{
47+
if (!$this->propagator instanceof TextMapPropagatorInterface) {
48+
$this->propagator = ($this->propagator)();
49+
}
50+
51+
return $this->propagator->extract($carrier, $getter, $context);
52+
}
53+
}

src/SDK/SdkAutoloader.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
use OpenTelemetry\Config\SDK\Configuration as SdkConfiguration;
2424
use OpenTelemetry\Config\SDK\Instrumentation as SdkInstrumentation;
2525
use OpenTelemetry\Context\Context;
26+
use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
2627
use OpenTelemetry\SDK\Common\Configuration\Configuration;
2728
use OpenTelemetry\SDK\Common\Configuration\Variables;
2829
use OpenTelemetry\SDK\Common\Util\ShutdownHandler;
2930
use OpenTelemetry\SDK\Logs\EventLoggerProviderFactory;
3031
use OpenTelemetry\SDK\Logs\LoggerProviderFactory;
3132
use OpenTelemetry\SDK\Metrics\MeterProviderFactory;
33+
use OpenTelemetry\SDK\Propagation\LateBindingTextMapPropagator;
3234
use OpenTelemetry\SDK\Propagation\PropagatorFactory;
3335
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
3436
use OpenTelemetry\SDK\Trace\AutoRootSpan;
@@ -154,7 +156,8 @@ private static function registerInstrumentations(): void
154156
$tracerProvider = self::createLateBindingTracerProvider();
155157
$meterProvider = self::createLateBindingMeterProvider();
156158
$loggerProvider = self::createLateBindingLoggerProvider();
157-
$context = new InstrumentationContext($tracerProvider, $meterProvider, $loggerProvider);
159+
$propagator = self::createLateBindingTextMapPropagator();
160+
$context = new InstrumentationContext($tracerProvider, $meterProvider, $loggerProvider, $propagator);
158161

159162
foreach (ServiceLoader::load(Instrumentation::class) as $instrumentation) {
160163
/** @var Instrumentation $instrumentation */
@@ -204,6 +207,19 @@ private static function createLateBindingLoggerProvider(): LoggerProviderInterfa
204207
});
205208
}
206209

210+
private static function createLateBindingTextMapPropagator(): TextMapPropagatorInterface
211+
{
212+
return new LateBindingTextMapPropagator(static function (): TextMapPropagatorInterface {
213+
$scope = Context::getRoot()->activate();
214+
215+
try {
216+
return Globals::propagator();
217+
} finally {
218+
$scope->detach();
219+
}
220+
});
221+
}
222+
207223
private static function getHookManager(): HookManagerInterface
208224
{
209225
/** @var HookManagerInterface $hookManager */

tests/Unit/API/Instrumentation/AutoInstrumentation/ContextTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use OpenTelemetry\API\Logs\NoopLoggerProvider;
99
use OpenTelemetry\API\Metrics\Noop\NoopMeterProvider;
1010
use OpenTelemetry\API\Trace\NoopTracerProvider;
11+
use OpenTelemetry\Context\Propagation\NoopTextMapPropagator;
1112
use PHPUnit\Framework\Attributes\CoversClass;
1213
use PHPUnit\Framework\TestCase;
1314

@@ -20,5 +21,6 @@ public function test_default_noops(): void
2021
$this->assertInstanceOf(NoopTracerProvider::class, $context->tracerProvider);
2122
$this->assertInstanceOf(NoopMeterProvider::class, $context->meterProvider);
2223
$this->assertInstanceOf(NoopLoggerProvider::class, $context->loggerProvider);
24+
$this->assertInstanceOf(NoopTextMapPropagator::class, $context->propagator);
2325
}
2426
}

tests/Unit/API/Instrumentation/AutoInstrumentation/LateBindingProviderTest.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace OpenTelemetry\Tests\Unit\API\Instrumentation\AutoInstrumentation;
66

7+
use function assert;
78
use Nevay\SPI\ServiceLoader;
89
use OpenTelemetry\API\Behavior\Internal\Logging;
910
use OpenTelemetry\API\Configuration\ConfigProperties;
@@ -25,11 +26,13 @@
2526
use OpenTelemetry\API\Trace\LateBindingTracerProvider;
2627
use OpenTelemetry\API\Trace\TracerInterface;
2728
use OpenTelemetry\API\Trace\TracerProviderInterface;
29+
use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
2830
use OpenTelemetry\SDK\Common\Configuration\Variables;
2931
use OpenTelemetry\SDK\SdkAutoloader;
3032
use OpenTelemetry\Tests\TestState;
3133
use PHPUnit\Framework\Attributes\CoversClass;
3234
use PHPUnit\Framework\TestCase;
35+
use Prophecy\PhpUnit\ProphecyTrait;
3336

3437
#[CoversClass(LateBindingLoggerProvider::class)]
3538
#[CoversClass(LateBindingLogger::class)]
@@ -45,6 +48,7 @@
4548
class LateBindingProviderTest extends TestCase
4649
{
4750
use TestState;
51+
use ProphecyTrait;
4852

4953
public function setUp(): void
5054
{
@@ -77,6 +81,12 @@ public function getLogger(): LoggerInterface
7781

7882
return self::$context->loggerProvider->getLogger('test');
7983
}
84+
public function getPropagator(): TextMapPropagatorInterface
85+
{
86+
assert(self::$context !== null);
87+
88+
return self::$context->propagator;
89+
}
8090
};
8191
$this->setEnvironmentVariable(Variables::OTEL_PHP_AUTOLOAD_ENABLED, 'true');
8292
$tracer_accessed = false;
@@ -101,14 +111,17 @@ public function getLogger(): LoggerInterface
101111

102112
return $this->createMock(LoggerInterface::class);
103113
});
114+
$propagator = $this->prophesize(TextMapPropagatorInterface::class);
115+
104116
ServiceLoader::register(Instrumentation::class, $instrumentation::class);
105117
$this->assertTrue(SdkAutoloader::autoload());
106118
//initializer added _after_ autoloader has run and instrumentation registered
107-
Globals::registerInitializer(function (Configurator $configurator) use ($tracerProvider, $loggerProvider, $meterProvider): Configurator {
119+
Globals::registerInitializer(function (Configurator $configurator) use ($tracerProvider, $loggerProvider, $meterProvider, $propagator): Configurator {
108120
return $configurator
109121
->withTracerProvider($tracerProvider)
110122
->withMeterProvider($meterProvider)
111123
->withLoggerProvider($loggerProvider)
124+
->withPropagator($propagator->reveal())
112125
;
113126
});
114127

@@ -129,5 +142,11 @@ public function getLogger(): LoggerInterface
129142
$this->assertFalse($logger_accessed);
130143
$logger->emit(new LogRecord()); /** @phpstan-ignore-next-line */
131144
$this->assertTrue($logger_accessed);
145+
146+
/** @phpstan-ignore-next-line */
147+
$propagator->fields()->shouldNotHaveBeenCalled();
148+
$instrumentation->getPropagator()->fields();
149+
/** @phpstan-ignore-next-line */
150+
$propagator->fields()->shouldHaveBeenCalledOnce();
132151
}
133152
}

0 commit comments

Comments
 (0)