diff --git a/composer.json b/composer.json index e127ff8fc..1bd398734 100644 --- a/composer.json +++ b/composer.json @@ -155,7 +155,13 @@ "OpenTelemetry\\Config\\SDK\\ComponentProvider\\Instrumentation\\General\\HttpConfigProvider", "OpenTelemetry\\Config\\SDK\\ComponentProvider\\Instrumentation\\General\\PeerConfigProvider", - "OpenTelemetry\\Example\\ExampleConfigProvider" + "OpenTelemetry\\Example\\ExampleConfigProvider", + + "OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Metrics\\AggregationResolverExplicitBucketHistogram", + "OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Metrics\\MetricExporterPrometheus", + "OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Metrics\\MetricReaderPull", + "OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Propagator\\TextMapPropagatorXray", + "OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Propagator\\TextMapPropagatorOtTrace" ], "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" diff --git a/examples/instrumentation/otel-sdk.yaml b/examples/instrumentation/otel-sdk.yaml index 53ce87914..70a188a75 100644 --- a/examples/instrumentation/otel-sdk.yaml +++ b/examples/instrumentation/otel-sdk.yaml @@ -1,12 +1,18 @@ file_format: '0.3' +propagator: + composite: [] + tracer_provider: processors: - simple: exporter: - console: {} + console: + sampler: + always_on: instrumentation: + general: php: example_instrumentation: span_name: ${EXAMPLE_INSTRUMENTATION_SPAN_NAME:-example span} diff --git a/examples/load_config.yaml b/examples/load_config.yaml index 0535a6dbb..528780799 100644 --- a/examples/load_config.yaml +++ b/examples/load_config.yaml @@ -18,11 +18,11 @@ tracer_provider: sampler: parent_based: root: - always_on: {} + always_on: processors: - simple: exporter: - console: {} + console: - batch: exporter: otlp: *otlp-exporter @@ -30,7 +30,7 @@ meter_provider: readers: - periodic: exporter: - console: {} + console: - periodic: exporter: otlp: @@ -40,7 +40,7 @@ logger_provider: processors: - simple: exporter: - console: {} + console: - batch: exporter: otlp: *otlp-exporter diff --git a/examples/src/ExampleConfigProvider.php b/examples/src/ExampleConfigProvider.php index eba88950a..8b326773a 100644 --- a/examples/src/ExampleConfigProvider.php +++ b/examples/src/ExampleConfigProvider.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Config\SDK\Configuration\Validation; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -35,16 +36,16 @@ public function createPlugin(array $properties, Context $context): Instrumentati /** * @psalm-suppress UndefinedInterfaceMethod,PossiblyNullReference */ - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $root = new ArrayNodeDefinition('example_instrumentation'); - $root + $node = $builder->arrayNode('example_instrumentation'); + $node ->children() ->scalarNode('span_name')->isRequired()->validate()->always(Validation::ensureString())->end()->end() ->end() ->canBeDisabled() ; - return $root; + return $node; } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 569545a4d..807247557 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -38,6 +38,7 @@ parameters: message: "#Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface::.*#" paths: - src/Config/SDK + - tests/Integration/Config - message: "#Cannot call method .* on null#" paths: diff --git a/psalm.xml.dist b/psalm.xml.dist index ed0d7ffc9..acec7254d 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -40,8 +40,14 @@ + + + + + + @@ -50,6 +56,7 @@ + diff --git a/src/Config/SDK/ComponentProvider/Instrumentation/General/HttpConfigProvider.php b/src/Config/SDK/ComponentProvider/Instrumentation/General/HttpConfigProvider.php index 01c86f73c..7809e77f4 100644 --- a/src/Config/SDK/ComponentProvider/Instrumentation/General/HttpConfigProvider.php +++ b/src/Config/SDK/ComponentProvider/Instrumentation/General/HttpConfigProvider.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -22,22 +23,22 @@ public function createPlugin(array $properties, Context $context): GeneralInstru return new HttpConfig($properties); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('http'); + $node = $builder->arrayNode('http'); $node ->children() - ->append($this->capturedHeaders('client')) - ->append($this->capturedHeaders('server')) + ->append($this->capturedHeaders('client', $builder)) + ->append($this->capturedHeaders('server', $builder)) ->end() ; return $node; } - private function capturedHeaders(string $name): ArrayNodeDefinition + private function capturedHeaders(string $name, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition($name); + $node = $builder->arrayNode($name); $node ->children() ->arrayNode('request_captured_headers') diff --git a/src/Config/SDK/ComponentProvider/Instrumentation/General/PeerConfigProvider.php b/src/Config/SDK/ComponentProvider/Instrumentation/General/PeerConfigProvider.php index f9273a422..fc08b1a4e 100644 --- a/src/Config/SDK/ComponentProvider/Instrumentation/General/PeerConfigProvider.php +++ b/src/Config/SDK/ComponentProvider/Instrumentation/General/PeerConfigProvider.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -21,9 +22,9 @@ public function createPlugin(array $properties, Context $context): GeneralInstru return new PeerConfig($properties); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('peer'); + $node = $builder->arrayNode('peer'); $node ->children() ->arrayNode('service_mapping') diff --git a/src/Config/SDK/ComponentProvider/InstrumentationConfigurationRegistry.php b/src/Config/SDK/ComponentProvider/InstrumentationConfigurationRegistry.php index 44f4ae4c7..a156bebec 100644 --- a/src/Config/SDK/ComponentProvider/InstrumentationConfigurationRegistry.php +++ b/src/Config/SDK/ComponentProvider/InstrumentationConfigurationRegistry.php @@ -12,6 +12,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @internal @@ -24,7 +25,7 @@ class InstrumentationConfigurationRegistry implements ComponentProvider * @param array{ * instrumentation: array{ * php: list>, - * general: list> + * general: list> * } * } $properties */ @@ -43,18 +44,16 @@ public function createPlugin(array $properties, Context $context): Configuration return $configurationRegistry; } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $root = new ArrayNodeDefinition('open_telemetry'); + $root = $builder->arrayNode('open_telemetry'); $root ->ignoreExtraKeys() ->children() ->arrayNode('instrumentation') ->ignoreExtraKeys() - ->children() - ->append($registry->componentList('php', InstrumentationConfiguration::class)) - ->append($registry->componentList('general', GeneralInstrumentationConfiguration::class)) - ->end() + ->append($registry->componentMap('php', InstrumentationConfiguration::class)) + ->append($registry->componentMap('general', GeneralInstrumentationConfiguration::class)) ->end() ->end() ; diff --git a/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterConsole.php b/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterConsole.php index aab88c355..a5b29b03c 100644 --- a/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterConsole.php +++ b/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterConsole.php @@ -11,6 +11,7 @@ use OpenTelemetry\SDK\Logs\LogRecordExporterInterface; use OpenTelemetry\SDK\Registry; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -29,8 +30,8 @@ public function createPlugin(array $properties, Context $context): LogRecordExpo )); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('console'); + return $builder->arrayNode('console'); } } diff --git a/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterOtlp.php b/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterOtlp.php index 4a829797b..d966c60c3 100644 --- a/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterOtlp.php +++ b/src/Config/SDK/ComponentProvider/Logs/LogRecordExporterOtlp.php @@ -17,6 +17,7 @@ use OpenTelemetry\SDK\Logs\LogRecordExporterInterface; use OpenTelemetry\SDK\Registry; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -36,6 +37,7 @@ final class LogRecordExporterOtlp implements ComponentProvider * headers_list: ?string, * compression: 'gzip'|null, * timeout: int<0, max>, + * insecure: ?bool, * } $properties */ public function createPlugin(array $properties, Context $context): LogRecordExporterInterface @@ -56,9 +58,9 @@ public function createPlugin(array $properties, Context $context): LogRecordExpo )); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('otlp'); + $node = $builder->arrayNode('otlp'); $node ->children() ->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc'])->end() @@ -77,6 +79,7 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit ->scalarNode('headers_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->enumNode('compression')->values(['gzip'])->defaultNull()->end() ->integerNode('timeout')->min(0)->defaultValue(10)->end() + ->booleanNode('insecure')->defaultNull()->end() ->end() ; diff --git a/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorBatch.php b/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorBatch.php index 780018284..7a458fc19 100644 --- a/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorBatch.php +++ b/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorBatch.php @@ -13,6 +13,7 @@ use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface; use OpenTelemetry\SDK\Logs\Processor\BatchLogRecordProcessor; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -42,9 +43,9 @@ public function createPlugin(array $properties, Context $context): LogRecordProc ); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('batch'); + $node = $builder->arrayNode('batch'); $node ->children() ->integerNode('schedule_delay')->min(0)->defaultValue(5000)->end() diff --git a/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorSimple.php b/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorSimple.php index 1e797a8d2..d4a839a20 100644 --- a/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorSimple.php +++ b/src/Config/SDK/ComponentProvider/Logs/LogRecordProcessorSimple.php @@ -12,6 +12,7 @@ use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface; use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -31,9 +32,9 @@ public function createPlugin(array $properties, Context $context): LogRecordProc ); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('simple'); + $node = $builder->arrayNode('simple'); $node ->children() ->append($registry->component('exporter', LogRecordExporterInterface::class)->isRequired()) diff --git a/src/Config/SDK/ComponentProvider/Metrics/AggregationResolverDefault.php b/src/Config/SDK/ComponentProvider/Metrics/AggregationResolverDefault.php index 98ae99827..acf94e6a6 100644 --- a/src/Config/SDK/ComponentProvider/Metrics/AggregationResolverDefault.php +++ b/src/Config/SDK/ComponentProvider/Metrics/AggregationResolverDefault.php @@ -10,6 +10,7 @@ use OpenTelemetry\SDK\Metrics\DefaultAggregationProviderInterface; use OpenTelemetry\SDK\Metrics\DefaultAggregationProviderTrait; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -28,8 +29,8 @@ public function createPlugin(array $properties, Context $context): DefaultAggreg }; } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('default'); + return $builder->arrayNode('default'); } } diff --git a/src/Config/SDK/ComponentProvider/Metrics/MetricExporterConsole.php b/src/Config/SDK/ComponentProvider/Metrics/MetricExporterConsole.php index 8d3f64ced..e09120134 100644 --- a/src/Config/SDK/ComponentProvider/Metrics/MetricExporterConsole.php +++ b/src/Config/SDK/ComponentProvider/Metrics/MetricExporterConsole.php @@ -10,6 +10,7 @@ use OpenTelemetry\SDK\Metrics\MetricExporter\ConsoleMetricExporter; use OpenTelemetry\SDK\Metrics\MetricExporterInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -25,8 +26,8 @@ public function createPlugin(array $properties, Context $context): MetricExporte return new ConsoleMetricExporter(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('console'); + return $builder->arrayNode('console'); } } diff --git a/src/Config/SDK/ComponentProvider/Metrics/MetricExporterOtlp.php b/src/Config/SDK/ComponentProvider/Metrics/MetricExporterOtlp.php index 6e566304e..595cb8a4c 100644 --- a/src/Config/SDK/ComponentProvider/Metrics/MetricExporterOtlp.php +++ b/src/Config/SDK/ComponentProvider/Metrics/MetricExporterOtlp.php @@ -18,6 +18,7 @@ use OpenTelemetry\SDK\Metrics\MetricExporterInterface; use OpenTelemetry\SDK\Registry; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -37,8 +38,9 @@ final class MetricExporterOtlp implements ComponentProvider * headers_list: ?string, * compression: 'gzip'|null, * timeout: int<0, max>, + * insecure: ?bool, * temporality_preference: 'cumulative'|'delta'|'lowmemory', - * default_histogram_aggregation: 'explicit_bucket_histogram', + * default_histogram_aggregation: 'explicit_bucket_histogram|base2_exponential_bucket_histogram', * } $properties */ public function createPlugin(array $properties, Context $context): MetricExporterInterface @@ -65,9 +67,9 @@ public function createPlugin(array $properties, Context $context): MetricExporte ), $temporality); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('otlp'); + $node = $builder->arrayNode('otlp'); $node ->children() ->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc'])->end() @@ -86,12 +88,13 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit ->scalarNode('headers_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->enumNode('compression')->values(['gzip'])->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->integerNode('timeout')->min(0)->defaultValue(10)->end() + ->booleanNode('insecure')->defaultNull()->end() ->enumNode('temporality_preference') ->values(['cumulative', 'delta', 'lowmemory']) ->defaultValue('cumulative') ->end() ->enumNode('default_histogram_aggregation') - ->values(['explicit_bucket_histogram']) + ->values(['explicit_bucket_histogram', 'base2_exponential_bucket_histogram']) ->defaultValue('explicit_bucket_histogram') ->end() ->end() diff --git a/src/Config/SDK/ComponentProvider/Metrics/MetricReaderPeriodic.php b/src/Config/SDK/ComponentProvider/Metrics/MetricReaderPeriodic.php index ab865c7af..b61bf1158 100644 --- a/src/Config/SDK/ComponentProvider/Metrics/MetricReaderPeriodic.php +++ b/src/Config/SDK/ComponentProvider/Metrics/MetricReaderPeriodic.php @@ -12,6 +12,7 @@ use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader; use OpenTelemetry\SDK\Metrics\MetricReaderInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -24,6 +25,7 @@ final class MetricReaderPeriodic implements ComponentProvider * interval: int<0, max>, * timeout: int<0, max>, * exporter: ComponentPlugin, + * producers: array, * } $properties */ public function createPlugin(array $properties, Context $context): MetricReaderInterface @@ -33,14 +35,16 @@ public function createPlugin(array $properties, Context $context): MetricReaderI ); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('periodic'); + $node = $builder->arrayNode('periodic'); $node ->children() ->integerNode('interval')->min(0)->defaultValue(5000)->end() ->integerNode('timeout')->min(0)->defaultValue(30000)->end() ->append($registry->component('exporter', MetricExporterInterface::class)->isRequired()) + ->arrayNode('producers') //@todo + ->variablePrototype()->end() ->end() ; diff --git a/src/Config/SDK/ComponentProvider/OpenTelemetrySdk.php b/src/Config/SDK/ComponentProvider/OpenTelemetrySdk.php index cae7ec901..19b04655e 100644 --- a/src/Config/SDK/ComponentProvider/OpenTelemetrySdk.php +++ b/src/Config/SDK/ComponentProvider/OpenTelemetrySdk.php @@ -42,6 +42,7 @@ use OpenTelemetry\SDK\Trace\SpanProcessorInterface; use OpenTelemetry\SDK\Trace\TracerProvider; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @internal @@ -58,6 +59,7 @@ final class OpenTelemetrySdk implements ComponentProvider * resource: array{ * attributes: array, * attributes_list: ?string, + * detectors: array, * schema_url: ?string, * }, * attribute_limits: array{ @@ -82,7 +84,10 @@ final class OpenTelemetrySdk implements ComponentProvider * stream: array{ * name: ?string, * description: ?string, - * attribute_keys: list, + * attribute_keys: array{ + * included: list, + * excluded: list, + * }, * aggregation: ?ComponentPlugin, * }, * selector: array{ @@ -204,8 +209,9 @@ public function createPlugin(array $properties, Context $context): SdkBuilder if (isset($view['stream']['description'])) { $viewTemplate = $viewTemplate->withDescription($view['stream']['description']); } - if ($view['stream']['attribute_keys']) { - $viewTemplate = $viewTemplate->withAttributeKeys($view['stream']['attribute_keys']); + // TODO Add support for excluded keys to view template + if ($view['stream']['attribute_keys']['included']) { + $viewTemplate = $viewTemplate->withAttributeKeys($view['stream']['attribute_keys']['included']); } if (isset($view['stream']['aggregation'])) { // TODO Add support for aggregation providers in views to allow usage of advisory @@ -254,9 +260,9 @@ public function createPlugin(array $properties, Context $context): SdkBuilder return $sdkBuilder; } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('open_telemetry'); + $node = $builder->arrayNode('open_telemetry'); $node ->addDefaultsIfNotSet() ->ignoreExtraKeys() @@ -268,20 +274,20 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit ->validate()->ifNotInArray(['0.3'])->thenInvalid('unsupported version')->end() ->end() ->booleanNode('disabled')->defaultFalse()->end() - ->append($this->getResourceConfig()) - ->append($this->getAttributeLimitsConfig()) + ->append($this->getResourceConfig($builder)) + ->append($this->getAttributeLimitsConfig($builder)) ->append($registry->component('propagator', TextMapPropagatorInterface::class)) - ->append($this->getTracerProviderConfig($registry)) - ->append($this->getMeterProviderConfig($registry)) - ->append($this->getLoggerProviderConfig($registry)) + ->append($this->getTracerProviderConfig($registry, $builder)) + ->append($this->getMeterProviderConfig($registry, $builder)) + ->append($this->getLoggerProviderConfig($registry, $builder)) ->end(); return $node; } - private function getResourceConfig(): ArrayNodeDefinition + private function getResourceConfig(NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('resource'); + $node = $builder->arrayNode('resource'); $node ->addDefaultsIfNotSet() ->children() @@ -298,15 +304,19 @@ private function getResourceConfig(): ArrayNodeDefinition ->end() ->end() ->scalarNode('attributes_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() + ->arrayNode('detectors') + ->variablePrototype()->end() + ->end() + ->scalarNode('attributes_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->scalarNode('schema_url')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->end(); return $node; } - private function getAttributeLimitsConfig(): ArrayNodeDefinition + private function getAttributeLimitsConfig(NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('attribute_limits'); + $node = $builder->arrayNode('attribute_limits'); $node ->addDefaultsIfNotSet() ->children() @@ -317,9 +327,9 @@ private function getAttributeLimitsConfig(): ArrayNodeDefinition return $node; } - private function getTracerProviderConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + private function getTracerProviderConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('tracer_provider'); + $node = $builder->arrayNode('tracer_provider'); $node ->addDefaultsIfNotSet() ->children() @@ -335,19 +345,27 @@ private function getTracerProviderConfig(ComponentProviderRegistry $registry): A ->end() ->end() ->append($registry->component('sampler', SamplerInterface::class)) - ->append($registry->componentArrayList('processors', SpanProcessorInterface::class)) + ->append($registry->componentList('processors', SpanProcessorInterface::class)) ->end() ; return $node; } - private function getMeterProviderConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + private function getMeterProviderConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('meter_provider'); + $node = $builder->arrayNode('meter_provider'); $node ->addDefaultsIfNotSet() ->children() + ->enumNode('exemplar_filter') + ->values([ + 'trace_based', + 'always_on', + 'always_off', + ]) + ->defaultValue('trace_based') + ->end() ->arrayNode('views') ->arrayPrototype() ->children() @@ -357,7 +375,14 @@ private function getMeterProviderConfig(ComponentProviderRegistry $registry): Ar ->scalarNode('name')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->scalarNode('description')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->arrayNode('attribute_keys') - ->scalarPrototype()->validate()->always(Validation::ensureString())->end()->end() + ->children() + ->arrayNode('included') + ->scalarPrototype()->validate()->always(Validation::ensureString())->end()->end() + ->end() + ->arrayNode('excluded') + ->scalarPrototype()->validate()->always(Validation::ensureString())->end()->end() + ->end() + ->end() ->end() ->append($registry->component('aggregation', DefaultAggregationProviderInterface::class)) ->end() @@ -386,16 +411,16 @@ private function getMeterProviderConfig(ComponentProviderRegistry $registry): Ar ->end() ->end() ->end() - ->append($registry->componentArrayList('readers', MetricReaderInterface::class)) + ->append($registry->componentList('readers', MetricReaderInterface::class)) ->end() ; return $node; } - private function getLoggerProviderConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + private function getLoggerProviderConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('logger_provider'); + $node = $builder->arrayNode('logger_provider'); $node ->addDefaultsIfNotSet() ->children() @@ -406,7 +431,7 @@ private function getLoggerProviderConfig(ComponentProviderRegistry $registry): A ->integerNode('attribute_count_limit')->min(0)->defaultNull()->end() ->end() ->end() - ->append($registry->componentArrayList('processors', LogRecordProcessorInterface::class)) + ->append($registry->componentList('processors', LogRecordProcessorInterface::class)) ->end() ; diff --git a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3.php b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3.php index ca349743c..fc96fad72 100644 --- a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3.php +++ b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3.php @@ -11,6 +11,7 @@ use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use OpenTelemetry\Extension\Propagator\B3\B3Propagator; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -27,8 +28,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag return B3Propagator::getB3SingleHeaderInstance(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('b3'); + return $builder->arrayNode('b3'); } } diff --git a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3Multi.php b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3Multi.php index 8809b7df9..286a5f1cb 100644 --- a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3Multi.php +++ b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorB3Multi.php @@ -11,6 +11,7 @@ use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use OpenTelemetry\Extension\Propagator\B3\B3Propagator; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -27,8 +28,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag return B3Propagator::getB3MultiHeaderInstance(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('b3multi'); + return $builder->arrayNode('b3multi'); } } diff --git a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorBaggage.php b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorBaggage.php index c3d05cfd3..22d8b0e84 100644 --- a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorBaggage.php +++ b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorBaggage.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -25,8 +26,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag return BaggagePropagator::getInstance(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('baggage'); + return $builder->arrayNode('baggage'); } } diff --git a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorComposite.php b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorComposite.php index d3d11bd40..e0befeeb4 100644 --- a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorComposite.php +++ b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorComposite.php @@ -11,6 +11,7 @@ use OpenTelemetry\Context\Propagation\MultiTextMapPropagator; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -31,7 +32,7 @@ public function createPlugin(array $properties, Context $context): TextMapPropag return new MultiTextMapPropagator($propagators); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { return $registry->componentNames('composite', TextMapPropagatorInterface::class); } diff --git a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorJaeger.php b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorJaeger.php index 3d8086d52..418086e89 100644 --- a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorJaeger.php +++ b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorJaeger.php @@ -11,6 +11,7 @@ use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use OpenTelemetry\Extension\Propagator\Jaeger\JaegerPropagator; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -27,8 +28,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag return JaegerPropagator::getInstance(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('jaeger'); + return $builder->arrayNode('jaeger'); } } diff --git a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorTraceContext.php b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorTraceContext.php index a55917b6f..b17386125 100644 --- a/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorTraceContext.php +++ b/src/Config/SDK/ComponentProvider/Propagator/TextMapPropagatorTraceContext.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -25,8 +26,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag return TraceContextPropagator::getInstance(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('tracecontext'); + return $builder->arrayNode('tracecontext'); } } diff --git a/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOff.php b/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOff.php index 89090ef28..bf2ae85e3 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOff.php +++ b/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOff.php @@ -10,6 +10,7 @@ use OpenTelemetry\SDK\Trace\Sampler\AlwaysOffSampler; use OpenTelemetry\SDK\Trace\SamplerInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -25,8 +26,8 @@ public function createPlugin(array $properties, Context $context): SamplerInterf return new AlwaysOffSampler(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('always_off'); + return $builder->arrayNode('always_off'); } } diff --git a/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOn.php b/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOn.php index 168d8b902..3792b4dc7 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOn.php +++ b/src/Config/SDK/ComponentProvider/Trace/SamplerAlwaysOn.php @@ -10,6 +10,7 @@ use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler; use OpenTelemetry\SDK\Trace\SamplerInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -25,8 +26,8 @@ public function createPlugin(array $properties, Context $context): SamplerInterf return new AlwaysOnSampler(); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('always_on'); + return $builder->arrayNode('always_on'); } } diff --git a/src/Config/SDK/ComponentProvider/Trace/SamplerParentBased.php b/src/Config/SDK/ComponentProvider/Trace/SamplerParentBased.php index 04438e8c0..3ca588b8e 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SamplerParentBased.php +++ b/src/Config/SDK/ComponentProvider/Trace/SamplerParentBased.php @@ -13,6 +13,7 @@ use OpenTelemetry\SDK\Trace\Sampler\ParentBased; use OpenTelemetry\SDK\Trace\SamplerInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -40,9 +41,9 @@ public function createPlugin(array $properties, Context $context): SamplerInterf ); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('parent_based'); + $node = $builder->arrayNode('parent_based'); $node ->children() ->append($registry->component('root', SamplerInterface::class)->isRequired()) diff --git a/src/Config/SDK/ComponentProvider/Trace/SamplerTraceIdRatioBased.php b/src/Config/SDK/ComponentProvider/Trace/SamplerTraceIdRatioBased.php index d945315f1..0935736bd 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SamplerTraceIdRatioBased.php +++ b/src/Config/SDK/ComponentProvider/Trace/SamplerTraceIdRatioBased.php @@ -10,6 +10,7 @@ use OpenTelemetry\SDK\Trace\Sampler\TraceIdRatioBasedSampler; use OpenTelemetry\SDK\Trace\SamplerInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -29,9 +30,9 @@ public function createPlugin(array $properties, Context $context): SamplerInterf ); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('trace_id_ratio_based'); + $node = $builder->arrayNode('trace_id_ratio_based'); $node ->children() ->floatNode('ratio')->min(0)->max(1)->isRequired()->end() diff --git a/src/Config/SDK/ComponentProvider/Trace/SpanExporterConsole.php b/src/Config/SDK/ComponentProvider/Trace/SpanExporterConsole.php index 945439f2b..50dc4dfaf 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SpanExporterConsole.php +++ b/src/Config/SDK/ComponentProvider/Trace/SpanExporterConsole.php @@ -11,6 +11,7 @@ use OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporter; use OpenTelemetry\SDK\Trace\SpanExporterInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -29,8 +30,8 @@ public function createPlugin(array $properties, Context $context): SpanExporterI )); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('console'); + return $builder->arrayNode('console'); } } diff --git a/src/Config/SDK/ComponentProvider/Trace/SpanExporterOtlp.php b/src/Config/SDK/ComponentProvider/Trace/SpanExporterOtlp.php index 32e2c0521..0d8af094c 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SpanExporterOtlp.php +++ b/src/Config/SDK/ComponentProvider/Trace/SpanExporterOtlp.php @@ -17,6 +17,7 @@ use OpenTelemetry\SDK\Registry; use OpenTelemetry\SDK\Trace\SpanExporterInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -36,6 +37,7 @@ final class SpanExporterOtlp implements ComponentProvider * headers_list: ?string, * compression: 'gzip'|null, * timeout: int<0, max>, + * insecure: ?bool, * } $properties */ public function createPlugin(array $properties, Context $context): SpanExporterInterface @@ -56,9 +58,9 @@ public function createPlugin(array $properties, Context $context): SpanExporterI )); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('otlp'); + $node = $builder->arrayNode('otlp'); $node ->children() ->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc'])->end() @@ -68,7 +70,7 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit ->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->arrayNode('headers') ->arrayPrototype() - ->children() + ->children() ->scalarNode('name')->isRequired()->cannotBeEmpty()->end() ->scalarNode('value')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->end() @@ -77,6 +79,7 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit ->scalarNode('headers_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end() ->enumNode('compression')->values(['gzip'])->defaultNull()->end() ->integerNode('timeout')->min(0)->defaultValue(10)->end() + ->booleanNode('insecure')->defaultNull()->end() ->end() ; diff --git a/src/Config/SDK/ComponentProvider/Trace/SpanExporterZipkin.php b/src/Config/SDK/ComponentProvider/Trace/SpanExporterZipkin.php index a5665ea46..3c54b17f9 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SpanExporterZipkin.php +++ b/src/Config/SDK/ComponentProvider/Trace/SpanExporterZipkin.php @@ -13,6 +13,7 @@ use OpenTelemetry\SDK\Registry; use OpenTelemetry\SDK\Trace\SpanExporterInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -36,9 +37,9 @@ public function createPlugin(array $properties, Context $context): SpanExporterI )); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('zipkin'); + $node = $builder->arrayNode('zipkin'); $node ->children() ->scalarNode('endpoint')->isRequired()->validate()->always(Validation::ensureString())->end()->end() diff --git a/src/Config/SDK/ComponentProvider/Trace/SpanProcessorBatch.php b/src/Config/SDK/ComponentProvider/Trace/SpanProcessorBatch.php index 287192ab9..e60b864a6 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SpanProcessorBatch.php +++ b/src/Config/SDK/ComponentProvider/Trace/SpanProcessorBatch.php @@ -13,6 +13,7 @@ use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor; use OpenTelemetry\SDK\Trace\SpanProcessorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -42,9 +43,9 @@ public function createPlugin(array $properties, Context $context): SpanProcessor ); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('batch'); + $node = $builder->arrayNode('batch'); $node ->children() ->integerNode('schedule_delay')->min(0)->defaultValue(5000)->end() diff --git a/src/Config/SDK/ComponentProvider/Trace/SpanProcessorSimple.php b/src/Config/SDK/ComponentProvider/Trace/SpanProcessorSimple.php index 403037272..4c34231a1 100644 --- a/src/Config/SDK/ComponentProvider/Trace/SpanProcessorSimple.php +++ b/src/Config/SDK/ComponentProvider/Trace/SpanProcessorSimple.php @@ -12,6 +12,7 @@ use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; use OpenTelemetry\SDK\Trace\SpanProcessorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * @implements ComponentProvider @@ -31,9 +32,9 @@ public function createPlugin(array $properties, Context $context): SpanProcessor ); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('simple'); + $node = $builder->arrayNode('simple'); $node ->children() ->append($registry->component('exporter', SpanExporterInterface::class)->isRequired()) diff --git a/src/Config/SDK/Configuration/ComponentProvider.php b/src/Config/SDK/Configuration/ComponentProvider.php index 86e079d73..38c96b008 100644 --- a/src/Config/SDK/Configuration/ComponentProvider.php +++ b/src/Config/SDK/Configuration/ComponentProvider.php @@ -5,6 +5,7 @@ namespace OpenTelemetry\Config\SDK\Configuration; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** * A component provider is responsible for interpreting configuration and returning an @@ -29,12 +30,12 @@ public function createPlugin(array $properties, Context $context): mixed; * Returns an array node describing the properties of this component provider. * * @param ComponentProviderRegistry $registry registry containing all available component providers + * @param NodeBuilder $builder node builder used to create configuration nodes * @return ArrayNodeDefinition array node describing the properties * * @see ComponentProviderRegistry::component() * @see ComponentProviderRegistry::componentList() - * @see ComponentProviderRegistry::componentArrayList() * @see ComponentProviderRegistry::componentNames() */ - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition; + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition; } diff --git a/src/Config/SDK/Configuration/ComponentProviderRegistry.php b/src/Config/SDK/Configuration/ComponentProviderRegistry.php index 363ca638a..fda7615b9 100644 --- a/src/Config/SDK/Configuration/ComponentProviderRegistry.php +++ b/src/Config/SDK/Configuration/ComponentProviderRegistry.php @@ -51,16 +51,16 @@ public function component(string $name, string $type): NodeDefinition; public function componentList(string $name, string $type): ArrayNodeDefinition; /** - * Creates a node to specify a list of component plugins represented as an array. + * Creates a node to specify a map of component plugins. * * `$name: list>` * * ``` * $name: - * - provider1: + * provider1: * property: value * anotherProperty: value - * - provider2: + * provider2: * property: value * anotherProperty: value * ``` @@ -68,7 +68,7 @@ public function componentList(string $name, string $type): ArrayNodeDefinition; * @param string $name name of configuration node * @param string $type type of the component plugin */ - public function componentArrayList(string $name, string $type): ArrayNodeDefinition; + public function componentMap(string $name, string $type): ArrayNodeDefinition; /** * Creates a node to specify a list of component plugin names. * diff --git a/src/Config/SDK/Configuration/ConfigurationFactory.php b/src/Config/SDK/Configuration/ConfigurationFactory.php index 66ce09c32..a3f13c442 100644 --- a/src/Config/SDK/Configuration/ConfigurationFactory.php +++ b/src/Config/SDK/Configuration/ConfigurationFactory.php @@ -14,13 +14,20 @@ use OpenTelemetry\Config\SDK\Configuration\Internal\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Internal\ConfigurationLoader; use OpenTelemetry\Config\SDK\Configuration\Internal\EnvSubstitutionNormalization; +use OpenTelemetry\Config\SDK\Configuration\Internal\NodeDefinition\ArrayNodeDefinition; +use OpenTelemetry\Config\SDK\Configuration\Internal\NodeDefinition\BooleanNodeDefinition; +use OpenTelemetry\Config\SDK\Configuration\Internal\NodeDefinition\FloatNodeDefinition; +use OpenTelemetry\Config\SDK\Configuration\Internal\NodeDefinition\IntegerNodeDefinition; +use OpenTelemetry\Config\SDK\Configuration\Internal\NodeDefinition\ScalarNodeDefinition; +use OpenTelemetry\Config\SDK\Configuration\Internal\NodeDefinition\StringNodeDefinition; +use OpenTelemetry\Config\SDK\Configuration\Internal\NodeDefinition\VariableNodeDefinition; use OpenTelemetry\Config\SDK\Configuration\Internal\ResourceCollection; use OpenTelemetry\Config\SDK\Configuration\Internal\TrackingEnvReader; -use OpenTelemetry\Config\SDK\Configuration\Internal\TreatNullAsUnsetNormalization; use OpenTelemetry\Config\SDK\Configuration\Loader\YamlExtensionFileLoader; use OpenTelemetry\Config\SDK\Configuration\Loader\YamlSymfonyFileLoader; use function serialize; use function sprintf; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\DelegatingLoader; @@ -124,18 +131,31 @@ class_exists(VarExporter::class) private function compileFactory(): CompiledConfigurationFactory { - $registry = new ComponentProviderRegistry(); + $envReader = new TrackingEnvReader($this->envReader); + $normalizations = [ + // Parse MUST perform environment variable substitution. + new EnvSubstitutionNormalization($envReader), + ]; + + $builder = new NodeBuilder(); + $builder->setNodeClass('variable', VariableNodeDefinition::class); + $builder->setNodeClass('scalar', ScalarNodeDefinition::class); + $builder->setNodeClass('boolean', BooleanNodeDefinition::class); + $builder->setNodeClass('integer', IntegerNodeDefinition::class); + $builder->setNodeClass('float', FloatNodeDefinition::class); + $builder->setNodeClass('array', ArrayNodeDefinition::class); + $builder->setNodeClass('string', StringNodeDefinition::class); + + $registry = new ComponentProviderRegistry($normalizations, $builder); + foreach ($this->componentProviders as $provider) { $registry->register($provider); } - $root = $this->rootComponent->getConfig($registry); - - $envReader = new TrackingEnvReader($this->envReader); - // Parse MUST perform environment variable substitution. - (new EnvSubstitutionNormalization($envReader))->apply($root); - // Parse MUST interpret null as equivalent to unset. - (new TreatNullAsUnsetNormalization())->apply($root); + $root = $this->rootComponent->getConfig($registry, $builder); + foreach ($normalizations as $normalization) { + $normalization->apply($root); + } $node = $root->getNode(forceRootNode: true); diff --git a/src/Config/SDK/Configuration/Internal/ArrayNodeDefaultNull.php b/src/Config/SDK/Configuration/Internal/ArrayNodeDefaultNull.php deleted file mode 100644 index 61d3316d7..000000000 --- a/src/Config/SDK/Configuration/Internal/ArrayNodeDefaultNull.php +++ /dev/null @@ -1,35 +0,0 @@ -getName()); - foreach (get_object_vars($node) as $property => $value) { - $defaultNull->$property = $value; - } - - return $defaultNull; - } - - public function hasDefaultValue(): bool - { - return true; - } - - public function getDefaultValue(): mixed - { - return null; - } -} diff --git a/src/Config/SDK/Configuration/Internal/ArrayNodeDefaultNullDefinition.php b/src/Config/SDK/Configuration/Internal/ArrayNodeDefaultNullDefinition.php deleted file mode 100644 index 45a05c4d9..000000000 --- a/src/Config/SDK/Configuration/Internal/ArrayNodeDefaultNullDefinition.php +++ /dev/null @@ -1,25 +0,0 @@ -> */ + /** @var iterable iterable */ + private readonly iterable $normalizations; + private readonly NodeBuilder $builder; + /** @var array> */ private array $providers = []; - /** @var array> */ - private array $recursionProtection = []; private ?ResourceCollection $resources = null; + /** + * @param iterable $normalizations + */ + public function __construct(iterable $normalizations, NodeBuilder $builder) + { + $this->normalizations = $normalizations; + $this->builder = $builder; + } + public function register(ComponentProvider $provider): void { - $name = self::loadName($provider); + $config = $provider->getConfig($this, $this->builder); + + $name = self::loadName($config); $type = self::loadType($provider); if (isset($this->providers[$type][$name])) { throw new LogicException(sprintf('Duplicate component provider registered for "%s" "%s"', $type, $name)); } - $this->providers[$type][$name] = $provider; + $this->providers[$type][$name] = new ComponentProviderRegistryEntry($provider, $config); } public function trackResources(?ResourceCollection $resources): void @@ -55,14 +68,7 @@ public function trackResources(?ResourceCollection $resources): void public function component(string $name, string $type): NodeDefinition { - if (!$this->getProviders($type)) { - return (new VariableNodeDefinition($name)) - ->info(sprintf('Component "%s"', $type)) - ->defaultNull() - ->validate()->always()->thenInvalid(sprintf('Component "%s" cannot be configured, it does not have any associated provider', $type))->end(); - } - - $node = new ArrayNodeDefaultNullDefinition($name); + $node = $this->builder->arrayNode($name); $this->applyToArrayNode($node, $type); return $node; @@ -70,121 +76,103 @@ public function component(string $name, string $type): NodeDefinition public function componentList(string $name, string $type): ArrayNodeDefinition { - $node = new ArrayNodeDefinition($name); - $this->applyToArrayNode($node, $type, true); + $node = $this->builder->arrayNode($name); + $this->applyToArrayNode($node->arrayPrototype(), $type); return $node; } - public function componentArrayList(string $name, string $type): ArrayNodeDefinition + public function componentMap(string $name, string $type): ArrayNodeDefinition { - $node = new ArrayNodeDefinition($name); - $this->applyToArrayNode($node->arrayPrototype(), $type); + $node = $this->builder->arrayNode($name); + $node->info(sprintf('Component "%s"', $type)); + $node->performNoDeepMerging(); + $node->ignoreExtraKeys(false); + $node->validate()->always(function (array|null $value) use ($type): array { + $components = []; + foreach ($value ?? [] as $name => $config) { + $components[] = $this->process($type, $name, [$name => $config]); + } + + return $components; + }); return $node; } public function componentNames(string $name, string $type): ArrayNodeDefinition { - $node = new ArrayNodeDefinition($name); - - $providers = $this->getProviders($type); - foreach ($providers as $providerName => $provider) { - try { - $provider->getConfig(new ComponentProviderRegistry())->getNode(true)->finalize([]); - } catch (InvalidConfigurationException) { - unset($providers[$providerName]); + $node = $this->builder->arrayNode($name); + $node->scalarPrototype()->validate()->always(Validation::ensureString())->end()->end(); + $node->validate()->always(function (array $value) use ($type): array { + $plugins = []; + foreach ($value as $name) { + $plugins[] = $this->process($type, $name, []); } - } - if ($providers) { - $node->enumPrototype()->values(array_keys($providers))->end(); - - $node->validate()->always(function (array $value) use ($type): array { - $plugins = []; - foreach ($value as $name) { - $provider = $this->providers[$type][$name]; - $this->resources?->addClassResource($provider); - $plugins[] = new ComponentPlugin([], $provider); - } - - return $plugins; - }); - } + return $plugins; + }); return $node; } - private function applyToArrayNode(ArrayNodeDefinition $node, string $type, bool $forceArray = false): void + private function applyToArrayNode(ArrayNodeDefinition $node, string $type): void { $node->info(sprintf('Component "%s"', $type)); $node->performNoDeepMerging(); + $node->ignoreExtraKeys(false); + $node->validate()->always(function (array $value) use ($type): ComponentPlugin { + if (count($value) !== 1) { + throw new InvalidArgumentException(sprintf( + 'Component "%s" must have exactly one provider defined, got %s', + $type, + implode(', ', array_map(json_encode(...), array_keys($value)) ?: ['none']) + )); + } - foreach ($this->getProviders($type) as $name => $provider) { - $this->recursionProtection[$type][$name] = true; + return $this->process($type, array_key_first($value), $value); + }); + } - try { - $node->children()->append($provider->getConfig($this)); - } finally { - unset($this->recursionProtection[$type][$name]); + private function process(string $type, string $name, mixed $configs): ComponentPlugin + { + if (!$provider = $this->providers[$type][$name] ?? null) { + throw new InvalidArgumentException(sprintf( + 'Component "%s" uses unknown provider "%s", available providers are %s', + $type, + $name, + implode(', ', array_map(json_encode(...), array_keys($this->providers[$type] ?? [])) ?: ['none']) + )); + } + + if (!$provider->node instanceof NodeInterface) { + foreach ($this->normalizations as $normalization) { + $normalization->apply($provider->node); } + $provider->node = $provider->node->getNode(forceRootNode: true); } - if ($forceArray) { - // if the config was a map rather than an array, force it back to an array - $node->validate()->always(function (array $value) use ($type): array { - $validated = []; - foreach ($value as $name => $v) { - $provider = $this->providers[$type][$name]; - $this->resources?->addClassResource($provider); - $validated[] = new ComponentPlugin($v, $this->providers[$type][$name]); - } - - return $validated; - }); - } else { - $node->validate()->always(function (array $value) use ($type): ComponentPlugin { - if (count($value) !== 1) { - throw new InvalidArgumentException(sprintf( - 'Component "%s" must have exactly one element defined, got %s', - $type, - implode(', ', array_map(json_encode(...), array_keys($value)) ?: ['none']) - )); - } - - $name = array_key_first($value); - $provider = $this->providers[$type][$name]; - $this->resources?->addClassResource($provider); - - return new ComponentPlugin($value[$name], $this->providers[$type][$name]); - }); + try { + $componentConfig = (new Processor())->process($provider->node, $configs); + } catch (InvalidConfigurationException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); } - } - /** - * Returns all registered providers for a specific component type. - * - * @param string $type the component type to load providers for - * @return array component providers indexed by their name - */ - private function getProviders(string $type): array - { - return array_diff_key( - $this->providers[$type] ?? [], - $this->recursionProtection[$type] ?? [], - ); + $this->resources?->addClassResource($provider); + + return new ComponentPlugin($componentConfig, $provider->componentProvider); } /** * @psalm-suppress PossiblyNullFunctionCall,InaccessibleProperty */ - private static function loadName(ComponentProvider $provider): string + private static function loadName(NodeDefinition $node): string { - static $accessor; //@todo inaccessible property $node->name - /** @phpstan-ignore-next-line */ + static $accessor; + // @phpstan-ignore-next-line $accessor ??= (static fn (NodeDefinition $node): ?string => $node->name)->bindTo(null, NodeDefinition::class); - return $accessor($provider->getConfig(new ComponentProviderRegistry())); + return $accessor($node); } private static function loadType(ComponentProvider $provider): string diff --git a/src/Config/SDK/Configuration/Internal/ComponentProviderRegistryEntry.php b/src/Config/SDK/Configuration/Internal/ComponentProviderRegistryEntry.php new file mode 100644 index 000000000..c075cad2a --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/ComponentProviderRegistryEntry.php @@ -0,0 +1,18 @@ +getName()); + foreach (get_object_vars($node) as $property => $value) { + $_node->$property = $value; + } + + return $_node; + } + + public function setDefaultValue(mixed $value): void + { + $this->defaultValue = $value; + $this->defaultValueSet = true; + } + + public function hasDefaultValue(): bool + { + return $this->defaultValueSet || parent::hasDefaultValue(); + } + + public function getDefaultValue(): mixed + { + return $this->defaultValueSet + ? $this->defaultValue + : parent::getDefaultValue(); + } + + public function setAllowEmptyValue(bool $boolean): void + { + $this->allowEmptyValue = $boolean; + } +} diff --git a/src/Config/SDK/Configuration/Internal/Node/BooleanNode.php b/src/Config/SDK/Configuration/Internal/Node/BooleanNode.php new file mode 100644 index 000000000..bc316f83b --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/Node/BooleanNode.php @@ -0,0 +1,10 @@ +allowEmptyValue && $this->defaultValueSet) { + $value = $this->defaultValue; + } + + /** @noinspection PhpMultipleClassDeclarationsInspection */ + return parent::preNormalize($value); + } + + protected function normalizeValue(mixed $value): mixed + { + if ($value === null) { + return null; + } + + /** @noinspection PhpMultipleClassDeclarationsInspection */ + return parent::normalizeValue($value); + } + + protected function mergeValues(mixed $leftSide, mixed $rightSide): mixed + { + if (null === $rightSide) { + return $leftSide; + } + if (null === $leftSide) { + return $rightSide; + } + + /** @noinspection PhpMultipleClassDeclarationsInspection */ + return parent::mergeValues($leftSide, $rightSide); + } + + protected function validateType(mixed $value): void + { + if ($value === null && $this->allowEmptyValue) { + return; + } + + /** @noinspection PhpMultipleClassDeclarationsInspection */ + parent::validateType($value); + } + + public function finalizeValue(mixed $value): mixed + { + if ($value === null) { + return null; + } + + /** @noinspection PhpMultipleClassDeclarationsInspection */ + return parent::finalizeValue($value); + } + + protected function isValueEmpty(mixed $value): bool + { + return $value === null; + } +} diff --git a/src/Config/SDK/Configuration/Internal/Node/PrototypedArrayNode.php b/src/Config/SDK/Configuration/Internal/Node/PrototypedArrayNode.php new file mode 100644 index 000000000..e6b580a20 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/Node/PrototypedArrayNode.php @@ -0,0 +1,47 @@ +getName()); + foreach (get_object_vars($node) as $property => $value) { + $_node->$property = $value; + } + + return $_node; + } + + public function setDefaultValue(mixed $value): void + { + $this->defaultValue_ = $value; + $this->defaultValueSet = true; + } + + public function hasDefaultValue(): bool + { + return $this->defaultValueSet || parent::hasDefaultValue(); + } + + public function getDefaultValue(): mixed + { + return $this->defaultValueSet + ? $this->defaultValue_ + : parent::getDefaultValue(); + } + + public function setAllowEmptyValue(bool $boolean): void + { + $this->allowEmptyValue = $boolean; + } +} diff --git a/src/Config/SDK/Configuration/Internal/Node/ScalarNode.php b/src/Config/SDK/Configuration/Internal/Node/ScalarNode.php new file mode 100644 index 000000000..5a66a84df --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/Node/ScalarNode.php @@ -0,0 +1,10 @@ +nullEquivalent = null; + } + + protected function createNode(): NodeInterface + { + $node = parent::createNode(); + + /** @phpstan-ignore-next-line */ + $node = match (true) { + $node instanceof \Symfony\Component\Config\Definition\PrototypedArrayNode => PrototypedArrayNode::fromNode($node), + $node instanceof \Symfony\Component\Config\Definition\ArrayNode => ArrayNode::fromNode($node), + }; + + $node->setAllowEmptyValue($this->allowEmptyValue); + if ($this->defaultValueSet) { + $node->setDefaultValue($this->defaultValue); + } + + return $node; + } + + public function defaultValue(mixed $value): static + { + $this->defaultValueSet = true; + $this->defaultValue = $value; + + return $this; + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/BooleanNodeDefinition.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/BooleanNodeDefinition.php new file mode 100644 index 000000000..9201eb069 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/BooleanNodeDefinition.php @@ -0,0 +1,20 @@ +name, $this->parent, $this->pathSeparator); + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/EnumNodeDefinition.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/EnumNodeDefinition.php new file mode 100644 index 000000000..e78b696ba --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/EnumNodeDefinition.php @@ -0,0 +1,22 @@ +name, $this->parent, $node->getValues(), $this->pathSeparator); + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/FloatNodeDefinition.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/FloatNodeDefinition.php new file mode 100644 index 000000000..cafc10ff6 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/FloatNodeDefinition.php @@ -0,0 +1,20 @@ +name, $this->parent, $this->min, $this->max, $this->pathSeparator); + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/IntegerNodeDefinition.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/IntegerNodeDefinition.php new file mode 100644 index 000000000..c62b32252 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/IntegerNodeDefinition.php @@ -0,0 +1,20 @@ +name, $this->parent, $this->min, $this->max, $this->pathSeparator); + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/NodeDefinitionTrait.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/NodeDefinitionTrait.php new file mode 100644 index 000000000..88e995f0e --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/NodeDefinitionTrait.php @@ -0,0 +1,31 @@ +allowEmptyValue = false; + + return $this; + } + + public function defaultValue(mixed $value): static + { + /** + * If a property has a default value defined (i.e. is _not_ required) and is + * missing or present but null, Create MUST ensure the SDK component is configured + * with the default value. + **/ + $this->validate()->ifNull()->then(static function () use ($value): mixed { + return $value; + }); + + return parent::defaultValue($value); + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/ScalarNodeDefinition.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/ScalarNodeDefinition.php new file mode 100644 index 000000000..96cefab49 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/ScalarNodeDefinition.php @@ -0,0 +1,20 @@ +name, $this->parent, $this->pathSeparator); + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/StringNodeDefinition.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/StringNodeDefinition.php new file mode 100644 index 000000000..f52fb7f63 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/StringNodeDefinition.php @@ -0,0 +1,20 @@ +name, $this->parent, $this->pathSeparator); + } +} diff --git a/src/Config/SDK/Configuration/Internal/NodeDefinition/VariableNodeDefinition.php b/src/Config/SDK/Configuration/Internal/NodeDefinition/VariableNodeDefinition.php new file mode 100644 index 000000000..61db25e90 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/NodeDefinition/VariableNodeDefinition.php @@ -0,0 +1,20 @@ +name, $this->parent, $this->pathSeparator); + } +} diff --git a/src/Config/SDK/Configuration/Internal/Normalization.php b/src/Config/SDK/Configuration/Internal/Normalization.php new file mode 100644 index 000000000..55d0c8f98 --- /dev/null +++ b/src/Config/SDK/Configuration/Internal/Normalization.php @@ -0,0 +1,16 @@ +getChildNodeDefinitions() as $childNode) { - $this->doApply($childNode); - } - } - - private function doApply(NodeDefinition $node): void - { - $node->beforeNormalization()->ifNull()->thenUnset()->end(); - - if ($node instanceof ParentNodeDefinitionInterface) { - foreach ($node->getChildNodeDefinitions() as $childNode) { - $this->doApply($childNode); - } - } - } -} diff --git a/src/Config/SDK/Configuration/Validation.php b/src/Config/SDK/Configuration/Validation.php index 6e741a879..d68a8131d 100644 --- a/src/Config/SDK/Configuration/Validation.php +++ b/src/Config/SDK/Configuration/Validation.php @@ -37,6 +37,24 @@ public static function ensureString(): Closure }; } + /** + * @psalm-suppress InvalidReturnType,InvalidReturnStatement + */ + public static function ensureNumber(): Closure + { + + return static function (mixed $value): null|int|float { + if ($value === null) { + return null; + } + if (!is_numeric($value)) { + throw new InvalidArgumentException('must be of type numeric'); + } + + return $value; + }; + } + /** * @psalm-suppress ArgumentTypeCoercion */ diff --git a/src/SDK/Metrics/Stream/DeltaStorage.php b/src/SDK/Metrics/Stream/DeltaStorage.php index 066d2d948..52c987c4b 100644 --- a/src/SDK/Metrics/Stream/DeltaStorage.php +++ b/src/SDK/Metrics/Stream/DeltaStorage.php @@ -14,7 +14,7 @@ */ final class DeltaStorage { - private Delta $head; + private readonly Delta $head; public function __construct(private readonly AggregationInterface $aggregation) { diff --git a/tests/Integration/Config/ComponentProvider/Metrics/AggregationResolverExplicitBucketHistogram.php b/tests/Integration/Config/ComponentProvider/Metrics/AggregationResolverExplicitBucketHistogram.php new file mode 100644 index 000000000..978f51e70 --- /dev/null +++ b/tests/Integration/Config/ComponentProvider/Metrics/AggregationResolverExplicitBucketHistogram.php @@ -0,0 +1,50 @@ + + */ +final class AggregationResolverExplicitBucketHistogram implements ComponentProvider +{ + + /** + * @param array{ + * boundaries: array, + * record_min_max: bool, + * } $properties + */ + public function createPlugin(array $properties, Context $context): DefaultAggregationProviderInterface + { + return new class() implements DefaultAggregationProviderInterface { + use DefaultAggregationProviderTrait; + }; + } + + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition + { + $node = $builder->arrayNode('explicit_bucket_histogram'); + $node + ->children() + ->arrayNode('boundaries') + ->prototype('scalar') + ->validate()->always(Validation::ensureNumber())->end() + ->end() + ->end() + ->booleanNode('record_min_max')->defaultTrue()->end() + ->end(); + + return $node; + } +} diff --git a/tests/Integration/Config/ComponentProvider/Metrics/MetricExporterPrometheus.php b/tests/Integration/Config/ComponentProvider/Metrics/MetricExporterPrometheus.php new file mode 100644 index 000000000..f9fd40b9b --- /dev/null +++ b/tests/Integration/Config/ComponentProvider/Metrics/MetricExporterPrometheus.php @@ -0,0 +1,75 @@ + + */ +final class MetricExporterPrometheus implements ComponentProvider +{ + /** + * @param array{ + * host: string, + * port: int, + * without_units: bool, + * without_type_suffix: bool, + * without_scope_info: bool, + * with_resource_constant_labels: array{ + * included: list, + * excluded: list, + * }, + * } $properties + */ + public function createPlugin(array $properties, Context $context): MetricExporterInterface + { + return new class() implements MetricExporterInterface { + + public function export(iterable $batch): bool + { + return true; + } + + public function shutdown(): bool + { + return true; + } + }; + } + + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition + { + $node = $builder->arrayNode('prometheus'); + $node + ->children() + ->scalarNode('host')->isRequired()->validate()->always(Validation::ensureString())->end()->end() + ->scalarNode('port')->isRequired()->validate()->always(Validation::ensureNumber())->end()->end() + ->booleanNode('without_units')->defaultFalse()->end() + ->booleanNode('without_type_suffix')->defaultFalse()->end() + ->booleanNode('without_scope_info')->defaultFalse()->end() + ->booleanNode('without_scope_trace')->defaultFalse()->end() + ->arrayNode('with_resource_constant_labels') + ->children() + ->arrayNode('included') + ->scalarPrototype()->validate()->always(Validation::ensureString())->end()->end() + ->end() + ->arrayNode('excluded') + ->scalarPrototype()->validate()->always(Validation::ensureString())->end()->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $node; + } +} diff --git a/tests/Integration/Config/ComponentProvider/Metrics/MetricReaderPull.php b/tests/Integration/Config/ComponentProvider/Metrics/MetricReaderPull.php new file mode 100644 index 000000000..934306e16 --- /dev/null +++ b/tests/Integration/Config/ComponentProvider/Metrics/MetricReaderPull.php @@ -0,0 +1,62 @@ + + */ +final class MetricReaderPull implements ComponentProvider +{ + /** + * @param array{ + * exporter: ComponentPlugin, + * producers: array, + * } $properties + */ + public function createPlugin(array $properties, Context $context): MetricReaderInterface + { + return new class() implements MetricReaderInterface { + + public function collect(): bool + { + return true; + } + + public function shutdown(): bool + { + return true; + } + + public function forceFlush(): bool + { + return true; + } + }; + } + + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition + { + $node = $builder->arrayNode('pull'); + $node + ->children() + ->append($registry->component('exporter', MetricExporterInterface::class)->isRequired()) + ->arrayNode('producers') //@todo + ->variablePrototype()->end() + ->end() + ->end() + ; + + return $node; + } +} diff --git a/tests/Integration/Config/ComponentProvider/Propagator/TextMapPropagatorOtTrace.php b/tests/Integration/Config/ComponentProvider/Propagator/TextMapPropagatorOtTrace.php new file mode 100644 index 000000000..ec52ace60 --- /dev/null +++ b/tests/Integration/Config/ComponentProvider/Propagator/TextMapPropagatorOtTrace.php @@ -0,0 +1,48 @@ + + */ +final class TextMapPropagatorOtTrace implements ComponentProvider +{ + public function createPlugin(array $properties, Context $context): TextMapPropagatorInterface + { + return new class() implements TextMapPropagatorInterface { + + public function fields(): array + { + return []; + } + + public function inject(mixed &$carrier, ?PropagationSetterInterface $setter = null, ?ContextInterface $context = null): void + { + //no-op + } + + public function extract($carrier, ?PropagationGetterInterface $getter = null, ?ContextInterface $context = null): ContextInterface + { + return $context ?? Ctx::getCurrent(); + } + }; + } + + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition + { + return $builder->arrayNode('ottrace'); + } +} diff --git a/tests/Integration/Config/ComponentProvider/Propagator/TextMapPropagatorXray.php b/tests/Integration/Config/ComponentProvider/Propagator/TextMapPropagatorXray.php new file mode 100644 index 000000000..0515a7a0d --- /dev/null +++ b/tests/Integration/Config/ComponentProvider/Propagator/TextMapPropagatorXray.php @@ -0,0 +1,48 @@ + + */ +final class TextMapPropagatorXray implements ComponentProvider +{ + public function createPlugin(array $properties, Context $context): TextMapPropagatorInterface + { + return new class() implements TextMapPropagatorInterface { + + public function fields(): array + { + return []; + } + + public function inject(mixed &$carrier, ?PropagationSetterInterface $setter = null, ?ContextInterface $context = null): void + { + //no-op + } + + public function extract($carrier, ?PropagationGetterInterface $getter = null, ?ContextInterface $context = null): ContextInterface + { + return $context ?? Ctx::getCurrent(); + } + }; + } + + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition + { + return $builder->arrayNode('xray'); + } +} diff --git a/tests/Integration/Config/configurations/anchors.yaml b/tests/Integration/Config/configurations/anchors.yaml index ea6121ac1..ec042a129 100644 --- a/tests/Integration/Config/configurations/anchors.yaml +++ b/tests/Integration/Config/configurations/anchors.yaml @@ -34,9 +34,14 @@ meter_provider: temporality_preference: delta tracer_provider: + sampler: + always_off: processors: - batch: exporter: otlp: # expand the otlp-exporter anchor <<: *otlp-exporter + +propagator: + composite: [] \ No newline at end of file diff --git a/tests/Integration/Config/configurations/kitchen-sink.yaml b/tests/Integration/Config/configurations/kitchen-sink.yaml index e0dcaf557..0f214721d 100644 --- a/tests/Integration/Config/configurations/kitchen-sink.yaml +++ b/tests/Integration/Config/configurations/kitchen-sink.yaml @@ -5,396 +5,467 @@ # # Configuration values are set to their defaults when default values are defined. -# The file format version +# The file format version. +# The yaml format is documented at +# https://github.com/open-telemetry/opentelemetry-configuration/tree/main/schema file_format: "0.3" - -# Configure if the SDK is disabled or not. This is not required to be provided -# to ensure the SDK isn't disabled, the default value when this is not provided -# is for the SDK to be enabled. -# -# Environment variable: OTEL_SDK_DISABLED +# Configure if the SDK is disabled or not. +# If omitted or null, false is used. disabled: false - # Configure general attribute limits. See also tracer_provider.limits, logger_provider.limits. attribute_limits: - # Configure max attribute value size. - # - # Environment variable: OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT - attribute_value_length_limit: 4096 - # Configure max attribute count. - # - # Environment variable: OTEL_ATTRIBUTE_COUNT_LIMIT - attribute_count_limit: 128 - + # Configure max attribute value size. + # If omitted or null, there is no limit. + attribute_value_length_limit: 4096 + # Configure max attribute count. + # If omitted or null, 128 is used. + attribute_count_limit: 128 # Configure logger provider. +# If omitted, a noop logger provider is used. logger_provider: - # Configure log record processors. - processors: - # Configure a batch log record processor. - - batch: - # Configure delay interval (in milliseconds) between two consecutive exports. - # - # Environment variable: OTEL_BLRP_SCHEDULE_DELAY - schedule_delay: 5000 - # Configure maximum allowed time (in milliseconds) to export data. - # - # Environment variable: OTEL_BLRP_EXPORT_TIMEOUT - export_timeout: 30000 - # Configure maximum queue size. - # - # Environment variable: OTEL_BLRP_MAX_QUEUE_SIZE - max_queue_size: 2048 - # Configure maximum batch size. - # - # Environment variable: OTEL_BLRP_MAX_EXPORT_BATCH_SIZE - max_export_batch_size: 512 - # Configure exporter. - # - # Environment variable: OTEL_LOGS_EXPORTER - exporter: - # Configure exporter to be OTLP. - otlp: - # Configure protocol. - # - # Environment variable: OTEL_EXPORTER_OTLP_PROTOCOL, OTEL_EXPORTER_OTLP_LOGS_PROTOCOL - protocol: http/protobuf - # Configure endpoint. - # - # Environment variable: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT - endpoint: http://localhost:4318 - # Configure certificate. - # - # Environment variable: OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE - certificate: /app/cert.pem - # Configure mTLS private client key. - # - # Environment variable: OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY - client_key: /app/cert.pem - # Configure mTLS client certificate. - # - # Environment variable: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE - client_certificate: /app/cert.pem - # Configure headers. Entries have higher priority than entries from .headers_list. - headers: - - name: api-key - value: "1234" - # Configure headers. Entries have lower priority than entries from .headers. - # The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. - headers_list: "api-key=1234" - # Configure compression. - # - # Environment variable: OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION - compression: gzip - # Configure max time (in milliseconds) to wait for each export. - # - # Environment variable: OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_LOGS_TIMEOUT - timeout: 10000 - # Configure log record limits. See also attribute_limits. - limits: - # Configure max log record attribute value size. Overrides attribute_limits.attribute_value_length_limit. - # - # Environment variable: OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT - attribute_value_length_limit: 4096 - # Configure max log record attribute count. Overrides attribute_limits.attribute_count_limit. - # - # Environment variable: OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT - attribute_count_limit: 128 - + # Configure log record processors. + processors: + - # Configure a batch log record processor. + batch: + # Configure delay interval (in milliseconds) between two consecutive exports. + # If omitted or null, 1000 is used. + schedule_delay: 5000 + # Configure maximum allowed time (in milliseconds) to export data. + # If omitted or null, 30000 is used. + export_timeout: 30000 + # Configure maximum queue size. + # If omitted or null, 2048 is used. + max_queue_size: 2048 + # Configure maximum batch size. + # If omitted or null, 512 is used. + max_export_batch_size: 512 + # Configure exporter. + exporter: + # Configure exporter to be OTLP. + otlp: + # Configure protocol. Values include: http/protobuf, http/json, grpc. + protocol: http/protobuf + # Configure endpoint. + # If .protocol is http/protobuf or http/json, the signal specific path must be included (i.e. http://localhost:4318/v1/{signal}). If .protocol is grpc, a path should not be included (i.e. http://localhost:4317). + endpoint: http://localhost:4318/v1/logs + # Configure certificate. Absolute path to certificate file. + # If omitted or null, system default certificate verification is used for secure connections. + certificate: /app/cert.pem + # Configure mTLS private client key. Absolute path to client key in PEM format. If set, .client_certificate must also be set. + # If omitted or null, mTLS is not used. + client_key: /app/cert.pem + # Configure mTLS client certificate. Absolute path to certificate file. If set, .client_key must also be set. + # If omitted or null, mTLS is not used. + client_certificate: /app/cert.pem + # Configure headers. Entries have higher priority than entries from .headers_list. + # If an entry's .value is null, the entry is ignored. + headers: + - name: api-key + value: "1234" + # Configure headers. Entries have lower priority than entries from .headers. + # The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. + # If omitted or null, no headers are added. + headers_list: "api-key=1234" + # Configure compression. Values include: gzip, none. Implementations may support other compression algorithms. + # If omitted or null, none is used. + compression: gzip + # Configure max time (in milliseconds) to wait for each export. + # If omitted or null, 10000 is used. + timeout: 10000 + # Configure client transport security for the exporter's connection. Only applicable when .protocol is grpc and .endpoint is provided without http or https scheme. Implementations may choose to ignore .insecure. + # If omitted or null, false is used. + insecure: false + - # Configure a simple log record processor. + simple: + # Configure exporter. + exporter: + # Configure exporter to be console. + console: + # Configure log record limits. See also attribute_limits. + limits: + # Configure max attribute value size. Overrides .attribute_limits.attribute_value_length_limit. + # If omitted or null, there is no limit. + attribute_value_length_limit: 4096 + # Configure max attribute count. Overrides .attribute_limits.attribute_count_limit. + # If omitted or null, 128 is used. + attribute_count_limit: 128 # Configure meter provider. +# If omitted, a noop meter provider is used. meter_provider: - # Configure metric readers. - readers: - # Configure a periodic metric reader. - - periodic: - # Configure delay interval (in milliseconds) between start of two consecutive exports. - # - # Environment variable: OTEL_METRIC_EXPORT_INTERVAL - interval: 5000 - # Configure maximum allowed time (in milliseconds) to export data. - # - # Environment variable: OTEL_METRIC_EXPORT_TIMEOUT - timeout: 30000 - # Configure exporter. - # - # Environment variable: OTEL_METRICS_EXPORTER - exporter: - # Configure exporter to be OTLP. - otlp: - # Configure protocol. - # - # Environment variable: OTEL_EXPORTER_OTLP_PROTOCOL, OTEL_EXPORTER_OTLP_METRICS_PROTOCOL - protocol: http/protobuf - # Configure endpoint. - # - # Environment variable: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT - endpoint: http://localhost:4318 - # Configure certificate. - # - # Environment variable: OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE - certificate: /app/cert.pem - # Configure mTLS private client key. - # - # Environment variable: OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY - client_key: /app/cert.pem - # Configure mTLS client certificate. - # - # Environment variable: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE - client_certificate: /app/cert.pem - # Configure headers. Entries have higher priority than entries from .headers_list. - headers: - - name: api-key - value: "1234" - # Configure headers. Entries have lower priority than entries from .headers. - # The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. - headers_list: "api-key=1234" - # Configure compression. - # - # Environment variable: OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION - compression: gzip - # Configure max time (in milliseconds) to wait for each export. - # - # Environment variable: OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_METRICS_TIMEOUT - timeout: 10000 - # Configure temporality preference. - # - # Environment variable: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - temporality_preference: delta - # Configure a periodic metric reader. - - periodic: - # Configure exporter. - exporter: - # Configure exporter to be console. - console: {} - # Configure views. Each view has a selector which determines the instrument(s) it applies to, and a configuration for the resulting stream(s). - views: - # Configure a view. - - selector: - # Configure instrument name selection criteria. - instrument_name: my-instrument - # Configure instrument type selection criteria. - instrument_type: histogram - # Configure the instrument unit selection criteria. - unit: ms - # Configure meter name selection criteria. - meter_name: my-meter - # Configure meter version selection criteria. - meter_version: 1.0.0 - # Configure meter schema url selection criteria. - meter_schema_url: https://opentelemetry.io/schemas/1.16.0 - # Configure stream. - stream: - # Configure metric name of the resulting stream(s). - name: new_instrument_name - # Configure metric description of the resulting stream(s). - description: new_description - # Configure aggregation of the resulting stream(s). Known values include: default, drop, explicit_bucket_histogram, base2_exponential_bucket_histogram, last_value, sum. - aggregation: ~ - # Configure attribute keys retained in the resulting stream(s). - attribute_keys: - - key1 - - key2 - + # Configure metric readers. + readers: + - # Configure a pull based metric reader. + pull: + # Configure exporter. + exporter: + # Configure exporter to be prometheus. + prometheus: + # Configure host. + # If omitted or null, localhost is used. + host: localhost + # Configure port. + # If omitted or null, 9464 is used. + port: 9464 + # Configure Prometheus Exporter to produce metrics without a unit suffix or UNIT metadata. + # If omitted or null, false is used. + without_units: false + # Configure Prometheus Exporter to produce metrics without a type suffix. + # If omitted or null, false is used. + without_type_suffix: false + # Configure Prometheus Exporter to produce metrics without a scope info metric. + # If omitted or null, false is used. + without_scope_info: false + # Configure Prometheus Exporter to add resource attributes as metrics attributes. + with_resource_constant_labels: + # Configure resource attributes to be included. + # Attribute keys from resources are evaluated to match as follows: + # * If the value of the attribute key exactly matches. + # * If the value of the attribute key matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none. + # If omitted, no resource attributes are included. + included: + - "service*" + # Configure resource attributes to be excluded. Applies after .with_resource_constant_labels.included (i.e. excluded has higher priority than included). + # Attribute keys from resources are evaluated to match as follows: + # * If the value of the attribute key exactly matches. + # * If the value of the attribute key matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none. + # If omitted, .included resource attributes are included. + excluded: + - "service.attr1" + # Configure metric producers. + producers: + - # Configure metric producer to be opencensus. + opencensus: + - # Configure a periodic metric reader. + periodic: + # Configure delay interval (in milliseconds) between start of two consecutive exports. + # If omitted or null, 60000 is used. + interval: 60000 + # Configure maximum allowed time (in milliseconds) to export data. + # If omitted or null, 30000 is used. + timeout: 30000 + # Configure exporter. + exporter: + # Configure exporter to be OTLP. + otlp: + # Configure protocol. Values include: http/protobuf, http/json, grpc. + protocol: http/protobuf + # Configure endpoint. + # If .protocol is http/protobuf or http/json, the signal specific path must be included (i.e. http://localhost:4318/v1/{signal}). If .protocol is grpc, a path should not be included (i.e. http://localhost:4317). + endpoint: http://localhost:4318/v1/metrics + # Configure certificate. Absolute path to certificate file. + # If omitted or null, system default certificate verification is used for secure connections. + certificate: /app/cert.pem + # Configure mTLS private client key. Absolute path to client key in PEM format. If set, .client_certificate must also be set. + # If omitted or null, mTLS is not used. + client_key: /app/cert.pem + # Configure mTLS client certificate. Absolute path to certificate file. If set, .client_key must also be set. + # If omitted or null, mTLS is not used. + client_certificate: /app/cert.pem + # Configure headers. Entries have higher priority than entries from .headers_list. + # If an entry's .value is null, the entry is ignored. + headers: + - name: api-key + value: "1234" + # Configure headers. Entries have lower priority than entries from .headers. + # The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. + # If omitted or null, no headers are added. + headers_list: "api-key=1234" + # Configure compression. Values include: gzip, none. Implementations may support other compression algorithms. + # If omitted or null, none is used. + compression: gzip + # Configure max time (in milliseconds) to wait for each export. + # If omitted or null, 10000 is used. + timeout: 10000 + # Configure client transport security for the exporter's connection. Only applicable when .protocol is grpc and .endpoint is provided without http or https scheme. Implementations may choose to ignore .insecure. + # If omitted or null, false is used. + insecure: false + # Configure temporality preference. Values include: cumulative, delta, low_memory. For behavior of values, see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/otlp.md. + # If omitted or null, cumulative is used. + temporality_preference: delta + # Configure default histogram aggregation. Values include: explicit_bucket_histogram, base2_exponential_bucket_histogram. For behavior of values, see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/otlp.md. + # If omitted or null, explicit_bucket_histogram is used. + default_histogram_aggregation: base2_exponential_bucket_histogram + # Configure metric producers. + producers: + - # Configure metric producer to be prometheus. + prometheus: + - # Configure a periodic metric reader. + periodic: + # Configure exporter. + exporter: + # Configure exporter to be console. + console: + # Configure views. Each view has a selector which determines the instrument(s) it applies to, and a configuration for the resulting stream(s). + views: + - # Configure view selector. Selection criteria is additive as described in https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#instrument-selection-criteria. + selector: + # Configure instrument name selection criteria. + # If omitted or null, all instrument names match. + instrument_name: my-instrument + # Configure instrument type selection criteria. + # If omitted or null, all instrument types match. + instrument_type: histogram + # Configure the instrument unit selection criteria. + # If omitted or null, all instrument units match. + unit: ms + # Configure meter name selection criteria. + # If omitted or null, all meter names match. + meter_name: my-meter + # Configure meter version selection criteria. + # If omitted or null, all meter versions match. + meter_version: 1.0.0 + # Configure meter schema url selection criteria. + # If omitted or null, all meter schema URLs match. + meter_schema_url: https://opentelemetry.io/schemas/1.16.0 + # Configure view stream. + stream: + # Configure metric name of the resulting stream(s). + # If omitted or null, the instrument's original name is used. + name: new_instrument_name + # Configure metric description of the resulting stream(s). + # If omitted or null, the instrument's origin description is used. + description: new_description + # Configure aggregation of the resulting stream(s). Values include: default, drop, explicit_bucket_histogram, base2_exponential_bucket_histogram, last_value, sum. For behavior of values see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#aggregation. + # If omitted, default is used. + aggregation: + # Configure aggregation to be explicit_bucket_histogram. + explicit_bucket_histogram: + # Configure bucket boundaries. + # If omitted, [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000] is used. + boundaries: + [ + 0.0, + 5.0, + 10.0, + 25.0, + 50.0, + 75.0, + 100.0, + 250.0, + 500.0, + 750.0, + 1000.0, + 2500.0, + 5000.0, + 7500.0, + 10000.0 + ] + # Configure record min and max. + # If omitted or null, true is used. + record_min_max: true + # Configure attribute keys retained in the resulting stream(s). + attribute_keys: + # Configure list of attribute keys to include in the resulting stream(s). All other attributes are dropped. + # If omitted, all attributes are included. + included: + - key1 + - key2 + # Configure list of attribute keys to exclude from the resulting stream(s). Applies after .attribute_keys.included (i.e. excluded has higher priority than included). + # If omitted, .attribute_keys.included are included. + excluded: + - key3 + # Configure the exemplar filter. Values include: trace_based, always_on, always_off. For behavior of values see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#metrics-sdk-configuration. + # If omitted or null, trace_based is used. + exemplar_filter: trace_based # Configure text map context propagators. -# -# Environment variable: OTEL_PROPAGATORS +# If omitted, tracecontext and baggage are used. propagator: - composite: [tracecontext, baggage, b3, b3multi, jaeger] - + # Configure the set of propagators to include in the composite text map propagator. Built-in values include: tracecontext, baggage, b3, b3multi, jaeger, none. Known third party values include: xray, ottrace. For behavior of values see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration. + composite: [ tracecontext, baggage, b3, b3multi, jaeger, xray, ottrace ] # Configure tracer provider. +# If omitted, a noop tracer provider is used. tracer_provider: - # Configure span processors. - processors: - # Configure a batch span processor. - - batch: - # Configure delay interval (in milliseconds) between two consecutive exports. - # - # Environment variable: OTEL_BSP_SCHEDULE_DELAY - schedule_delay: 5000 - # Configure maximum allowed time (in milliseconds) to export data. - # - # Environment variable: OTEL_BSP_EXPORT_TIMEOUT - export_timeout: 30000 - # Configure maximum queue size. - # - # Environment variable: OTEL_BSP_MAX_QUEUE_SIZE - max_queue_size: 2048 - # Configure maximum batch size. - # - # Environment variable: OTEL_BSP_MAX_EXPORT_BATCH_SIZE - max_export_batch_size: 512 - # Configure exporter. - # - # Environment variable: OTEL_TRACES_EXPORTER - exporter: - # Configure exporter to be OTLP. - otlp: - # Configure protocol. - # - # Environment variable: OTEL_EXPORTER_OTLP_PROTOCOL, OTEL_EXPORTER_OTLP_TRACES_PROTOCOL - protocol: http/protobuf - # Configure endpoint. - # - # Environment variable: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - endpoint: http://localhost:4318 - # Configure certificate. - # - # Environment variable: OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE - certificate: /app/cert.pem - # Configure mTLS private client key. - # - # Environment variable: OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY - client_key: /app/cert.pem - # Configure mTLS client certificate. - # - # Environment variable: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE - client_certificate: /app/cert.pem - # Configure headers. Entries have higher priority than entries from .headers_list. - headers: - - name: api-key - value: "1234" - # Configure headers. Entries have lower priority than entries from .headers. - # The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. - headers_list: "api-key=1234" - # Configure compression. - # - # Environment variable: OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_TRACES_COMPRESSION - compression: gzip - # Configure max time (in milliseconds) to wait for each export. - # - # Environment variable: OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_TRACES_TIMEOUT - timeout: 10000 - # Configure a batch span processor. - - batch: - # Configure exporter. - # - # Environment variable: OTEL_TRACES_EXPORTER - exporter: - # Configure exporter to be zipkin. - zipkin: - # Configure endpoint. - # - # Environment variable: OTEL_EXPORTER_ZIPKIN_ENDPOINT - endpoint: http://localhost:9411/api/v2/spans - # Configure max time (in milliseconds) to wait for each export. - # - # Environment variable: OTEL_EXPORTER_ZIPKIN_TIMEOUT - timeout: 10000 - # Configure a simple span processor. - - simple: - # Configure exporter. - exporter: - # Configure exporter to be console. - console: {} - # Configure span limits. See also attribute_limits. - limits: - # Configure max span attribute value size. Overrides attribute_limits.attribute_value_length_limit. - # - # Environment variable: OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT - attribute_value_length_limit: 4096 - # Configure max span attribute count. Overrides attribute_limits.attribute_count_limit. - # - # Environment variable: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT - attribute_count_limit: 128 - # Configure max span event count. - # - # Environment variable: OTEL_SPAN_EVENT_COUNT_LIMIT - event_count_limit: 128 - # Configure max span link count. - # - # Environment variable: OTEL_SPAN_LINK_COUNT_LIMIT - link_count_limit: 128 - # Configure max attributes per span event. - # - # Environment variable: OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT - event_attribute_count_limit: 128 - # Configure max attributes per span link. - # - # Environment variable: OTEL_LINK_ATTRIBUTE_COUNT_LIMIT - link_attribute_count_limit: 128 - # Configure the sampler. - sampler: - # Configure sampler to be parent_based. Known values include: always_off, always_on, jaeger_remote, parent_based, trace_id_ratio_based. - # - # Environment variable: OTEL_TRACES_SAMPLER=parentbased_* - parent_based: - # Configure root sampler. - # - # Environment variable: OTEL_TRACES_SAMPLER=parentbased_traceidratio - root: - # Configure sampler to be trace_id_ratio_based. - trace_id_ratio_based: - # Configure trace_id_ratio. - # - # Environment variable: OTEL_TRACES_SAMPLER_ARG=traceidratio=0.0001 - ratio: 0.0001 - # Configure remote_parent_sampled sampler. - remote_parent_sampled: - # Configure sampler to be always_on. - always_on: {} - # Configure remote_parent_not_sampled sampler. - remote_parent_not_sampled: - # Configure sampler to be always_off. - always_off: {} - # Configure local_parent_sampled sampler. - local_parent_sampled: - # Configure sampler to be always_on. - always_on: {} - # Configure local_parent_not_sampled sampler. - local_parent_not_sampled: - # Configure sampler to be always_off. - always_off: {} - + # Configure span processors. + processors: + - # Configure a batch span processor. + batch: + # Configure delay interval (in milliseconds) between two consecutive exports. + # If omitted or null, 5000 is used. + schedule_delay: 5000 + # Configure maximum allowed time (in milliseconds) to export data. + # If omitted or null, 30000 is used. + export_timeout: 30000 + # Configure maximum queue size. + # If omitted or null, 2048 is used. + max_queue_size: 2048 + # Configure maximum batch size. + # If omitted or null, 512 is used. + max_export_batch_size: 512 + # Configure exporter. + exporter: + # Configure exporter to be OTLP. + otlp: + # Configure protocol. Values include: http/protobuf, http/json, grpc. + protocol: http/protobuf + # Configure endpoint. + # If .protocol is http/protobuf or http/json, the signal specific path must be included (i.e. http://localhost:4318/v1/{signal}). If .protocol is grpc, a path should not be included (i.e. http://localhost:4317). + endpoint: http://localhost:4318/v1/traces + # Configure certificate. Absolute path to certificate file. + # If omitted or null, system default certificate verification is used for secure connections. + certificate: /app/cert.pem + # Configure mTLS private client key. Absolute path to client key in PEM format. If set, .client_certificate must also be set. + # If omitted or null, mTLS is not used. + client_key: /app/cert.pem + # Configure mTLS client certificate. Absolute path to certificate file. If set, .client_key must also be set. + # If omitted or null, mTLS is not used. + client_certificate: /app/cert.pem + # Configure headers. Entries have higher priority than entries from .headers_list. + # If an entry's .value is null, the entry is ignored. + headers: + - name: api-key + value: "1234" + # Configure headers. Entries have lower priority than entries from .headers. + # The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details. + # If omitted or null, no headers are added. + headers_list: "api-key=1234" + # Configure compression. Values include: gzip, none. Implementations may support other compression algorithms. + # If omitted or null, none is used. + compression: gzip + # Configure max time (in milliseconds) to wait for each export. + # If omitted or null, 10000 is used. + timeout: 10000 + # Configure client transport security for the exporter's connection. Only applicable when .protocol is grpc and .endpoint is provided without http or https scheme. Implementations may choose to ignore .insecure. + # If omitted or null, false is used. + insecure: false + - # Configure a batch span processor. + batch: + # Configure exporter. + exporter: + # Configure exporter to be zipkin. + zipkin: + # Configure endpoint. + # If omitted or null, http://localhost:9411/api/v2/spans is used. + endpoint: http://localhost:9411/api/v2/spans + # Configure max time (in milliseconds) to wait for each export. + # If omitted or null, 10000 is used. + timeout: 10000 + - # Configure a simple span processor. + simple: + # Configure exporter. + exporter: + # Configure exporter to be console. + console: + # Configure span limits. See also attribute_limits. + limits: + # Configure max attribute value size. Overrides .attribute_limits.attribute_value_length_limit. + # If omitted or null, there is no limit. + attribute_value_length_limit: 4096 + # Configure max attribute count. Overrides .attribute_limits.attribute_count_limit. + # If omitted or null, 128 is used. + attribute_count_limit: 128 + # Configure max span event count. + # If omitted or null, 128 is used. + event_count_limit: 128 + # Configure max span link count. + # If omitted or null, 128 is used. + link_count_limit: 128 + # Configure max attributes per span event. + # If omitted or null, 128 is used. + event_attribute_count_limit: 128 + # Configure max attributes per span link. + # If omitted or null, 128 is used. + link_attribute_count_limit: 128 + # Configure the sampler. + # If omitted, parent based sampler with a root of always_on is used. + sampler: + # Configure sampler to be parent_based. + parent_based: + # Configure root sampler. + # If omitted or null, always_on is used. + root: + # Configure sampler to be trace_id_ratio_based. + trace_id_ratio_based: + # Configure trace_id_ratio. + # If omitted or null, 1.0 is used. + ratio: 0.0001 + # Configure remote_parent_sampled sampler. + # If omitted or null, always_on is used. + remote_parent_sampled: + # Configure sampler to be always_on. + always_on: + # Configure remote_parent_not_sampled sampler. + # If omitted or null, always_off is used. + remote_parent_not_sampled: + # Configure sampler to be always_off. + always_off: + # Configure local_parent_sampled sampler. + # If omitted or null, always_on is used. + local_parent_sampled: + # Configure sampler to be always_on. + always_on: + # Configure local_parent_not_sampled sampler. + # If omitted or null, always_off is used. + local_parent_not_sampled: + # Configure sampler to be always_off. + always_off: # Configure resource for all signals. +# If omitted, the default resource is used. resource: - # Configure resource attributes. Entries have higher priority than entries from .resource.attributes_list. - # Entries must contain .name nand .value, and may optionally include .type, which defaults ot "string" if not set. The value must match the type. Values for .type include: string, bool, int, double, string_array, bool_array, int_array, double_array. + # Configure resource attributes. Entries have higher priority than entries from .resource.attributes_list. + # Entries must contain .name and .value, and may optionally include .type. If an entry's .type omitted or null, string is used. + # The .value's type must match the .type. Values for .type include: string, bool, int, double, string_array, bool_array, int_array, double_array. + attributes: + - name: service.name + value: unknown_service + - name: string_key + value: value + type: string + - name: bool_key + value: true + type: bool + - name: int_key + value: 1 + type: int + - name: double_key + value: 1.1 + type: double + - name: string_array_key + value: [ "value1", "value2" ] + type: string_array + - name: bool_array_key + value: [ true, false ] + type: bool_array + - name: int_array_key + value: [ 1, 2 ] + type: int_array + - name: double_array_key + value: [ 1.1, 2.2 ] + type: double_array + # Configure resource attributes. Entries have lower priority than entries from .resource.attributes. + # The value is a list of comma separated key-value pairs matching the format of OTEL_RESOURCE_ATTRIBUTES. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details. + # If omitted or null, no resource attributes are added. + attributes_list: "service.namespace=my-namespace,service.version=1.0.0" + # Configure resource detectors. + detectors: + # Configure attributes provided by resource detectors. attributes: - - name: service.name - value: unknown_service - - name: string_key - value: value - type: string - - name: bool_key - value: true - type: bool - - name: int_key - value: 1 - type: int - - name: double_key - value: 1.1 - type: double - - name: string_array_key - value: [ "value1", "value2" ] - type: string_array - - name: bool_array_key - value: [ true, false ] - type: bool_array - - name: int_array_key - value: [ 1, 2 ] - type: int_array - - name: double_array_key - value: [ 1.1, 2.2 ] - type: double_array - # Configure resource attributes. Entries have lower priority than entries from .resource.attributes. - # The value is a list of comma separated key-value pairs matching the format of OTEL_RESOURCE_ATTRIBUTES. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details. - attributes_list: "service.namespace=my-namespace,service.version=1.0.0" - # Configure the resource schema URL. - schema_url: https://opentelemetry.io/schemas/1.27.0 - + # Configure list of attribute key patterns to include from resource detectors. + # Attribute keys from resource detectors are evaluated to match as follows: + # * If the value of the attribute key exactly matches. + # * If the value of the attribute key matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none. + # If omitted, all attributes are included. + included: + - process.* + # Configure list of attribute key patterns to exclude from resource detectors. Applies after .resource.detectors.attributes.included (i.e. excluded has higher priority than included). + # Attribute keys from resource detectors are evaluated to match as follows: + # * If the value of the attribute key exactly matches. + # * If the value of the attribute key matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none. + # If omitted, .included attributes are included. + excluded: + - process.command_args + # Configure resource schema URL. + # If omitted or null, no schema URL is used. + schema_url: https://opentelemetry.io/schemas/1.27.0 # Configure instrumentation. instrumentation: # Configure general SemConv options that may apply to multiple languages and instrumentations. - # # Instrumenation may merge general config options with the language specific configuration at .instrumentation.. general: # Configure instrumentations following the peer semantic conventions. - # # See peer semantic conventions: https://opentelemetry.io/docs/specs/semconv/attributes-registry/peer/ peer: # Configure the service mapping for instrumentations following peer.service semantic conventions. - # # Each entry is a key value pair where "peer" defines the IP address and "service" defines the corresponding logical name of the service. - # # See peer.service semantic conventions: https://opentelemetry.io/docs/specs/semconv/general/attributes/#general-remote-service-attributes service_mapping: - peer: 1.2.3.4 @@ -402,7 +473,6 @@ instrumentation: - peer: 2.3.4.5 service: BarService # Configure instrumentations following the http semantic conventions. - # # See http semantic conventions: https://opentelemetry.io/docs/specs/semconv/http/ http: # Configure instrumentations following the http client semantic conventions. @@ -425,10 +495,6 @@ instrumentation: response_captured_headers: - Content-Type - Content-Encoding - # Configure language-specific instrumentation libraries. - # - # Keys may refer to instrumentation libraries or collections of related configuration. Because there is no central schema defining the keys or their contents, instrumentation must carefully document their schema and avoid key collisions with other instrumentations. - # # Configure C++ language-specific instrumentation libraries. cpp: # Configure the instrumentation corresponding to key "example". diff --git a/tests/Unit/Config/SDK/Configuration/ConfigurationFactoryTest.php b/tests/Unit/Config/SDK/Configuration/ConfigurationFactoryTest.php index 04302026d..a8626c788 100644 --- a/tests/Unit/Config/SDK/Configuration/ConfigurationFactoryTest.php +++ b/tests/Unit/Config/SDK/Configuration/ConfigurationFactoryTest.php @@ -21,6 +21,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; use Symfony\Component\Yaml\Yaml; #[CoversClass(ConfigurationFactory::class)] @@ -57,7 +58,7 @@ public function createPlugin(array $properties, Context $context): mixed /** * @psalm-suppress UndefinedInterfaceMethod,PossiblyNullReference */ - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { $node = new ArrayNodeDefinition('env_substitution'); /** @phpstan-ignore-next-line */ @@ -127,7 +128,7 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit combo_string_key: foo value 1.1 # Interpreted as type string, tag URI tag:yaml.org,2002:str string_key_with_default: fallback # Interpreted as type string, tag URI tag:yaml.org,2002:str # undefined_key removed as null is treated as unset - # undefined_key: # Interpreted as type null, tag URI tag:yaml.org,2002:null + undefined_key: # Interpreted as type null, tag URI tag:yaml.org,2002:null ${STRING_VALUE}: value # Interpreted as type string, tag URI tag:yaml.org,2002:str YAML), self::getPropertiesFromPlugin($parsed), @@ -167,16 +168,23 @@ public function test_env_substitution_non_string(): void $this->assertSame(2048, self::getPropertiesFromPlugin($parsed)['attribute_limits']['attribute_value_length_limit']); } - public function test_treat_null_as_unset(): void + /** + * If a property has a default value defined (i.e. is _not_ required) and is + * missing or present but null, Create MUST ensure the SDK component is configured + * with the default value. + */ + #[BackupGlobals(true)] + public function test_env_substitution_missing_value(): void { + unset($_SERVER['OTEL_ATTRIBUTE_COUNT_LIMIT']); $parsed = self::factory()->process([[ 'file_format' => '0.1', 'attribute_limits' => [ - 'attribute_count_limit' => null, + 'attribute_count_limit' => '${OTEL_ATTRIBUTE_COUNT_LIMIT}', ], ]]); - $this->assertInstanceOf(ComponentPlugin::class, $parsed); + $this->assertNull(self::getPropertiesFromPlugin($parsed)['attribute_limits']['attribute_value_length_limit']); $this->assertSame(128, self::getPropertiesFromPlugin($parsed)['attribute_limits']['attribute_count_limit']); } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterConsole.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterConsole.php index df77c1224..b97901d59 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterConsole.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterConsole.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class LogRecordExporterConsole implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): LogRecordExpo throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('console'); + return $builder->arrayNode('console'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterOtlp.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterOtlp.php index 469c731f8..32bf183d5 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterOtlp.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordExporterOtlp.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Config\SDK\Configuration\Validation; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class LogRecordExporterOtlp implements ComponentProvider { @@ -32,9 +33,9 @@ public function createPlugin(array $properties, Context $context): LogRecordExpo throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('otlp'); + $node = $builder->arrayNode('otlp'); $node ->children() ->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc/protobuf', 'grpc/json'])->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorBatch.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorBatch.php index 1d4a00f91..154c208f7 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorBatch.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorBatch.php @@ -12,6 +12,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class LogRecordProcessorBatch implements ComponentProvider { @@ -30,9 +31,9 @@ public function createPlugin(array $properties, Context $context): LogRecordProc throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('batch'); + $node = $builder->arrayNode('batch'); $node ->children() ->integerNode('schedule_delay')->min(0)->defaultValue(5000)->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorSimple.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorSimple.php index fa728816f..e3225ecb2 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorSimple.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Logs/LogRecordProcessorSimple.php @@ -12,6 +12,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class LogRecordProcessorSimple implements ComponentProvider { @@ -26,9 +27,9 @@ public function createPlugin(array $properties, Context $context): LogRecordProc throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('simple'); + $node = $builder->arrayNode('simple'); $node ->children() ->append($registry->component('exporter', LogRecordExporter::class)->isRequired()) diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDefault.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDefault.php index 4ccfc034b..2c640adfa 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDefault.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDefault.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class AggregationResolverDefault implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): AggregationRe throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('default'); + return $builder->arrayNode('default'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDrop.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDrop.php index 6067a05df..46c53ad24 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDrop.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverDrop.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class AggregationResolverDrop implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): AggregationRe throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('drop'); + return $builder->arrayNode('drop'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverExplicitBucketHistogram.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverExplicitBucketHistogram.php index 3a0736106..0626e3446 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverExplicitBucketHistogram.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverExplicitBucketHistogram.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class AggregationResolverExplicitBucketHistogram implements ComponentProvider { @@ -26,9 +27,9 @@ public function createPlugin(array $properties, Context $context): AggregationRe throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('explicit_bucket_histogram'); + $node = $builder->arrayNode('explicit_bucket_histogram'); $node ->children() ->arrayNode('boundaries') diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverLastValue.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverLastValue.php index 16dc6a4dd..3b514cb0a 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverLastValue.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverLastValue.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class AggregationResolverLastValue implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): AggregationRe throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('last_value'); + return $builder->arrayNode('last_value'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverSum.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverSum.php index c79368a8e..32b481cb8 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverSum.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/AggregationResolverSum.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class AggregationResolverSum implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): AggregationRe throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('sum'); + return $builder->arrayNode('sum'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterConsole.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterConsole.php index 27d7c8a83..2b0fa06ff 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterConsole.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterConsole.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class MetricExporterConsole implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): MetricExporte throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('console'); + return $builder->arrayNode('console'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterOtlp.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterOtlp.php index 8fb2779b7..d3e9a9ffb 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterOtlp.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterOtlp.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Config\SDK\Configuration\Validation; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class MetricExporterOtlp implements ComponentProvider { @@ -34,9 +35,9 @@ public function createPlugin(array $properties, Context $context): MetricExporte throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('otlp'); + $node = $builder->arrayNode('otlp'); $node ->children() ->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc/protobuf', 'grpc/json'])->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterPrometheus.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterPrometheus.php index beb2873c7..2f6d2e816 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterPrometheus.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricExporterPrometheus.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Config\SDK\Configuration\Validation; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class MetricExporterPrometheus implements ComponentProvider { @@ -29,9 +30,9 @@ public function createPlugin(array $properties, Context $context): MetricExporte throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('prometheus'); + $node = $builder->arrayNode('prometheus'); $node ->children() ->scalarNode('host')->defaultValue('localhost')->validate()->always(Validation::ensureString())->end()->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPeriodic.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPeriodic.php index 932668ea0..12c0a1508 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPeriodic.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPeriodic.php @@ -12,6 +12,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class MetricReaderPeriodic implements ComponentProvider { @@ -28,9 +29,9 @@ public function createPlugin(array $properties, Context $context): MetricReader throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('periodic'); + $node = $builder->arrayNode('periodic'); $node ->children() ->integerNode('interval')->min(0)->defaultValue(5000)->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPull.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPull.php index c9ce152b2..acbe26345 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPull.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Metrics/MetricReaderPull.php @@ -12,6 +12,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class MetricReaderPull implements ComponentProvider { @@ -26,9 +27,9 @@ public function createPlugin(array $properties, Context $context): MetricReader throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('pull'); + $node = $builder->arrayNode('pull'); $node ->children() ->append($registry->component('exporter', MetricExporter::class)->isRequired()) diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/OpenTelemetryConfiguration.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/OpenTelemetryConfiguration.php index 3731ab722..d79ceb77c 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/OpenTelemetryConfiguration.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/OpenTelemetryConfiguration.php @@ -18,6 +18,7 @@ use OpenTelemetry\Config\SDK\Configuration\Validation; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class OpenTelemetryConfiguration implements ComponentProvider { @@ -80,9 +81,9 @@ public function createPlugin(array $properties, Context $context): Configuration throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('open_telemetry'); + $node = $builder->arrayNode('open_telemetry'); $node ->addDefaultsIfNotSet() ->ignoreExtraKeys() @@ -94,20 +95,20 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit ->validate()->ifNotInArray(['0.1'])->thenInvalid('unsupported version')->end() ->end() ->booleanNode('disabled')->defaultFalse()->end() - ->append($this->getResourceConfig()) - ->append($this->getAttributeLimitsConfig()) + ->append($this->getResourceConfig($builder)) + ->append($this->getAttributeLimitsConfig($builder)) ->append($registry->component('propagator', TextMapPropagatorInterface::class)) - ->append($this->getTracerProviderConfig($registry)) - ->append($this->getMeterProviderConfig($registry)) - ->append($this->getLoggerProviderConfig($registry)) + ->append($this->getTracerProviderConfig($registry, $builder)) + ->append($this->getMeterProviderConfig($registry, $builder)) + ->append($this->getLoggerProviderConfig($registry, $builder)) ->end(); return $node; } - private function getResourceConfig(): ArrayNodeDefinition + private function getResourceConfig(NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('resource'); + $node = $builder->arrayNode('resource'); $node ->addDefaultsIfNotSet() ->children() @@ -120,9 +121,9 @@ private function getResourceConfig(): ArrayNodeDefinition return $node; } - private function getAttributeLimitsConfig(): ArrayNodeDefinition + private function getAttributeLimitsConfig(NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('attribute_limits'); + $node = $builder->arrayNode('attribute_limits'); $node ->addDefaultsIfNotSet() ->children() @@ -133,9 +134,9 @@ private function getAttributeLimitsConfig(): ArrayNodeDefinition return $node; } - private function getTracerProviderConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + private function getTracerProviderConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('tracer_provider'); + $node = $builder->arrayNode('tracer_provider'); $node ->addDefaultsIfNotSet() ->children() @@ -151,16 +152,16 @@ private function getTracerProviderConfig(ComponentProviderRegistry $registry): A ->end() ->end() ->append($registry->component('sampler', Sampler::class)) - ->append($registry->componentArrayList('processors', SpanProcessor::class)) + ->append($registry->componentList('processors', SpanProcessor::class)) ->end() ; return $node; } - private function getMeterProviderConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + private function getMeterProviderConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('meter_provider'); + $node = $builder->arrayNode('meter_provider'); $node ->addDefaultsIfNotSet() ->children() @@ -203,16 +204,16 @@ private function getMeterProviderConfig(ComponentProviderRegistry $registry): Ar ->end() ->end() ->end() - ->append($registry->componentArrayList('readers', MetricReader::class)) + ->append($registry->componentList('readers', MetricReader::class)) ->end() ; return $node; } - private function getLoggerProviderConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + private function getLoggerProviderConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('logger_provider'); + $node = $builder->arrayNode('logger_provider'); $node ->addDefaultsIfNotSet() ->children() @@ -223,7 +224,7 @@ private function getLoggerProviderConfig(ComponentProviderRegistry $registry): A ->integerNode('attribute_count_limit')->min(0)->defaultNull()->end() ->end() ->end() - ->append($registry->componentArrayList('processors', LogRecordProcessor::class)) + ->append($registry->componentList('processors', LogRecordProcessor::class)) ->end() ; diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3.php index 6dab69009..b4cc3abe4 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorB3 implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('b3'); + return $builder->arrayNode('b3'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3Multi.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3Multi.php index 20fd5c753..bd19526cc 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3Multi.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorB3Multi.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorB3Multi implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('b3multi'); + return $builder->arrayNode('b3multi'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorBaggage.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorBaggage.php index fab7a0652..fd5bce514 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorBaggage.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorBaggage.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorBaggage implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('baggage'); + return $builder->arrayNode('baggage'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorComposite.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorComposite.php index 8089d6efb..bc7ae1b89 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorComposite.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorComposite.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorComposite implements ComponentProvider { @@ -23,7 +24,7 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { return $registry->componentNames('composite', TextMapPropagatorInterface::class); } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorJaeger.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorJaeger.php index 1d6a01da0..c1695ad3e 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorJaeger.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorJaeger.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorJaeger implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('jaeger'); + return $builder->arrayNode('jaeger'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorOTTrace.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorOTTrace.php index 397031784..b5f66d957 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorOTTrace.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorOTTrace.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorOTTrace implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('ottrace'); + return $builder->arrayNode('ottrace'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorTraceContext.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorTraceContext.php index d3e730a44..32cbed311 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorTraceContext.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorTraceContext.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorTraceContext implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('tracecontext'); + return $builder->arrayNode('tracecontext'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorXRay.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorXRay.php index 4be5bd7f4..976aa58dd 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorXRay.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Propagator/TextMapPropagatorXRay.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class TextMapPropagatorXRay implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): TextMapPropag throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('xray'); + return $builder->arrayNode('xray'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOff.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOff.php index 552b2f992..366ea330a 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOff.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOff.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SamplerAlwaysOff implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): Sampler throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('always_off'); + return $builder->arrayNode('always_off'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOn.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOn.php index f9aacdd93..5df8ebce7 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOn.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerAlwaysOn.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SamplerAlwaysOn implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): Sampler throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('always_on'); + return $builder->arrayNode('always_on'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerParentBased.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerParentBased.php index b6569ca45..1a70f9b68 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerParentBased.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerParentBased.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SamplerParentBased implements ComponentProvider { @@ -29,9 +30,9 @@ public function createPlugin(array $properties, Context $context): Sampler throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('parent_based'); + $node = $builder->arrayNode('parent_based'); $node ->children() ->append($registry->component('root', Sampler::class)->isRequired()) diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerTraceIdRatioBased.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerTraceIdRatioBased.php index eb6e6cb7d..0544b5409 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerTraceIdRatioBased.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SamplerTraceIdRatioBased.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SamplerTraceIdRatioBased implements ComponentProvider { @@ -24,9 +25,9 @@ public function createPlugin(array $properties, Context $context): Sampler throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('trace_id_ratio_based'); + $node = $builder->arrayNode('trace_id_ratio_based'); $node ->children() ->floatNode('ratio')->min(0)->max(1)->isRequired()->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterConsole.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterConsole.php index be7627279..3906da2de 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterConsole.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterConsole.php @@ -10,6 +10,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SpanExporterConsole implements ComponentProvider { @@ -22,8 +23,8 @@ public function createPlugin(array $properties, Context $context): SpanExporter throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - return new ArrayNodeDefinition('console'); + return $builder->arrayNode('console'); } } diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterOtlp.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterOtlp.php index 6bd53513e..1d974d4ce 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterOtlp.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterOtlp.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Config\SDK\Configuration\Validation; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SpanExporterOtlp implements ComponentProvider { @@ -32,9 +33,9 @@ public function createPlugin(array $properties, Context $context): SpanExporter throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('otlp'); + $node = $builder->arrayNode('otlp'); $node ->children() ->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc/protobuf', 'grpc/json'])->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterZipkin.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterZipkin.php index c0037c901..c3bdbfba2 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterZipkin.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanExporterZipkin.php @@ -11,6 +11,7 @@ use OpenTelemetry\Config\SDK\Configuration\Context; use OpenTelemetry\Config\SDK\Configuration\Validation; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SpanExporterZipkin implements ComponentProvider { @@ -26,9 +27,9 @@ public function createPlugin(array $properties, Context $context): SpanExporter throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('zipkin'); + $node = $builder->arrayNode('zipkin'); $node ->children() ->scalarNode('endpoint')->isRequired()->validate()->always(Validation::ensureString())->end()->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorBatch.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorBatch.php index de2c24026..62fc08da3 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorBatch.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorBatch.php @@ -12,6 +12,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SpanProcessorBatch implements ComponentProvider { @@ -30,9 +31,9 @@ public function createPlugin(array $properties, Context $context): SpanProcessor throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('batch'); + $node = $builder->arrayNode('batch'); $node ->children() ->integerNode('schedule_delay')->min(0)->defaultValue(5000)->end() diff --git a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorSimple.php b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorSimple.php index b9c3c7b41..feeeb8054 100644 --- a/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorSimple.php +++ b/tests/Unit/Config/SDK/Configuration/ExampleSdk/Trace/SpanProcessorSimple.php @@ -12,6 +12,7 @@ use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry; use OpenTelemetry\Config\SDK\Configuration\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; final class SpanProcessorSimple implements ComponentProvider { @@ -26,9 +27,9 @@ public function createPlugin(array $properties, Context $context): SpanProcessor throw new BadMethodCallException('not implemented'); } - public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinition + public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition { - $node = new ArrayNodeDefinition('simple'); + $node = $builder->arrayNode('simple'); $node ->children() ->append($registry->component('exporter', SpanExporter::class)->isRequired()) diff --git a/tests/Unit/SDK/fixtures/otel-sdk.yaml b/tests/Unit/SDK/fixtures/otel-sdk.yaml index 510810ea1..4adc05b77 100644 --- a/tests/Unit/SDK/fixtures/otel-sdk.yaml +++ b/tests/Unit/SDK/fixtures/otel-sdk.yaml @@ -4,7 +4,12 @@ tracer_provider: processors: - simple: exporter: - console: {} + console: + sampler: + always_off: + +propagator: + composite: [] instrumentation: php: