Skip to content

Commit

Permalink
implement scope configuration (#1353)
Browse files Browse the repository at this point in the history
  • Loading branch information
brettmc committed Aug 18, 2024
1 parent 382331e commit 41dd113
Show file tree
Hide file tree
Showing 67 changed files with 1,267 additions and 123 deletions.
1 change: 1 addition & 0 deletions .phan/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
'PhanAccessClassInternal',
'PhanAccessMethodInternal',
'PhanAccessPropertyInternal',
'PhanTypeMismatchPropertyReal',
'PhanTemplateTypeNotUsedInFunctionReturn',
],

Expand Down
12 changes: 12 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,15 @@ parameters:
message: "#Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface::.*#"
paths:
- src/Config/SDK
-
message: "#Cannot call method .* on null#"
paths:
- tests/Integration/SDK/Trace
-
message: "#Property .*Logger.*config .* does not accept .*Config?#"
paths:
- src/SDK/Logs
-
message: "#.*return with type T is not subtype.*#"
paths:
- src/SDK/Common/InstrumentationScope
2 changes: 1 addition & 1 deletion src/API/Logs/LateBindingLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function emit(LogRecord $logRecord): void
($this->logger ??= ($this->factory)())->emit($logRecord);
}

public function enabled(): bool
public function isEnabled(): bool
{
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Logs/LoggerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ public function emit(LogRecord $logRecord): void;
* are about to generate a LogRecord, to avoid performing computationally expensive work.
* @experimental
*/
public function enabled(): bool;
public function isEnabled(): bool;
}
2 changes: 1 addition & 1 deletion src/API/Logs/NoopLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function log($level, $message, array $context = []): void
{
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Metrics/GaugeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* @experimental
*/
interface GaugeInterface
interface GaugeInterface extends SynchronousInstrument
{

/**
Expand Down
7 changes: 6 additions & 1 deletion src/API/Metrics/Instrument.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ interface Instrument
{
/**
* Determine if the instrument is enabled. Instrumentation authors SHOULD call this API each time they record a measurement.
*
* MUST return false if:
* - The MeterConfig of the Meter used to create the instrument has parameter disabled=true
* - All resolved views for the instrument are configured with the Drop Aggregation
* @experimental
* @see https://opentelemetry.io/docs/specs/otel/metrics/sdk/#instrument-enabled
*/
public function enabled(): bool;
public function isEnabled(): bool;
}
5 changes: 5 additions & 0 deletions src/API/Metrics/LateBindingMeter.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,9 @@ public function createObservableUpDownCounter(string $name, ?string $unit = null
{
return ($this->meter ??= ($this->factory)())->createObservableUpDownCounter($name, $unit, $description, $advisory, $callbacks);
}

public function isEnabled(): bool
{
return true;
}
}
2 changes: 2 additions & 0 deletions src/API/Metrics/MeterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,6 @@ public function createObservableUpDownCounter(
array|callable $advisory = [],
callable ...$callbacks,
): ObservableUpDownCounterInterface;

public function isEnabled(): bool;
}
2 changes: 1 addition & 1 deletion src/API/Metrics/Noop/NoopCounter.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function add($amount, iterable $attributes = [], $context = null): void
// no-op
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
5 changes: 5 additions & 0 deletions src/API/Metrics/Noop/NoopGauge.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ public function record(float|int $amount, iterable $attributes = [], $context =
{
// no-op
}

public function isEnabled(): bool
{
return false;
}
}
2 changes: 1 addition & 1 deletion src/API/Metrics/Noop/NoopHistogram.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function record($amount, iterable $attributes = [], $context = null): voi
// no-op
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
5 changes: 5 additions & 0 deletions src/API/Metrics/Noop/NoopMeter.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,9 @@ public function createObservableUpDownCounter(string $name, ?string $unit = null
{
return new NoopObservableUpDownCounter();
}

public function isEnabled(): bool
{
return false;
}
}
2 changes: 1 addition & 1 deletion src/API/Metrics/Noop/NoopObservableCounter.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function observe(callable $callback, bool $weaken = false): ObservableCal
return new NoopObservableCallback();
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Metrics/Noop/NoopObservableGauge.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function observe(callable $callback, bool $weaken = false): ObservableCal
return new NoopObservableCallback();
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Metrics/Noop/NoopObservableUpDownCounter.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function observe(callable $callback, bool $weaken = false): ObservableCal
return new NoopObservableCallback();
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Metrics/Noop/NoopUpDownCounter.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function add($amount, iterable $attributes = [], $context = null): void
// no-op
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Trace/LateBindingTracer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function spanBuilder(string $spanName): SpanBuilderInterface
return ($this->tracer ??= ($this->factory)())->spanBuilder($spanName);
}

