Skip to content

Commit

Permalink
adding configuration resolver (#1083)
Browse files Browse the repository at this point in the history
adding a configuration resolver interface, and api+sdk implementations. the resolver is globally configured.
this allows contrib modules to fetch config if an SDK is installed, without directly using the SDK (per spec).
  • Loading branch information
brettmc authored Jul 31, 2023
1 parent 1905dbf commit 7b8daff
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 4 deletions.
16 changes: 13 additions & 3 deletions src/API/Globals.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use function assert;
use Closure;
use const E_USER_WARNING;
use OpenTelemetry\API\Instrumentation\ConfigurationResolverInterface;
use OpenTelemetry\API\Instrumentation\Configurator;
use OpenTelemetry\API\Instrumentation\ContextKeys;
use OpenTelemetry\API\Logs\LoggerProviderInterface;
Expand All @@ -31,17 +32,20 @@ final class Globals
private MeterProviderInterface $meterProvider;
private TextMapPropagatorInterface $propagator;
private LoggerProviderInterface $loggerProvider;
private ConfigurationResolverInterface $configurationResolver;

public function __construct(
TracerProviderInterface $tracerProvider,
MeterProviderInterface $meterProvider,
LoggerProviderInterface $loggerProvider,
TextMapPropagatorInterface $propagator
TextMapPropagatorInterface $propagator,
ConfigurationResolverInterface $configurationResolver
) {
$this->tracerProvider = $tracerProvider;
$this->meterProvider = $meterProvider;
$this->loggerProvider = $loggerProvider;
$this->propagator = $propagator;
$this->configurationResolver = $configurationResolver;
}

public static function tracerProvider(): TracerProviderInterface
Expand All @@ -64,6 +68,11 @@ public static function loggerProvider(): LoggerProviderInterface
return Context::getCurrent()->get(ContextKeys::loggerProvider()) ?? self::globals()->loggerProvider;
}

public static function configurationResolver(): ConfigurationResolverInterface
{
return Context::getCurrent()->get(ContextKeys::configurationResolver()) ?? self::globals()->configurationResolver;
}

/**
* @param Closure(Configurator): Configurator $initializer
*
Expand Down Expand Up @@ -104,10 +113,11 @@ private static function globals(): self
$meterProvider = $context->get(ContextKeys::meterProvider());
$propagator = $context->get(ContextKeys::propagator());
$loggerProvider = $context->get(ContextKeys::loggerProvider());
$configurationResolver = $context->get(ContextKeys::configurationResolver());

assert(isset($tracerProvider, $meterProvider, $loggerProvider, $propagator));
assert(isset($tracerProvider, $meterProvider, $loggerProvider, $propagator, $configurationResolver));

return self::$globals = new self($tracerProvider, $meterProvider, $loggerProvider, $propagator);
return self::$globals = new self($tracerProvider, $meterProvider, $loggerProvider, $propagator, $configurationResolver);
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/API/Instrumentation/ConfigurationResolverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Instrumentation;

interface ConfigurationResolverInterface
{
public function has(string $name): bool;
public function getString(string $name): ?string;
public function getBoolean(string $name): ?bool;
public function getInt(string $name): ?int;
public function getList(string $name): array;
}
14 changes: 14 additions & 0 deletions src/API/Instrumentation/Configurator.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ final class Configurator implements ImplicitContextKeyedInterface
private ?MeterProviderInterface $meterProvider = null;
private ?TextMapPropagatorInterface $propagator = null;
private ?LoggerProviderInterface $loggerProvider = null;
private ?ConfigurationResolverInterface $configurationResolver = null;

private function __construct()
{
Expand All @@ -51,6 +52,7 @@ public static function createNoop(): Configurator
->withMeterProvider(new NoopMeterProvider())
->withPropagator(new NoopTextMapPropagator())
->withLoggerProvider(new NoopLoggerProvider())
->withConfigurationResolver(new NoopConfigurationResolver())
;
}

Expand All @@ -75,6 +77,9 @@ public function storeInContext(?ContextInterface $context = null): ContextInterf
if ($this->loggerProvider !== null) {
$context = $context->with(ContextKeys::loggerProvider(), $this->loggerProvider);
}
if ($this->configurationResolver !== null) {
$context = $context->with(ContextKeys::configurationResolver(), $this->configurationResolver);
}

return $context;
}
Expand Down Expand Up @@ -102,11 +107,20 @@ public function withPropagator(?TextMapPropagatorInterface $propagator): Configu

return $self;
}

public function withLoggerProvider(?LoggerProviderInterface $loggerProvider): Configurator
{
$self = clone $this;
$self->loggerProvider = $loggerProvider;

return $self;
}

public function withConfigurationResolver(?ConfigurationResolverInterface $configurationResolver): Configurator
{
$self = clone $this;
$self->configurationResolver = $configurationResolver;

return $self;
}
}
10 changes: 10 additions & 0 deletions src/API/Instrumentation/ContextKeys.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,14 @@ public static function loggerProvider(): ContextKeyInterface

return $instance ??= Context::createKey(LoggerProviderInterface::class);
}

/**
* @return ContextKeyInterface<ConfigurationResolverInterface>
*/
public static function configurationResolver(): ContextKeyInterface
{
static $instance;

return $instance ??= Context::createKey(ConfigurationResolverInterface::class);
}
}
33 changes: 33 additions & 0 deletions src/API/Instrumentation/NoopConfigurationResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Instrumentation;

