diff options
Diffstat (limited to 'vendor/open-telemetry/api/Instrumentation')
7 files changed, 595 insertions, 0 deletions
diff --git a/vendor/open-telemetry/api/Instrumentation/CachedInstrumentation.php b/vendor/open-telemetry/api/Instrumentation/CachedInstrumentation.php new file mode 100644 index 000000000..5ffb3950d --- /dev/null +++ b/vendor/open-telemetry/api/Instrumentation/CachedInstrumentation.php @@ -0,0 +1,97 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\API\Instrumentation; + +use ArrayAccess; +use function assert; +use function class_exists; +use OpenTelemetry\API\Globals; +use OpenTelemetry\API\Logs\LoggerInterface; +use OpenTelemetry\API\Logs\LoggerProviderInterface; +use OpenTelemetry\API\Metrics\MeterInterface; +use OpenTelemetry\API\Metrics\MeterProviderInterface; +use OpenTelemetry\API\Trace\TracerInterface; +use OpenTelemetry\API\Trace\TracerProviderInterface; +use const PHP_VERSION_ID; + +/** + * Provides access to cached {@link TracerInterface} and {@link MeterInterface} + * instances. + * + * Autoinstrumentation should prefer using a {@link CachedInstrumentation} + * instance over repeatedly obtaining instrumentation instances from + * {@link Globals}. + */ +final class CachedInstrumentation +{ + private string $name; + private ?string $version; + private ?string $schemaUrl; + private iterable $attributes; + /** @var ArrayAccess<TracerProviderInterface, TracerInterface>|null */ + private ?ArrayAccess $tracers; + /** @var ArrayAccess<MeterProviderInterface, MeterInterface>|null */ + private ?ArrayAccess $meters; + /** @var ArrayAccess<LoggerProviderInterface, LoggerInterface>|null */ + private ?ArrayAccess $loggers; + + public function __construct(string $name, ?string $version = null, ?string $schemaUrl = null, iterable $attributes = []) + { + $this->name = $name; + $this->version = $version; + $this->schemaUrl = $schemaUrl; + $this->attributes = $attributes; + $this->tracers = self::createWeakMap(); + $this->meters = self::createWeakMap(); + $this->loggers = self::createWeakMap(); + } + + private static function createWeakMap(): ?ArrayAccess + { + if (PHP_VERSION_ID < 80000) { + return null; + } + + /** @phan-suppress-next-line PhanUndeclaredClassReference */ + assert(class_exists(\WeakMap::class, false)); + /** @phan-suppress-next-line PhanUndeclaredClassMethod */ + $map = new \WeakMap(); + assert($map instanceof ArrayAccess); + + return $map; + } + + public function tracer(): TracerInterface + { + $tracerProvider = Globals::tracerProvider(); + + if ($this->tracers === null) { + return $tracerProvider->getTracer($this->name, $this->version, $this->schemaUrl, $this->attributes); + } + + return $this->tracers[$tracerProvider] ??= $tracerProvider->getTracer($this->name, $this->version, $this->schemaUrl, $this->attributes); + } + + public function meter(): MeterInterface + { + $meterProvider = Globals::meterProvider(); + + if ($this->meters === null) { + return $meterProvider->getMeter($this->name, $this->version, $this->schemaUrl, $this->attributes); + } + + return $this->meters[$meterProvider] ??= $meterProvider->getMeter($this->name, $this->version, $this->schemaUrl, $this->attributes); + } + public function logger(): LoggerInterface + { + $loggerProvider = Globals::loggerProvider(); + + if ($this->loggers === null) { + return $loggerProvider->getLogger($this->name, $this->version, $this->schemaUrl, $this->attributes); + } + + return $this->loggers[$loggerProvider] ??= $loggerProvider->getLogger($this->name, $this->version, $this->schemaUrl, $this->attributes); + } +} diff --git a/vendor/open-telemetry/api/Instrumentation/ConfigurationResolver.php b/vendor/open-telemetry/api/Instrumentation/ConfigurationResolver.php new file mode 100644 index 000000000..bb5619c30 --- /dev/null +++ b/vendor/open-telemetry/api/Instrumentation/ConfigurationResolver.php @@ -0,0 +1,77 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\API\Instrumentation; + +class ConfigurationResolver implements ConfigurationResolverInterface +{ + public function has(string $name): bool + { + return $this->getVariable($name) !== null; + } + + public function getString(string $name): ?string + { + return $this->getVariable($name); + } + + public function getBoolean(string $name): ?bool + { + $value = $this->getVariable($name); + if ($value === null) { + return null; + } + + return ($value === 'true'); + } + + public function getInt(string $name): ?int + { + $value = $this->getVariable($name); + if ($value === null) { + return null; + } + if (filter_var($value, FILTER_VALIDATE_INT) === false) { + //log warning + return null; + } + + return (int) $value; + } + + public function getList(string $name): array + { + $value = $this->getVariable($name); + if ($value === null) { + return []; + } + + return explode(',', $value); + } + + private function getVariable(string $name): ?string + { + $value = $_SERVER[$name] ?? null; + if ($value !== false && !self::isEmpty($value)) { + assert(is_string($value)); + + return $value; + } + $value = getenv($name); + if ($value !== false && !self::isEmpty($value)) { + return $value; + } + $value = ini_get($name); + if ($value !== false && !self::isEmpty($value)) { + return $value; + } + + return null; + } + + private static function isEmpty($value): bool + { + return $value === false || $value === null || $value === ''; + } +} diff --git a/vendor/open-telemetry/api/Instrumentation/ConfigurationResolverInterface.php b/vendor/open-telemetry/api/Instrumentation/ConfigurationResolverInterface.php new file mode 100644 index 000000000..79bd94047 --- /dev/null +++ b/vendor/open-telemetry/api/Instrumentation/ConfigurationResolverInterface.php @@ -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; +} diff --git a/vendor/open-telemetry/api/Instrumentation/Configurator.php b/vendor/open-telemetry/api/Instrumentation/Configurator.php new file mode 100644 index 000000000..71d301363 --- /dev/null +++ b/vendor/open-telemetry/api/Instrumentation/Configurator.php @@ -0,0 +1,113 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\API\Instrumentation; + +use OpenTelemetry\API\Logs\LoggerProviderInterface; +use OpenTelemetry\API\Logs\NoopLoggerProvider; +use OpenTelemetry\API\Metrics\MeterProviderInterface; +use OpenTelemetry\API\Metrics\Noop\NoopMeterProvider; +use OpenTelemetry\API\Trace\NoopTracerProvider; +use OpenTelemetry\API\Trace\TracerProviderInterface; +use OpenTelemetry\Context\Context; +use OpenTelemetry\Context\ContextInterface; +use OpenTelemetry\Context\ImplicitContextKeyedInterface; +use OpenTelemetry\Context\Propagation\NoopTextMapPropagator; +use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; +use OpenTelemetry\Context\ScopeInterface; + +/** + * Configures the global (context scoped) instrumentation instances. + * + * @see Configurator::activate() + */ +final class Configurator implements ImplicitContextKeyedInterface +{ + private ?TracerProviderInterface $tracerProvider = null; + private ?MeterProviderInterface $meterProvider = null; + private ?TextMapPropagatorInterface $propagator = null; + private ?LoggerProviderInterface $loggerProvider = null; + + private function __construct() + { + } + + /** + * Creates a configurator that uses parent instances for not configured values. + */ + public static function create(): Configurator + { + return new self(); + } + + /** + * Creates a configurator that uses noop instances for not configured values. + */ + public static function createNoop(): Configurator + { + return self::create() + ->withTracerProvider(new NoopTracerProvider()) + ->withMeterProvider(new NoopMeterProvider()) + ->withPropagator(new NoopTextMapPropagator()) + ->withLoggerProvider(new NoopLoggerProvider()) + ; + } + + public function activate(): ScopeInterface + { + return $this->storeInContext()->activate(); + } + + public function storeInContext(?ContextInterface $context = null): ContextInterface + { + $context ??= Context::getCurrent(); + + if ($this->tracerProvider !== null) { + $context = $context->with(ContextKeys::tracerProvider(), $this->tracerProvider); + } + if ($this->meterProvider !== null) { + $context = $context->with(ContextKeys::meterProvider(), $this->meterProvider); + } + if ($this->propagator !== null) { + $context = $context->with(ContextKeys::propagator(), $this->propagator); + } + if ($this->loggerProvider !== null) { + $context = $context->with(ContextKeys::loggerProvider(), $this->loggerProvider); + } + + return $context; + } + + public function withTracerProvider(?TracerProviderInterface $tracerProvider): Configurator + { + $self = clone $this; + $self->tracerProvider = $tracerProvider; + + return $self; + } + + public function withMeterProvider(?MeterProviderInterface $meterProvider): Configurator + { + $self = clone $this; + $self->meterProvider = $meterProvider; + + return $self; + } + + public function withPropagator(?TextMapPropagatorInterface $propagator): Configurator + { + $self = clone $this; + $self->propagator = $propagator; + + return $self; + } + + public function withLoggerProvider(?LoggerProviderInterface $loggerProvider): Configurator + { + $self = clone $this; + $self->loggerProvider = $loggerProvider; + + return $self; + } +} diff --git a/vendor/open-telemetry/api/Instrumentation/ContextKeys.php b/vendor/open-telemetry/api/Instrumentation/ContextKeys.php new file mode 100644 index 000000000..ea1a66416 --- /dev/null +++ b/vendor/open-telemetry/api/Instrumentation/ContextKeys.php @@ -0,0 +1,58 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\API\Instrumentation; + +use OpenTelemetry\API\Logs\LoggerProviderInterface; +use OpenTelemetry\API\Metrics\MeterProviderInterface; +use OpenTelemetry\API\Trace\TracerProviderInterface; +use OpenTelemetry\Context\Context; +use OpenTelemetry\Context\ContextKeyInterface; +use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; + +/** + * @internal + */ +final class ContextKeys +{ + /** + * @return ContextKeyInterface<TracerProviderInterface> + */ + public static function tracerProvider(): ContextKeyInterface + { + static $instance; + + return $instance ??= Context::createKey(TracerProviderInterface::class); + } + + /** + * @return ContextKeyInterface<MeterProviderInterface> + */ + public static function meterProvider(): ContextKeyInterface + { + static $instance; + + return $instance ??= Context::createKey(MeterProviderInterface::class); + } + + /** + * @return ContextKeyInterface<TextMapPropagatorInterface> + */ + public static function propagator(): ContextKeyInterface + { + static $instance; + + return $instance ??= Context::createKey(TextMapPropagatorInterface::class); + } + + /** + * @return ContextKeyInterface<LoggerProviderInterface> + */ + public static function loggerProvider(): ContextKeyInterface + { + static $instance; + + return $instance ??= Context::createKey(LoggerProviderInterface::class); + } +} diff --git a/vendor/open-telemetry/api/Instrumentation/InstrumentationInterface.php b/vendor/open-telemetry/api/Instrumentation/InstrumentationInterface.php new file mode 100644 index 000000000..d67bc8d6d --- /dev/null +++ b/vendor/open-telemetry/api/Instrumentation/InstrumentationInterface.php @@ -0,0 +1,43 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\API\Instrumentation; + +use OpenTelemetry\API\Metrics\MeterInterface; +use OpenTelemetry\API\Metrics\MeterProviderInterface; +use OpenTelemetry\API\Trace\TracerInterface; +use OpenTelemetry\API\Trace\TracerProviderInterface; +use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; +use Psr\Log\LoggerInterface; + +interface InstrumentationInterface +{ + public function getName(): string; + + public function getVersion(): ?string; + + public function getSchemaUrl(): ?string; + + public function init(): bool; + + public function activate(): bool; + + public function setPropagator(TextMapPropagatorInterface $propagator): void; + + public function getPropagator(): TextMapPropagatorInterface; + + public function setTracerProvider(TracerProviderInterface $tracerProvider): void; + + public function getTracerProvider(): TracerProviderInterface; + + public function getTracer(): TracerInterface; + + public function setMeterProvider(MeterProviderInterface $meterProvider): void; + + public function getMeter(): MeterInterface; + + public function setLogger(LoggerInterface $logger): void; + + public function getLogger(): LoggerInterface; +} diff --git a/vendor/open-telemetry/api/Instrumentation/InstrumentationTrait.php b/vendor/open-telemetry/api/Instrumentation/InstrumentationTrait.php new file mode 100644 index 000000000..1e695adb5 --- /dev/null +++ b/vendor/open-telemetry/api/Instrumentation/InstrumentationTrait.php @@ -0,0 +1,193 @@ +<?php + +declare(strict_types=1); + +namespace OpenTelemetry\API\Instrumentation; + +use OpenTelemetry\API\Metrics\MeterInterface; +use OpenTelemetry\API\Metrics\MeterProviderInterface; +use OpenTelemetry\API\Metrics\Noop\NoopMeter; +use OpenTelemetry\API\Trace\NoopTracer; +use OpenTelemetry\API\Trace\NoopTracerProvider; +use OpenTelemetry\API\Trace\TracerInterface; +use OpenTelemetry\API\Trace\TracerProviderInterface; +use OpenTelemetry\Context\Propagation\NoopTextMapPropagator; +use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; +use RuntimeException; + +/** + This trait in conjunction with the InstrumentationInterface is meant as a base for instrumentations for the + OpenTelemetry API. + Instrumentations need to implement the abstract methods of this trait (besides any instrumentation specific code) + + A very simplified instrumentation could look like this: + +class Instrumentation implements InstrumentationInterface +{ + use InstrumentationTrait; + + public function getName(): string + { + return 'foo-instrumentation'; + } + + public function getVersion(): ?string + { + return '0.0.1'; + } + + public function getSchemaUrl(): ?string + { + return null; + } + + public function init(): bool + { + // This is just an example. In a real-world scenario one should only create spans in reaction of things + // happening in the instrumented code, not just for the sake of it. + $span = $this->getTracer()->spanBuilder($this->getName())->startSpan(); + // do stuff + $span->end(); + } +} + +An user of the instrumentation and API/SDK would the call: + +$instrumentation = new Instrumentation; +$instrumentation->activate() + +to activate and use the instrumentation with the API/SDK. + **/ + +trait InstrumentationTrait +{ + private TextMapPropagatorInterface $propagator; + private TracerProviderInterface $tracerProvider; + private TracerInterface $tracer; + private MeterInterface $meter; + private LoggerInterface $logger; + + public function __construct() + { + $this->initDefaults(); + } + + /** + * The name of the instrumenting/instrumented library/package/project. + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/glossary.md#instrumentation-scope + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/glossary.md#instrumentation-library + */ + abstract public function getName(): string; + + /** + * The version of the instrumenting/instrumented library/package/project. + * If unknown or a lookup is too expensive simply return NULL. + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/glossary.md#instrumentation-scope + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/glossary.md#instrumentation-library + */ + abstract public function getVersion(): ?string; + + /** + * The version of the instrumenting/instrumented library/package/project. + * If unknown simply return NULL. + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/glossary.md#instrumentation-scope + * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/glossary.md#instrumentation-library + */ + abstract public function getSchemaUrl(): ?string; + + /** + * This method will be called from the API when the instrumentation has been activated (via activate()). + * Here you can put any bootstrapping code needed by the instrumentation. + * If not needed simply implement a method which returns TRUE. + */ + abstract public function init(): bool; + + /** + * This method registers and activates the instrumentation with the OpenTelemetry API/SDK and thus + * the instrumentation will be used to generate telemetry data. + */ + public function activate(): bool + { + $this->validateImplementation(); + // activate instrumentation with the API. not implemented yet. + return true; + } + + public function setPropagator(TextMapPropagatorInterface $propagator): void + { + $this->propagator = $propagator; + } + + public function getPropagator(): TextMapPropagatorInterface + { + return $this->propagator; + } + + public function setTracerProvider(TracerProviderInterface $tracerProvider): void + { + $this->tracerProvider = $tracerProvider; + // @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/trace/api.md#get-a-tracer + $this->tracer = $tracerProvider->getTracer( + $this->getName(), + $this->getVersion(), + $this->getSchemaUrl(), + ); + } + + public function getTracerProvider(): TracerProviderInterface + { + return $this->tracerProvider; + } + + public function getTracer(): TracerInterface + { + return $this->tracer; + } + + public function setMeterProvider(MeterProviderInterface $meterProvider): void + { + // @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/metrics/api.md#get-a-meter + $this->meter = $meterProvider->getMeter( + $this->getName(), + $this->getVersion(), + ); + } + + public function getMeter(): MeterInterface + { + return $this->meter; + } + + public function setLogger(LoggerInterface $logger): void + { + $this->logger = $logger; + } + + public function getLogger(): LoggerInterface + { + return $this->logger; + } + + private function validateImplementation(): void + { + if (!$this instanceof InstrumentationInterface) { + throw new RuntimeException(sprintf( + '"%s" is meant to implement "%s"', + InstrumentationTrait::class, + InstrumentationInterface::class + )); + } + } + + private function initDefaults(): void + { + $this->propagator = new NoopTextMapPropagator(); + $this->tracer = new NoopTracer(); + $this->tracerProvider = new NoopTracerProvider(); + /** @phan-suppress-next-line PhanAccessMethodInternal */ + $this->meter = new NoopMeter(); + $this->logger = new NullLogger(); + } +} |