public function enabled(): bool
public function isEnabled(): bool
{
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Trace/NoopTracer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function spanBuilder(string $spanName): SpanBuilderInterface
return new NoopSpanBuilder(Context::storage());
}

public function enabled(): bool
public function isEnabled(): bool
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/API/Trace/TracerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ public function spanBuilder(string $spanName): SpanBuilderInterface;
* creating a new span.
* @experimental
*/
public function enabled(): bool;
public function isEnabled(): bool;
}
14 changes: 14 additions & 0 deletions src/SDK/Common/InstrumentationScope/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Common\InstrumentationScope;

/**
* @internal
*/
interface Config
{
public function setDisabled(bool $disabled): void;
public function isEnabled(): bool;
}
20 changes: 20 additions & 0 deletions src/SDK/Common/InstrumentationScope/ConfigTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Common\InstrumentationScope;

trait ConfigTrait
{
private bool $disabled = false;

public function setDisabled(bool $disabled): void
{
$this->disabled = $disabled;
}

public function isEnabled(): bool
{
return $this->disabled === false;
}
}
10 changes: 10 additions & 0 deletions src/SDK/Common/InstrumentationScope/Configurable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Common\InstrumentationScope;

interface Configurable
{
public function updateConfigurator(Configurator $configurator): void;
}
104 changes: 104 additions & 0 deletions src/SDK/Common/InstrumentationScope/Configurator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Common\InstrumentationScope;

use Closure;
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
use OpenTelemetry\SDK\Logs\LoggerConfig;
use OpenTelemetry\SDK\Metrics\MeterConfig;
use OpenTelemetry\SDK\Trace\TracerConfig;
use WeakMap;

/**
* @template T
*/
final class Configurator
{
/** @var Closure(InstrumentationScopeInterface): T */
private readonly Closure $factory;
/** @var WeakMap<InstrumentationScopeInterface, T> */
private WeakMap $configs;
/** @var list<ConfiguratorClosure> */
private array $configurators = [];

/**
* @param Closure(InstrumentationScopeInterface): T $factory
* @psalm-suppress PropertyTypeCoercion
*/
public function __construct(Closure $factory)
{
$this->configs = new WeakMap();
$this->factory = $factory;
}

/**
* @param Closure(T, InstrumentationScopeInterface): void $closure
*/
public function with(Closure $closure, ?string $name, ?string $version = null, ?string $schemaUrl = null): self
{
$this->configurators[] = $configurator = new ConfiguratorClosure($closure, self::namePattern($name), $version, $schemaUrl);

foreach ($this->configs as $instrumentationScope => $config) {
if ($configurator->matches($instrumentationScope)) {
($configurator->closure)($config, $instrumentationScope);
}
}

return $this;
}

/**
* @return T
*/
public function resolve(InstrumentationScopeInterface $instrumentationScope): Config
{
if ($config = $this->configs[$instrumentationScope] ?? null) {
return $config;
}

$config = ($this->factory)($instrumentationScope);
foreach ($this->configurators as $configurator) {
if ($configurator->matches($instrumentationScope)) {
($configurator->closure)($config, $instrumentationScope);
}
}

return $this->configs[$instrumentationScope] ??= $config;
}

/**
* Create a default Configurator for a LoggerConfig
* @return Configurator<LoggerConfig>
*/
public static function logger(): self
{
return (new Configurator(static fn () => new LoggerConfig()));
}

/**
* Create a default Configurator for a MeterConfig
* @return Configurator<MeterConfig>
*/
public static function meter(): self
{
return (new Configurator(static fn () => new MeterConfig()));
}

/**
* Create a default Configurator for a TracerConfig
* @return Configurator<TracerConfig>
*/
public static function tracer(): self
{
return (new Configurator(static fn () => new TracerConfig()));
}

private static function namePattern(?string $name): ?string
{
return $name !== null
? sprintf('/^%s$/', strtr(preg_quote($name, '/'), ['\\?' => '.', '\\*' => '.*']))
: null;
}
}
33 changes: 33 additions & 0 deletions src/SDK/Common/InstrumentationScope/ConfiguratorClosure.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Common\InstrumentationScope;

use Closure;
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;

/**
* @internal
*/
final class ConfiguratorClosure
{

public function __construct(
public readonly Closure $closure,
private readonly ?string $name,
private readonly ?string $version,
private readonly ?string $schemaUrl,
) {
}

/**
* @psalm-suppress ArgumentTypeCoercion
*/
public function matches(InstrumentationScopeInterface $instrumentationScope): bool
{
return ($this->name === null || preg_match($this->name, $instrumentationScope->getName()))
&& ($this->version === null || $this->version === $instrumentationScope->getVersion())
&& ($this->schemaUrl === null || $this->schemaUrl === $instrumentationScope->getSchemaUrl());
}
}
Loading

0 comments on commit 41dd113

Please sign in to comment.