class NoopConfigurationResolver implements ConfigurationResolverInterface
{
public function has(string $name): bool
{
return false;
}

public function getString(string $name): ?string
{
return null;
}

public function getBoolean(string $name): ?bool
{
return null;
}

public function getInt(string $name): ?int
{
return null;
}

public function getList(string $name): array
{
return [];
}
}
35 changes: 35 additions & 0 deletions src/SDK/Common/Configuration/ConfigurationResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Common\Configuration;

use OpenTelemetry\API\Instrumentation\ConfigurationResolverInterface;

class ConfigurationResolver implements ConfigurationResolverInterface
{
public function has(string $name): bool
{
return Configuration::has($name);
}

public function getString(string $name): ?string
{
return Configuration::getString($name);
}

public function getBoolean(string $name): ?bool
{
return Configuration::getBoolean($name);
}

public function getInt(string $name): ?int
{
return Configuration::getInt($name);
}

public function getList(string $name): array
{
return Configuration::getList($name);
}
}
5 changes: 4 additions & 1 deletion src/SDK/SdkAutoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use OpenTelemetry\API\Globals;
use OpenTelemetry\API\Instrumentation\Configurator;
use OpenTelemetry\SDK\Common\Configuration\Configuration;
use OpenTelemetry\SDK\Common\Configuration\ConfigurationResolver;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\Common\Util\ShutdownHandler;
use OpenTelemetry\SDK\Logs\LoggerProviderFactory;
Expand Down Expand Up @@ -58,7 +59,9 @@ public static function autoload(): bool
->withTracerProvider($tracerProvider)
->withMeterProvider($meterProvider)
->withLoggerProvider($loggerProvider)
->withPropagator($propagator);
->withPropagator($propagator)
->withConfigurationResolver(new ConfigurationResolver())
;
});

return true;
Expand Down
25 changes: 25 additions & 0 deletions tests/Unit/API/Instrumentation/InstrumentationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

use OpenTelemetry\API\Globals;
use OpenTelemetry\API\Instrumentation\CachedInstrumentation;
use OpenTelemetry\API\Instrumentation\ConfigurationResolverInterface;
use OpenTelemetry\API\Instrumentation\Configurator;
use OpenTelemetry\API\Instrumentation\NoopConfigurationResolver;
use OpenTelemetry\API\Logs\LoggerInterface;
use OpenTelemetry\API\Logs\LoggerProviderInterface;
use OpenTelemetry\API\Logs\NoopLoggerProvider;
Expand All @@ -30,12 +32,18 @@
*/
final class InstrumentationTest extends TestCase
{
public function tearDown(): void
{
Globals::reset();
}

public function test_globals_not_configured_returns_noop_instances(): void
{
$this->assertInstanceOf(NoopTracerProvider::class, Globals::tracerProvider());
$this->assertInstanceOf(NoopMeterProvider::class, Globals::meterProvider());
$this->assertInstanceOf(NoopTextMapPropagator::class, Globals::propagator());
$this->assertInstanceOf(NoopLoggerProvider::class, Globals::loggerProvider());
$this->assertInstanceOf(NoopConfigurationResolver::class, Globals::configurationResolver());
}

public function test_globals_returns_configured_instances(): void
Expand All @@ -44,19 +52,22 @@ public function test_globals_returns_configured_instances(): void
$meterProvider = $this->createMock(MeterProviderInterface::class);
$propagator = $this->createMock(TextMapPropagatorInterface::class);
$loggerProvider = $this->createMock(LoggerProviderInterface::class);
$configurationResolver = $this->createMock(ConfigurationResolverInterface::class);

$scope = Configurator::create()
->withTracerProvider($tracerProvider)
->withMeterProvider($meterProvider)
->withPropagator($propagator)
->withLoggerProvider($loggerProvider)
->withConfigurationResolver($configurationResolver)
->activate();

try {
$this->assertSame($tracerProvider, Globals::tracerProvider());
$this->assertSame($meterProvider, Globals::meterProvider());
$this->assertSame($propagator, Globals::propagator());
$this->assertSame($loggerProvider, Globals::loggerProvider());
$this->assertSame($configurationResolver, Globals::configurationResolver());
} finally {
$scope->detach();
}
Expand Down Expand Up @@ -100,4 +111,18 @@ public function test_instrumentation_returns_configured_instances(): void
$scope->detach();
}
}

public function test_initializers(): void
{
$called = false;
$closure = function (Configurator $configurator) use (&$called): Configurator {
$called = true;

return $configurator;
};
Globals::registerInitializer($closure);
$this->assertFalse($called);
Globals::propagator();
$this->assertTrue($called); //@phpstan-ignore-line
}
}
5 changes: 5 additions & 0 deletions tests/Unit/SDK/SdkAutoloaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use OpenTelemetry\API\Globals;
use OpenTelemetry\API\Instrumentation\NoopConfigurationResolver;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Logs\NoopLoggerProvider;
use OpenTelemetry\API\Metrics\Noop\NoopMeterProvider;
Expand Down Expand Up @@ -40,6 +41,8 @@ public function test_disabled_by_default(): void
$this->assertFalse(SdkAutoloader::autoload());
$this->assertInstanceOf(NoopMeterProvider::class, Globals::meterProvider());
$this->assertInstanceOf(NoopTracerProvider::class, Globals::tracerProvider());
$this->assertInstanceOf(NoopLoggerProvider::class, Globals::loggerProvider());
$this->assertInstanceOf(NoopConfigurationResolver::class, Globals::configurationResolver());
$this->assertInstanceOf(NoopTextMapPropagator::class, Globals::propagator(), 'propagator not initialized by disabled autoloader');
}

Expand All @@ -57,6 +60,7 @@ public function test_sdk_disabled_does_not_disable_propagator(): void
$this->assertNotInstanceOf(NoopTextMapPropagator::class, Globals::propagator());
$this->assertInstanceOf(NoopMeterProvider::class, Globals::meterProvider());
$this->assertInstanceOf(NoopTracerProvider::class, Globals::tracerProvider());
$this->assertInstanceOf(NoopConfigurationResolver::class, Globals::configurationResolver());
}

public function test_enabled_by_configuration(): void
Expand All @@ -67,5 +71,6 @@ public function test_enabled_by_configuration(): void
$this->assertNotInstanceOf(NoopMeterProvider::class, Globals::meterProvider());
$this->assertNotInstanceOf(NoopTracerProvider::class, Globals::tracerProvider());
$this->assertNotInstanceOf(NoopLoggerProvider::class, Globals::loggerProvider());
$this->assertNotInstanceOf(NoopConfigurationResolver::class, Globals::configurationResolver());
}
}

0 comments on commit 7b8daff

Please sign in to comment.