From eb490cf56bf2ea6e9203de8c98960cea781c9839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Reyrol?= Date: Fri, 26 Jan 2024 18:56:18 +0100 Subject: [PATCH] refactor: better services injection with factories --- .github/workflows/ci.yml | 2 +- .gitignore | 1 + composer.json | 18 +- phpunit.xml.dist | 27 +- src/DependencyInjection/Configuration.php | 7 +- .../ExporterDefinitionsFactory.php | 44 --- .../OpenTelemetryExtension.php | 10 +- .../OpenTelemetryLogsExtension.php | 153 ++-------- .../OpenTelemetryMetricsExtension.php | 98 ++----- .../OpenTelemetryTracesExtension.php | 203 +++---------- .../Cache/TagAwareTraceableCacheAdapter.php | 2 +- .../Symfony/Cache/TraceableCacheAdapter.php | 2 +- .../HttpClient/TraceableHttpClient.php | 2 +- .../Symfony/HttpClient/TraceableResponse.php | 2 +- .../Symfony/Mailer/TraceableMailer.php | 2 +- .../Mailer/TraceableMailerTransport.php | 2 +- src/OpenTelemetry/Exporter/ExporterDsn.php | 2 +- .../Exporter/ExporterFactoryInterface.php | 4 +- .../Exporter/OtlpExporterEndpoint.php | 2 +- .../AbstractLogExporterFactory.php | 15 + .../LogExporter/ConsoleLogExporterFactory.php | 12 +- .../InMemoryLogExporterFactory.php | 9 +- .../Log/LogExporter/LogExporterEnum.php | 24 -- .../Log/LogExporter/LogExporterFactory.php | 39 +++ .../LogExporter/NoopLogExporterFactory.php | 9 +- .../LogExporter/OtlpLogExporterFactory.php | 25 +- .../AbstractLogProcessorFactory.php | 13 + .../LogProcessorFactoryInterface.php | 2 +- .../LogProcessor/MultiLogProcessorFactory.php | 4 +- .../LogProcessor/NoopLogProcessorFactory.php | 4 +- .../SimpleLogProcessorFactory.php | 4 +- .../AbstractLoggerProviderFactory.php | 12 + ...y.php => DefaultLoggerProviderFactory.php} | 6 +- .../Log/LoggerProvider/LoggerProviderEnum.php | 2 +- .../LoggerProviderFactoryInterface.php | 4 +- .../NoopLoggerProviderFactory.php | 6 +- .../Metric/ExemplarFilterEnum.php | 10 + .../Metric/ExemplarFilterFactory.php | 23 ++ .../AbstractMeterProviderFactory.php | 12 + ...ry.php => DefaultMeterProviderFactory.php} | 2 +- .../MeterProvider/ExemplarFilterEnum.php | 27 -- .../MeterProvider/MeterProviderEnum.php | 2 +- .../NoopMeterProviderFactory.php | 4 +- .../AbstractMetricExporterFactory.php | 15 + .../ConsoleMetricExporterFactory.php | 13 +- .../InMemoryMetricExporterFactory.php | 9 +- .../MetricExporter/MetricExporterEnum.php | 24 -- .../MetricExporter/MetricExporterFactory.php | 39 +++ .../NoopMetricExporterFactory.php | 9 +- .../OtlpMetricExporterFactory.php | 29 +- src/OpenTelemetry/Trace/SamplerFactory.php | 27 ++ .../AbstractSpanExporterFactory.php | 15 + .../ConsoleSpanExporterFactory.php | 12 +- .../InMemorySpanExporterFactory.php | 9 +- .../SpanExporter/OtlpSpanExporterFactory.php | 23 +- .../SpanExporter/SpanExporterFactory.php | 39 +++ .../Trace/SpanExporter/TraceExporterEnum.php | 31 -- .../ZipkinSpanExporterFactory.php | 20 +- .../AbstractSpanProcessorFactory.php | 13 + .../MultiSpanProcessorFactory.php | 4 +- .../NoopSpanProcessorFactory.php | 4 +- .../SimpleSpanProcessorFactory.php | 4 +- .../Trace/SpanProcessor/SpanProcessorEnum.php | 31 -- .../SpanProcessorFactoryInterface.php | 2 +- src/OpenTelemetry/Trace/TraceSamplerEnum.php | 13 + .../AbstractTracerProviderFactory.php | 12 + ...y.php => DefaultTracerProviderFactory.php} | 4 +- .../NoopTracerProviderFactory.php | 2 +- .../TracerProvider/TraceProviderEnum.php | 26 -- .../Trace/TracerProvider/TraceSamplerEnum.php | 30 -- .../TracerProviderFactoryInterface.php | 2 +- .../Trace/ZipkinExporterEndpoint.php | 2 +- .../Transport/AbstractTransportFactory.php | 13 + .../Transport/GrpcTransportFactory.php | 45 ++- .../Transport/OtlpHttpTransportFactory.php | 44 +-- .../Transport/PsrHttpTransportFactory.php | 43 +-- .../Transport/StreamTransportFactory.php | 43 +-- src/OpenTelemetry/Transport/TransportEnum.php | 12 - .../Transport/TransportFactory.php | 39 +++ .../Transport/TransportFactoryInterface.php | 6 +- src/Resources/config/services.php | 81 ++---- src/Resources/config/services_logs.php | 103 +++++++ src/Resources/config/services_metrics.php | 101 +++++++ src/Resources/config/services_traces.php | 105 +++++++ .../services_tracing_instrumentation.php | 4 +- src/Resources/config/services_transports.php | 47 ++++ tests/Unit/Command/DummyCommandTest.php | 11 +- .../DependencyInjection/ConfigurationTest.php | 5 +- .../DependencyInjectionTest.php | 9 - .../FixtureOpenTelemetryExtensionTest.php | 266 ------------------ .../YamlOpenTelemetryExtensionTest.php | 16 -- .../ConsoleEventSubscriberTest.php | 12 +- .../Exporter/ConsoleExporterEndpointTest.php | 12 +- .../Exporter/OtlpExporterEndpointTest.php | 12 +- .../Exporter/OtlpExporterOptionsTest.php | 8 +- .../ConsoleLogExporterFactoryTest.php | 26 +- .../InMemoryLogExporterFactoryTest.php | 15 +- .../LogExporter/LogExporterFactoryTest.php | 116 ++++++++ .../NoopLogExporterFactoryTest.php | 15 +- .../OtlpLogExporterFactoryTest.php | 20 +- .../Log/LogExporterEndpointTest.php | 12 +- .../SimpleLogProcessorFactoryTest.php | 12 +- .../LoggerProviderFactoryTest.php | 6 +- .../NoopLoggerProviderFactoryTest.php | 2 +- .../MeterProviderFactoryTest.php | 14 +- .../ConsoleMetricExporterFactoryTest.php | 15 +- .../InMemoryMetricExporterFactoryTest.php | 15 +- .../MetricExporterFactoryTest.php | 115 ++++++++ .../NoopMetricExporterFactoryTest.php | 15 +- .../OtlpMetricExporterFactoryTest.php | 26 +- .../Metric/MetricExporterEndpointTest.php | 12 +- .../Metric/MetricExporterOptionsTest.php | 10 +- .../Trace/SamplerFactoryTest.php | 79 ++++++ .../ConsoleSpanExporterFactoryTest.php | 29 +- .../InMemorySpanExporterFactoryTest.php | 15 +- .../OtlpSpanExporterFactoryTest.php | 25 +- .../SpanExporter/SpanExporterFactoryTest.php | 116 ++++++++ .../ZipkinSpanExporterFactoryTest.php | 17 +- .../SimpleSpanProcessorFactoryTest.php | 11 +- .../Trace/TraceExporterEndpointTest.php | 12 +- .../TracerProviderFactoryTest.php | 8 +- .../Trace/ZipkinExporterEndpointTest.php | 12 +- .../Transport/GrpcTransportFactoryTest.php | 40 ++- .../OtlpHttpTransportFactoryTest.php | 42 ++- .../Transport/PsrHttpTransportFactoryTest.php | 42 ++- .../Transport/StreamTransportFactoryTest.php | 47 ++-- .../Transport/TransportFactoryTest.php | 142 ++++++++++ .../Transport/TransportParamsTest.php | 11 +- 128 files changed, 1912 insertions(+), 1535 deletions(-) delete mode 100644 src/DependencyInjection/ExporterDefinitionsFactory.php create mode 100644 src/OpenTelemetry/Log/LogExporter/AbstractLogExporterFactory.php create mode 100644 src/OpenTelemetry/Log/LogExporter/LogExporterFactory.php create mode 100644 src/OpenTelemetry/Log/LogProcessor/AbstractLogProcessorFactory.php create mode 100644 src/OpenTelemetry/Log/LoggerProvider/AbstractLoggerProviderFactory.php rename src/OpenTelemetry/Log/LoggerProvider/{LoggerProviderFactory.php => DefaultLoggerProviderFactory.php} (70%) create mode 100644 src/OpenTelemetry/Metric/ExemplarFilterEnum.php create mode 100644 src/OpenTelemetry/Metric/ExemplarFilterFactory.php create mode 100644 src/OpenTelemetry/Metric/MeterProvider/AbstractMeterProviderFactory.php rename src/OpenTelemetry/Metric/MeterProvider/{MeterProviderFactory.php => DefaultMeterProviderFactory.php} (91%) delete mode 100644 src/OpenTelemetry/Metric/MeterProvider/ExemplarFilterEnum.php create mode 100644 src/OpenTelemetry/Metric/MetricExporter/AbstractMetricExporterFactory.php create mode 100644 src/OpenTelemetry/Metric/MetricExporter/MetricExporterFactory.php create mode 100644 src/OpenTelemetry/Trace/SamplerFactory.php create mode 100644 src/OpenTelemetry/Trace/SpanExporter/AbstractSpanExporterFactory.php create mode 100644 src/OpenTelemetry/Trace/SpanExporter/SpanExporterFactory.php create mode 100644 src/OpenTelemetry/Trace/SpanProcessor/AbstractSpanProcessorFactory.php create mode 100644 src/OpenTelemetry/Trace/TraceSamplerEnum.php create mode 100644 src/OpenTelemetry/Trace/TracerProvider/AbstractTracerProviderFactory.php rename src/OpenTelemetry/Trace/TracerProvider/{TracerProviderFactory.php => DefaultTracerProviderFactory.php} (67%) delete mode 100644 src/OpenTelemetry/Trace/TracerProvider/TraceSamplerEnum.php create mode 100644 src/OpenTelemetry/Transport/AbstractTransportFactory.php create mode 100644 src/OpenTelemetry/Transport/TransportFactory.php create mode 100644 src/Resources/config/services_logs.php create mode 100644 src/Resources/config/services_metrics.php create mode 100644 src/Resources/config/services_traces.php create mode 100644 src/Resources/config/services_transports.php delete mode 100644 tests/Unit/DependencyInjection/DependencyInjectionTest.php delete mode 100644 tests/Unit/DependencyInjection/FixtureOpenTelemetryExtensionTest.php delete mode 100644 tests/Unit/DependencyInjection/YamlOpenTelemetryExtensionTest.php create mode 100644 tests/Unit/OpenTelemetry/Log/LogExporter/LogExporterFactoryTest.php create mode 100644 tests/Unit/OpenTelemetry/Metric/MetricExporter/MetricExporterFactoryTest.php create mode 100644 tests/Unit/OpenTelemetry/Trace/SamplerFactoryTest.php create mode 100644 tests/Unit/OpenTelemetry/Trace/SpanExporter/SpanExporterFactoryTest.php create mode 100644 tests/Unit/OpenTelemetry/Transport/TransportFactoryTest.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2313d4..403ca14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: - name: Run PHPStan analysis run: | ./vendor/bin/phpstan --version - ./vendor/bin/phpstan analyse --no-interaction --no-progress --ansi --format=github + ./vendor/bin/phpstan analyse --no-interaction --no-progress --ansi --error-format=github --memory-limit=256M phpunit: name: PHPUnit (PHP ${{ matrix.php }}) runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 8b5d093..fa36f64 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ composer.lock phpunit.xml .phpunit.result.cache .phpunit.cache +coverage diff --git a/composer.json b/composer.json index bfc96ad..aa7b427 100644 --- a/composer.json +++ b/composer.json @@ -27,8 +27,10 @@ "open-telemetry/api": "^1.0", "open-telemetry/context": "^1.0", "open-telemetry/opentelemetry-logger-monolog": "^1.0", + "open-telemetry/opentelemetry-propagation-server-timing": "^0.0.1", + "open-telemetry/opentelemetry-propagation-traceresponse": "^0.0.2", "open-telemetry/sdk": "^1.0", - "open-telemetry/sem-conv": "^1.23", + "open-telemetry/sem-conv": "^1.24", "open-telemetry/symfony-sdk-bundle": "^0.0.24", "php-http/discovery": "^1.19", "psr/http-factory": "^1.0", @@ -45,15 +47,15 @@ "ext-mbstring": "*", "ext-opentelemetry": "*", "ext-xdebug": "*", - "doctrine/dbal": "^3.7", + "doctrine/dbal": "^3.8", "doctrine/doctrine-bundle": "^2.11", "doctrine/orm": "^2.17", - "ergebnis/composer-normalize": "^2.41", - "friendsofphp/php-cs-fixer": "^3.41", + "ergebnis/composer-normalize": "^2.42", + "friendsofphp/php-cs-fixer": "^3.49", "guzzlehttp/promises": "^2.0", "maglnet/composer-require-checker": "^4.8", "matthiasnoback/symfony-config-test": "^5.1", - "matthiasnoback/symfony-dependency-injection-test": "^5.0", + "matthiasnoback/symfony-dependency-injection-test": "^5.1", "nyholm/symfony-bundle-test": "^3.0", "open-telemetry/exporter-otlp": "^1.0", "open-telemetry/exporter-zipkin": "^1.0", @@ -65,7 +67,7 @@ "phpstan/phpstan-phpunit": "^1.3", "phpstan/phpstan-strict-rules": "^1.5", "phpstan/phpstan-symfony": "^1.3", - "phpunit/phpunit": "^9.6", + "phpunit/phpunit": "^10.5", "pyrech/composer-changelogs": "^2.1", "roave/security-advisories": "dev-master", "symfony/cache": "^6.4 || ^7.0", @@ -117,6 +119,10 @@ }, "scripts": { "check-reqs": "@php vendor/bin/composer-require-checker check", + "coverage": [ + "@putenv XDEBUG_MODE=coverage", + "@phpunit --coverage-html=coverage" + ], "format": [ "@php-cs-fixer:fix", "@composer normalize" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0258944..a7f3485 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,15 +1,13 @@ + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" + bootstrap="vendor/autoload.php" + executionOrder="depends,defects" + beStrictAboutOutputDuringTests="true" + failOnRisky="true" + failOnWarning="false" + cacheDirectory=".phpunit.cache" +> @@ -24,14 +22,9 @@ - + src - - - - - + diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index ecfa6ab..8e77b7c 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -7,12 +7,12 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterOptions; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\LoggerProviderEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogProcessor\LogProcessorEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\ExemplarFilterEnum; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\ExemplarFilterEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\MeterProviderEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\MetricTemporalityEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanProcessor\SpanProcessorEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\TraceProviderEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\TraceSamplerEnum; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceSamplerEnum; use Monolog\Level; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; @@ -237,8 +237,7 @@ private function getTracingProvidersNode(): ArrayNodeDefinition ->values(array_map(fn (TraceSamplerEnum $enum) => $enum->value, TraceSamplerEnum::cases())) ->isRequired() ->end() - ->floatNode('ratio')->end() - ->scalarNode('parent')->cannotBeEmpty()->end() + ->floatNode('probability')->end() ->end() ->end() ->arrayNode('processors') diff --git a/src/DependencyInjection/ExporterDefinitionsFactory.php b/src/DependencyInjection/ExporterDefinitionsFactory.php deleted file mode 100644 index b273f91..0000000 --- a/src/DependencyInjection/ExporterDefinitionsFactory.php +++ /dev/null @@ -1,44 +0,0 @@ -container - ->getDefinition('open_telemetry.exporter_dsn') - ->setArguments([$dsn]); - } - - /** - * @param array $configuration - * @param string[] $extraOptions - */ - public function createExporterOptionsDefinition( - array $configuration, - string $definition = 'open_telemetry.exporter_options', - array $extraOptions = [], - ): Definition { - return $this->container - ->getDefinition($definition) - ->setArguments([array_filter( - $configuration, - fn (string $key) => in_array( - $key, - self::EXPORTER_OPTIONS + $extraOptions, - true, - ), ARRAY_FILTER_USE_KEY), - ]); - } -} diff --git a/src/DependencyInjection/OpenTelemetryExtension.php b/src/DependencyInjection/OpenTelemetryExtension.php index c367223..772b58e 100644 --- a/src/DependencyInjection/OpenTelemetryExtension.php +++ b/src/DependencyInjection/OpenTelemetryExtension.php @@ -35,9 +35,13 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container { $loader = new PhpFileLoader($container, new FileLocator(dirname(__DIR__).'/Resources/config')); $loader->load('services.php'); + $loader->load('services_transports.php'); + $loader->load('services_logs.php'); + $loader->load('services_metrics.php'); + $loader->load('services_traces.php'); $loader->load('services_tracing_instrumentation.php'); - $this->loadService($mergedConfig['service'], $container); + $this->loadServiceParams($mergedConfig['service'], $container); $this->loadInstrumentationParams($mergedConfig['instrumentation'], $container); (new OpenTelemetryTracesExtension())($mergedConfig['traces'], $container); @@ -55,7 +59,7 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container * environment: string * } $config */ - private function loadService(array $config, ContainerBuilder $container): void + private function loadServiceParams(array $config, ContainerBuilder $container): void { $container->setParameter('open_telemetry.service.namespace', $config['namespace']); $container->setParameter('open_telemetry.service.name', $config['name']); @@ -123,7 +127,7 @@ private function loadMonologHandlers(array $config, ContainerBuilder $container) ->setDefinition($handlerId, new ChildDefinition('open_telemetry.logs.monolog.handler')) ->setPublic(true) ->setArguments([ - '$loggerProvider' => new Reference(sprintf('open_telemetry.logs.providers.%s', $handler['provider'])), + '$loggerProvider' => new Reference($handler['provider']), '$level' => Level::fromName(ucfirst($handler['level'])), '$bubble' => $handler['bubble'], ]); diff --git a/src/DependencyInjection/OpenTelemetryLogsExtension.php b/src/DependencyInjection/OpenTelemetryLogsExtension.php index 81d75a8..33dcae6 100644 --- a/src/DependencyInjection/OpenTelemetryLogsExtension.php +++ b/src/DependencyInjection/OpenTelemetryLogsExtension.php @@ -2,17 +2,10 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\LogExporterEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\LoggerProviderEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\LoggerProviderFactoryInterface; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogProcessor\LogProcessorEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogProcessor\LogProcessorFactoryInterface; -use OpenTelemetry\SDK\Logs\LoggerProviderInterface; -use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; /** @@ -73,20 +66,15 @@ public function __invoke(array $config, ContainerBuilder $container): void */ private function loadLogExporter(string $name, array $options): void { - $exporterId = sprintf('open_telemetry.logs.exporters.%s', $name); - $dsn = ExporterDsn::fromString($options['dsn']); - $exporter = LogExporterEnum::from($dsn->getExporter()); - - $exporterDefinitionsFactory = new ExporterDefinitionsFactory($this->container); + $dsn = $this->container->getDefinition('open_telemetry.exporter_dsn')->setArguments([$options['dsn']]); + $exporterOptions = $this->container->getDefinition('open_telemetry.otlp_exporter_options')->setArguments([$options['options'] ?? []]); $this->container - ->setDefinition($exporterId, new ChildDefinition('open_telemetry.logs.exporter')) - ->setClass($exporter->getClass()) - ->setFactory([$exporter->getFactoryClass(), 'createExporter']) - ->setArguments([ - '$dsn' => $exporterDefinitionsFactory->createExporterDsnDefinition($options['dsn']), - '$options' => $exporterDefinitionsFactory->createExporterOptionsDefinition($options['options'] ?? []), - ]); + ->setDefinition( + sprintf('open_telemetry.logs.exporters.%s', $name), + new ChildDefinition('open_telemetry.logs.exporter_interface'), + ) + ->setArguments([$dsn, $exporterOptions]); } /** @@ -98,73 +86,18 @@ private function loadLogExporter(string $name, array $options): void */ private function loadLogProcessor(string $name, array $processor): void { - $processorId = sprintf('open_telemetry.logs.processors.%s', $name); - $options = $this->getLogProcessorOptions($processor); - $this->container - ->setDefinition($processorId, new ChildDefinition('open_telemetry.logs.processor')) - ->setClass($options['class']) - ->setFactory([$options['factory'], 'createProcessor']) + ->setDefinition( + sprintf('open_telemetry.logs.processors.%s', $name), + new ChildDefinition('open_telemetry.logs.processor_interface') + ) + ->setFactory([new Reference(sprintf('open_telemetry.logs.processor_factory.%s', $processor['type'])), 'createProcessor']) ->setArguments([ - '$processors' => $options['processors'], - '$exporter' => $options['exporter'], + array_map(fn (string $processor) => new Reference($processor), $processor['processors'] ?? []), + new Reference($processor['exporter'], ContainerInterface::NULL_ON_INVALID_REFERENCE), ]); } - /** - * @param array{ - * type: string, - * processors?: string[], - * exporter?: string - * } $processor - * - * @return array{ - * factory: class-string, - * class: class-string, - * processors: ?Reference[], - * exporter: ?Reference, - * } - */ - private function getLogProcessorOptions(array $processor): array - { - $processorEnum = LogProcessorEnum::from($processor['type']); - $options = [ - 'factory' => $processorEnum->getFactoryClass(), - 'class' => $processorEnum->getClass(), - 'processors' => [], - 'exporter' => null, - ]; - - // if (LogProcessorEnum::Batch === $processorEnum) { - // // TODO: Check batch options - // clock: OpenTelemetry\SDK\Common\Time\SystemClock - // max_queue_size: 2048 - // schedule_delay: 5000 - // export_timeout: 30000 - // max_export_batch_size: 512 - // auto_flush: true - // } - - if (LogProcessorEnum::Multi === $processorEnum) { - if (!isset($processor['processors']) || 0 === count($processor['processors'])) { - throw new \InvalidArgumentException('Processors are not set or empty'); - } - $options['processors'] = array_map( - fn (string $processor) => new Reference(sprintf('open_telemetry.logs.processors.%s', $processor)), - $processor['processors'], - ); - } - - if (LogProcessorEnum::Simple === $processorEnum) { - if (!isset($processor['exporter'])) { - throw new \InvalidArgumentException('Exporter is not set'); - } - $options['exporter'] = new Reference(sprintf('open_telemetry.logs.exporters.%s', $processor['exporter'])); - } - - return $options; - } - /** * @param array{ * type: string, @@ -173,49 +106,17 @@ private function getLogProcessorOptions(array $processor): array */ private function loadLogProvider(string $name, array $provider): void { - $providerId = sprintf('open_telemetry.logs.providers.%s', $name); - $options = $this->getLoggerProviderOptions($provider); - $this->container - ->setDefinition($providerId, new ChildDefinition('open_telemetry.logs.provider')) - ->setClass($options['class']) - ->setFactory([$options['factory'], 'createProvider']) + ->setDefinition( + sprintf('open_telemetry.logs.providers.%s', $name), + new ChildDefinition('open_telemetry.logs.provider_interface') + ) + ->setFactory([new Reference(sprintf('open_telemetry.logs.provider_factory.%s', $provider['type'])), 'createProvider']) ->setArguments([ - '$processor' => $options['processor'], + new Reference($provider['processor'] ?? ''), ]); } - /** - * @param array{ - * type: string, - * processor?: string, - * } $provider - * - * @return array{ - * factory: class-string, - * class: class-string, - * processor: ?Reference, - * } - */ - private function getLoggerProviderOptions(array $provider): array - { - $providerEnum = LoggerProviderEnum::from($provider['type']); - $options = [ - 'factory' => $providerEnum->getFactoryClass(), - 'class' => $providerEnum->getClass(), - 'processor' => null, - ]; - - if (LoggerProviderEnum::Default === $providerEnum) { - if (!isset($provider['processor'])) { - throw new \InvalidArgumentException('Processor is not set'); - } - $options['processor'] = new Reference(sprintf('open_telemetry.logs.processors.%s', $provider['processor'])); - } - - return $options; - } - /** * @param array{ * provider: string, @@ -225,15 +126,13 @@ private function getLoggerProviderOptions(array $provider): array */ private function loadLogLogger(string $name, array $logger): void { - $loggerId = sprintf('open_telemetry.logs.loggers.%s', $name); - $this->container - ->setDefinition($loggerId, new ChildDefinition('open_telemetry.logs.logger')) + ->setDefinition( + sprintf('open_telemetry.logs.loggers.%s', $name), + new ChildDefinition('open_telemetry.logs.logger'), + ) ->setPublic(true) - ->setFactory([ - new Reference(sprintf('open_telemetry.logs.providers.%s', $logger['provider'])), - 'getLogger', - ]) + ->setFactory([new Reference($logger['provider']), 'getLogger']) ->setArguments([ $logger['name'] ?? $this->container->getParameter('open_telemetry.bundle.name'), $logger['version'] ?? $this->container->getParameter('open_telemetry.bundle.version'), diff --git a/src/DependencyInjection/OpenTelemetryMetricsExtension.php b/src/DependencyInjection/OpenTelemetryMetricsExtension.php index a0f5efc..f03bafb 100644 --- a/src/DependencyInjection/OpenTelemetryMetricsExtension.php +++ b/src/DependencyInjection/OpenTelemetryMetricsExtension.php @@ -2,13 +2,8 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\ExemplarFilterEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\MeterProviderEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\MeterProviderFactoryInterface; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\MetricExporterEnum; -use OpenTelemetry\SDK\Metrics\MeterProviderInterface; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\ExemplarFilterEnum; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -68,24 +63,15 @@ public function __invoke(array $config, ContainerBuilder $container): void */ private function loadMetricExporter(string $name, array $options): void { - $exporterId = sprintf('open_telemetry.metrics.exporters.%s', $name); - $dsn = ExporterDsn::fromString($options['dsn']); - $exporter = MetricExporterEnum::from($dsn->getExporter()); - - $exporterDefinitionsFactory = new ExporterDefinitionsFactory($this->container); + $dsn = $this->container->getDefinition('open_telemetry.exporter_dsn')->setArguments([$options['dsn']]); + $exporterOptions = $this->container->getDefinition('open_telemetry.metric_exporter_options')->setArguments([$options['options'] ?? []]); $this->container - ->setDefinition($exporterId, new ChildDefinition('open_telemetry.metrics.exporter')) - ->setClass($exporter->getClass()) - ->setFactory([$exporter->getFactoryClass(), 'createExporter']) - ->setArguments([ - '$dsn' => $exporterDefinitionsFactory->createExporterDsnDefinition($options['dsn']), - '$options' => $exporterDefinitionsFactory->createExporterOptionsDefinition( - $options['options'] ?? [], - 'open_telemetry.metric_exporter_options', - ExporterDefinitionsFactory::METRIC_EXPORTER_OPTIONS, - ), - ]); + ->setDefinition( + sprintf('open_telemetry.metrics.exporters.%s', $name), + new ChildDefinition('open_telemetry.metrics.exporter_interface'), + ) + ->setArguments([$dsn, $exporterOptions]); } /** @@ -97,60 +83,20 @@ private function loadMetricExporter(string $name, array $options): void */ private function loadMetricProvider(string $name, array $provider): void { - $providerId = sprintf('open_telemetry.metrics.providers.%s', $name); - $options = $this->getMetricProviderOptions($provider); + $filter = $this->container->getDefinition('open_telemetry.metrics.exemplar_factory')->setArguments([$provider['filter'] ?? ExemplarFilterEnum::All->value]); $this->container - ->setDefinition($providerId, new ChildDefinition('open_telemetry.metrics.provider')) - ->setClass($options['class']) - ->setFactory([$options['factory'], 'createProvider']) + ->setDefinition( + sprintf('open_telemetry.metrics.providers.%s', $name), + new ChildDefinition('open_telemetry.metrics.provider_interface'), + ) + ->setFactory([new Reference(sprintf('open_telemetry.metrics.provider_factory.%s', $provider['type'])), 'createProvider']) ->setArguments([ - '$exporter' => $options['exporter'], - '$filter' => $options['filter'], + new Reference($provider['exporter'] ?? '', ContainerBuilder::NULL_ON_INVALID_REFERENCE), + $filter, ]); } - /** - * @param array{ - * type: string, - * exporter?: string, - * filter?: string, - * } $provider - * - * @return array{ - * factory: class-string, - * class: class-string, - * exporter: ?Reference, - * filter: ?Reference, - * } - */ - private function getMetricProviderOptions(array $provider): array - { - $providerEnum = MeterProviderEnum::from($provider['type']); - $options = [ - 'factory' => $providerEnum->getFactoryClass(), - 'class' => $providerEnum->getClass(), - 'exporter' => null, - 'filter' => null, - ]; - - if (MeterProviderEnum::Default === $providerEnum) { - if (!isset($provider['exporter'])) { - throw new \InvalidArgumentException('Exporter is not set'); - } - $options['exporter'] = new Reference(sprintf('open_telemetry.metrics.exporters.%s', $provider['exporter'])); - } - - $filter = isset($provider['filter']) ? ExemplarFilterEnum::from($provider['filter']) : ExemplarFilterEnum::All; - $options['filter'] = match ($filter) { - ExemplarFilterEnum::WithSampledTrace => new Reference('open_telemetry.metrics.exemplar_filters.with_sampled_trace'), - ExemplarFilterEnum::All => new Reference('open_telemetry.metrics.exemplar_filters.all'), - ExemplarFilterEnum::None => new Reference('open_telemetry.metrics.exemplar_filters.none'), - }; - - return $options; - } - /** * @param array{ * provider: string, @@ -160,15 +106,13 @@ private function getMetricProviderOptions(array $provider): array */ private function loadMetricMeter(string $name, array $meter): void { - $meterId = sprintf('open_telemetry.metrics.meters.%s', $name); - $this->container - ->setDefinition($meterId, new ChildDefinition('open_telemetry.metrics.meter')) + ->setDefinition( + sprintf('open_telemetry.metrics.meters.%s', $name), + new ChildDefinition('open_telemetry.metrics.meter') + ) ->setPublic(true) - ->setFactory([ - new Reference(sprintf('open_telemetry.metrics.providers.%s', $meter['provider'])), - 'getMeter', - ]) + ->setFactory([new Reference($meter['provider']), 'getMeter']) ->setArguments([ $meter['name'] ?? $this->container->getParameter('open_telemetry.bundle.name'), $meter['version'] ?? $this->container->getParameter('open_telemetry.bundle.version'), diff --git a/src/DependencyInjection/OpenTelemetryTracesExtension.php b/src/DependencyInjection/OpenTelemetryTracesExtension.php index c598abe..dbdb76b 100644 --- a/src/DependencyInjection/OpenTelemetryTracesExtension.php +++ b/src/DependencyInjection/OpenTelemetryTracesExtension.php @@ -2,19 +2,11 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\TraceExporterEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanProcessor\SpanProcessorEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanProcessor\SpanProcessorFactoryInterface; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\TraceProviderEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\TracerProviderFactoryInterface; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\TraceSamplerEnum; -use OpenTelemetry\SDK\Trace\SpanProcessorInterface; -use OpenTelemetry\SDK\Trace\TracerProviderInterface; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceSamplerEnum; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; /** @@ -76,20 +68,15 @@ public function __invoke(array $config, ContainerBuilder $container): void */ private function loadTraceExporter(string $name, array $options): void { - $exporterId = sprintf('open_telemetry.traces.exporters.%s', $name); - $dsn = ExporterDsn::fromString($options['dsn']); - $exporter = TraceExporterEnum::from($dsn->getExporter()); - - $exporterDefinitionsFactory = new ExporterDefinitionsFactory($this->container); + $dsn = $this->container->getDefinition('open_telemetry.exporter_dsn')->setArguments([$options['dsn']]); + $exporterOptions = $this->container->getDefinition('open_telemetry.otlp_exporter_options')->setArguments([$options['options'] ?? []]); $this->container - ->setDefinition($exporterId, new ChildDefinition('open_telemetry.traces.exporter')) - ->setClass($exporter->getClass()) - ->setFactory([$exporter->getFactoryClass(), 'createExporter']) - ->setArguments([ - '$dsn' => $exporterDefinitionsFactory->createExporterDsnDefinition($options['dsn']), - '$options' => $exporterDefinitionsFactory->createExporterOptionsDefinition($options['options'] ?? []), - ]); + ->setDefinition( + sprintf('open_telemetry.traces.exporters.%s', $name), + new ChildDefinition('open_telemetry.traces.exporter_interface') + ) + ->setArguments([$dsn, $exporterOptions]); } /** @@ -101,166 +88,44 @@ private function loadTraceExporter(string $name, array $options): void */ private function loadTraceProcessor(string $name, array $processor): void { - $processorId = sprintf('open_telemetry.traces.processors.%s', $name); - $options = $this->getTraceProcessorOptions($processor); - $this->container - ->setDefinition($processorId, new ChildDefinition('open_telemetry.traces.processor')) - ->setClass($options['class']) - ->setFactory([$options['factory'], 'createProcessor']) + ->setDefinition( + sprintf('open_telemetry.traces.processors.%s', $name), + new ChildDefinition('open_telemetry.traces.processor_interface'), + ) + ->setFactory([new Reference(sprintf('open_telemetry.traces.processor_factory.%s', $processor['type'])), 'createProcessor']) ->setArguments([ - '$processors' => $options['processors'], - '$exporter' => $options['exporter'], + array_map(fn (string $processor) => new Reference($processor), $processor['processors'] ?? []), + new Reference($processor['exporter'], ContainerInterface::NULL_ON_INVALID_REFERENCE), ]); } /** * @param array{ * type: string, - * processors?: string[], - * exporter?: string - * } $processor - * - * @return array{ - * factory: class-string, - * class: class-string, - * processors: ?Reference[], - * exporter: ?Reference, - * } - */ - private function getTraceProcessorOptions(array $processor): array - { - $processorEnum = SpanProcessorEnum::from($processor['type']); - $options = [ - 'factory' => $processorEnum->getFactoryClass(), - 'class' => $processorEnum->getClass(), - 'processors' => [], - 'exporter' => null, - ]; - - // if (SpanProcessorEnum::Batch === $options['type']) { - // // TODO: Check batch options - // clock: OpenTelemetry\SDK\Common\Time\SystemClock - // max_queue_size: 2048 - // schedule_delay: 5000 - // export_timeout: 30000 - // max_export_batch_size: 512 - // auto_flush: true - // } - - if (SpanProcessorEnum::Multi === $processorEnum) { - if (!isset($processor['processors']) || 0 === count($processor['processors'])) { - throw new \InvalidArgumentException('Processors are not set or empty'); - } - $options['processors'] = array_map( - fn (string $processor) => new Reference(sprintf('open_telemetry.traces.processors.%s', $processor)), - $processor['processors'], - ); - } - - if (SpanProcessorEnum::Simple === $processorEnum) { - if (!isset($processor['exporter'])) { - throw new \InvalidArgumentException('Exporter is not set'); - } - $options['exporter'] = new Reference(sprintf('open_telemetry.traces.exporters.%s', $processor['exporter'])); - } - - return $options; - } - - /** - * @param array{ - * type: string, - * sampler?: array{type: string, ratio?: float, parent?: string}, + * sampler?: array{type: string, probability?: float}, * processors?: string[] * } $provider */ private function loadTraceProvider(string $name, array $provider): void { - $providerId = sprintf('open_telemetry.traces.providers.%s', $name); - $options = $this->getTraceProviderOptions($provider); - - $sampler = isset($provider['sampler']) ? $this->getTraceSamplerDefinition($provider['sampler']) : $this->container->getDefinition('open_telemetry.traces.samplers.always_on'); + $sampler = $this->container->getDefinition('open_telemetry.traces.sampler_factory')->setArguments([ + $provider['sampler']['type'] ?? TraceSamplerEnum::AlwaysOn->value, + $provider['sampler']['probability'] ?? null, + ]); $this->container - ->setDefinition($providerId, new ChildDefinition('open_telemetry.traces.provider')) - ->setClass($options['class']) - ->setFactory([$options['factory'], 'createProvider']) + ->setDefinition( + sprintf('open_telemetry.traces.providers.%s', $name), + new ChildDefinition('open_telemetry.traces.provider_interface'), + ) + ->setFactory([new Reference(sprintf('open_telemetry.traces.provider_factory.%s', $provider['type'])), 'createProvider']) ->setArguments([ - '$sampler' => $sampler, - '$processors' => $options['processors'], + $sampler, + array_map(fn (string $processor) => new Reference($processor), $provider['processors'] ?? []), ]); } - /** - * @param array{type: string, ratio?: float, parent?: string} $sampler - */ - private function getTraceSamplerDefinition(array $sampler): Definition - { - $type = TraceSamplerEnum::from($sampler['type']); - - if (TraceSamplerEnum::TraceIdRatio === $type && !isset($sampler['ratio'])) { - throw new \InvalidArgumentException(sprintf("Sampler of type '%s' requires a ratio parameter.", $type->value)); - } - - if (TraceSamplerEnum::ParentBased === $type) { - if (!isset($sampler['parent'])) { - throw new \InvalidArgumentException(sprintf("Sampler of type '%s' requires a parent parameter.", $type->value)); - } - $parentSampler = TraceSamplerEnum::tryFrom($sampler['parent']); - if (!in_array($parentSampler, [TraceSamplerEnum::AlwaysOn, TraceSamplerEnum::AlwaysOff], true)) { - throw new \InvalidArgumentException(sprintf("Unsupported '%s' parent sampler", $parentSampler->value)); - } - } - - return match ($type) { - TraceSamplerEnum::AlwaysOn => $this->container->getDefinition('open_telemetry.traces.samplers.always_on'), - TraceSamplerEnum::AlwaysOff => $this->container->getDefinition('open_telemetry.traces.samplers.always_off'), - TraceSamplerEnum::TraceIdRatio => $this->container - ->getDefinition('open_telemetry.traces.samplers.trace_id_ratio_based') - ->setArgument('$probability', $sampler['ratio']), - TraceSamplerEnum::ParentBased => $this->container - ->getDefinition('open_telemetry.traces.samplers.parent_based') - ->setArgument('$root', $this->getTraceSamplerDefinition([ - 'type' => $sampler['parent'], - ])), - }; - } - - /** - * @param array{ - * type: string, - * processors?: string[] - * } $provider - * - * @return array{ - * factory: class-string, - * class: class-string, - * processors: ?Reference[], - * } - */ - private function getTraceProviderOptions(array $provider): array - { - $providerEnum = TraceProviderEnum::from($provider['type']); - $options = [ - 'factory' => $providerEnum->getFactoryClass(), - 'class' => $providerEnum->getClass(), - 'processors' => [], - ]; - - if (TraceProviderEnum::Default === $providerEnum) { - if (!isset($provider['processors']) || 0 === count($provider['processors'])) { - throw new \InvalidArgumentException('Processors are not set or empty'); - } - $options['processors'] = array_map( - fn (string $processor) => new Reference(sprintf('open_telemetry.traces.processors.%s', $processor)), - $provider['processors'] - ); - } - - return $options; - } - /** * @param array{ * name?: string, @@ -270,15 +135,13 @@ private function getTraceProviderOptions(array $provider): array */ private function loadTraceTracer(string $name, array $tracer): void { - $tracerId = sprintf('open_telemetry.traces.tracers.%s', $name); - $this->container - ->setDefinition($tracerId, new ChildDefinition('open_telemetry.traces.tracer')) + ->setDefinition( + sprintf('open_telemetry.traces.tracers.%s', $name), + new ChildDefinition('open_telemetry.traces.tracer'), + ) ->setPublic(true) - ->setFactory([ - new Reference(sprintf('open_telemetry.traces.providers.%s', $tracer['provider'])), - 'getTracer', - ]) + ->setFactory([new Reference($tracer['provider']), 'getTracer']) ->setArguments([ $tracer['name'] ?? $this->container->getParameter('open_telemetry.bundle.name'), $tracer['version'] ?? $this->container->getParameter('open_telemetry.bundle.version'), diff --git a/src/Instrumentation/Symfony/Cache/TagAwareTraceableCacheAdapter.php b/src/Instrumentation/Symfony/Cache/TagAwareTraceableCacheAdapter.php index 275725b..d21cf8a 100644 --- a/src/Instrumentation/Symfony/Cache/TagAwareTraceableCacheAdapter.php +++ b/src/Instrumentation/Symfony/Cache/TagAwareTraceableCacheAdapter.php @@ -22,7 +22,7 @@ public function __construct( $this->adapter = $adapter; } - public function get(string $key, callable $callback, float $beta = null, array &$metadata = null): mixed + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed { return $this->tracer->traceFunction( 'cache.get', diff --git a/src/Instrumentation/Symfony/Cache/TraceableCacheAdapter.php b/src/Instrumentation/Symfony/Cache/TraceableCacheAdapter.php index 87d3dbc..2529d44 100644 --- a/src/Instrumentation/Symfony/Cache/TraceableCacheAdapter.php +++ b/src/Instrumentation/Symfony/Cache/TraceableCacheAdapter.php @@ -21,7 +21,7 @@ public function __construct( $this->adapter = $adapter; } - public function get(string $key, callable $callback, float $beta = null, array &$metadata = null): mixed + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed { return $this->tracer->traceFunction( 'cache.get', diff --git a/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php b/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php index eb9e1ee..060e148 100644 --- a/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php +++ b/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php @@ -61,7 +61,7 @@ public function request(string $method, string $url, array $options = []): Respo } } - public function stream(iterable|ResponseInterface $responses, float $timeout = null): ResponseStreamInterface + public function stream(iterable|ResponseInterface $responses, ?float $timeout = null): ResponseStreamInterface { $scope = Context::storage()->scope(); if (null === $scope) { diff --git a/src/Instrumentation/Symfony/HttpClient/TraceableResponse.php b/src/Instrumentation/Symfony/HttpClient/TraceableResponse.php index 59bdea1..8052f9d 100644 --- a/src/Instrumentation/Symfony/HttpClient/TraceableResponse.php +++ b/src/Instrumentation/Symfony/HttpClient/TraceableResponse.php @@ -78,7 +78,7 @@ public function cancel(): void $this->endSpan(); } - public function getInfo(string $type = null): mixed + public function getInfo(?string $type = null): mixed { return $this->response->getInfo($type); } diff --git a/src/Instrumentation/Symfony/Mailer/TraceableMailer.php b/src/Instrumentation/Symfony/Mailer/TraceableMailer.php index 79afb7a..8d9ce66 100644 --- a/src/Instrumentation/Symfony/Mailer/TraceableMailer.php +++ b/src/Instrumentation/Symfony/Mailer/TraceableMailer.php @@ -22,7 +22,7 @@ public function __construct( ) { } - public function send(RawMessage $message, Envelope $envelope = null): void + public function send(RawMessage $message, ?Envelope $envelope = null): void { $scope = Context::storage()->scope(); if (null === $scope) { diff --git a/src/Instrumentation/Symfony/Mailer/TraceableMailerTransport.php b/src/Instrumentation/Symfony/Mailer/TraceableMailerTransport.php index 2dbb4f9..a5db5c8 100644 --- a/src/Instrumentation/Symfony/Mailer/TraceableMailerTransport.php +++ b/src/Instrumentation/Symfony/Mailer/TraceableMailerTransport.php @@ -29,7 +29,7 @@ public function __toString() return (string) $this->transport; } - public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage { $scope = Context::storage()->scope(); if (null === $scope) { diff --git a/src/OpenTelemetry/Exporter/ExporterDsn.php b/src/OpenTelemetry/Exporter/ExporterDsn.php index 47c1b58..412c426 100644 --- a/src/OpenTelemetry/Exporter/ExporterDsn.php +++ b/src/OpenTelemetry/Exporter/ExporterDsn.php @@ -55,7 +55,7 @@ public function getPath(): ?string return $this->uri->path()->isEmpty() ? null : $this->uri->path()->toString(); } - public function getPort(int $default = null): ?int + public function getPort(?int $default = null): ?int { return $this->uri->port() ?? $default; } diff --git a/src/OpenTelemetry/Exporter/ExporterFactoryInterface.php b/src/OpenTelemetry/Exporter/ExporterFactoryInterface.php index 3406995..f5805be 100644 --- a/src/OpenTelemetry/Exporter/ExporterFactoryInterface.php +++ b/src/OpenTelemetry/Exporter/ExporterFactoryInterface.php @@ -7,8 +7,10 @@ */ interface ExporterFactoryInterface { + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool; + /** * @return T */ - public static function createExporter(ExporterDsn $dsn, ExporterOptionsInterface $options); + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options); } diff --git a/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php b/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php index e8f1c4a..74e79d1 100644 --- a/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php +++ b/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php @@ -17,7 +17,7 @@ final class OtlpExporterEndpoint implements ExporterEndpointInterface private function __construct( private readonly ExporterDsn $dsn, - UriFactoryInterface $uriFactory = null, + ?UriFactoryInterface $uriFactory = null, ) { if ('otlp' !== $this->dsn->getExporter()) { throw new \RuntimeException('Provided DSN exporter is not compatible with this endpoint.'); diff --git a/src/OpenTelemetry/Log/LogExporter/AbstractLogExporterFactory.php b/src/OpenTelemetry/Log/LogExporter/AbstractLogExporterFactory.php new file mode 100644 index 0000000..ff9a82e --- /dev/null +++ b/src/OpenTelemetry/Log/LogExporter/AbstractLogExporterFactory.php @@ -0,0 +1,15 @@ +getExporter()); + } - return new ConsoleExporter($transportFactory->createTransport()); + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): ConsoleExporter + { + return new ConsoleExporter($this->transportFactory->createTransport(LogExporterEndpoint::fromDsn($dsn), $options)); } } diff --git a/src/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactory.php b/src/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactory.php index f2b9041..f99a245 100644 --- a/src/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactory.php +++ b/src/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactory.php @@ -6,9 +6,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use OpenTelemetry\SDK\Logs\Exporter\InMemoryExporter; -final class InMemoryLogExporterFactory implements LogExporterFactoryInterface +final class InMemoryLogExporterFactory extends AbstractLogExporterFactory { - public static function createExporter(ExporterDsn $dsn = null, ExporterOptionsInterface $options = null): InMemoryExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + return LogExporterEnum::InMemory === LogExporterEnum::tryFrom($dsn->getExporter()); + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): InMemoryExporter { return new InMemoryExporter(); } diff --git a/src/OpenTelemetry/Log/LogExporter/LogExporterEnum.php b/src/OpenTelemetry/Log/LogExporter/LogExporterEnum.php index deb0c50..1cdd87b 100644 --- a/src/OpenTelemetry/Log/LogExporter/LogExporterEnum.php +++ b/src/OpenTelemetry/Log/LogExporter/LogExporterEnum.php @@ -3,10 +3,6 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; -use OpenTelemetry\Contrib\Otlp\LogsExporter; -use OpenTelemetry\SDK\Logs\Exporter\ConsoleExporter; -use OpenTelemetry\SDK\Logs\Exporter\InMemoryExporter; -use OpenTelemetry\SDK\Logs\Exporter\NoopExporter; enum LogExporterEnum: string { @@ -15,26 +11,6 @@ enum LogExporterEnum: string case Noop = 'noop'; case Otlp = 'otlp'; - public function getFactoryClass(): string - { - return match ($this) { - self::Console => ConsoleLogExporterFactory::class, - self::InMemory => InMemoryLogExporterFactory::class, - self::Otlp => OtlpLogExporterFactory::class, - self::Noop => NoopLogExporterFactory::class, - }; - } - - public function getClass(): string - { - return match ($this) { - self::Console => ConsoleExporter::class, - self::InMemory => InMemoryExporter::class, - self::Otlp => LogsExporter::class, - self::Noop => NoopExporter::class, - }; - } - public static function fromDsn(ExporterDsn $dsn): self { $exporter = self::tryFrom($dsn->getExporter()); diff --git a/src/OpenTelemetry/Log/LogExporter/LogExporterFactory.php b/src/OpenTelemetry/Log/LogExporter/LogExporterFactory.php new file mode 100644 index 0000000..1885efb --- /dev/null +++ b/src/OpenTelemetry/Log/LogExporter/LogExporterFactory.php @@ -0,0 +1,39 @@ + $factories + */ + public function __construct(private readonly iterable $factories) + { + } + + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn, $options)) { + return true; + } + } + + return false; + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): LogRecordExporterInterface + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn, $options)) { + return $factory->createExporter($dsn, $options); + } + } + + throw new \InvalidArgumentException('No log exporter supports the given DSN.'); + } +} diff --git a/src/OpenTelemetry/Log/LogExporter/NoopLogExporterFactory.php b/src/OpenTelemetry/Log/LogExporter/NoopLogExporterFactory.php index b9a2edb..cb67f0b 100644 --- a/src/OpenTelemetry/Log/LogExporter/NoopLogExporterFactory.php +++ b/src/OpenTelemetry/Log/LogExporter/NoopLogExporterFactory.php @@ -6,9 +6,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use OpenTelemetry\SDK\Logs\Exporter\NoopExporter; -final class NoopLogExporterFactory implements LogExporterFactoryInterface +final class NoopLogExporterFactory extends AbstractLogExporterFactory { - public static function createExporter(ExporterDsn $dsn = null, ExporterOptionsInterface $options = null): NoopExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + return LogExporterEnum::Noop === LogExporterEnum::tryFrom($dsn->getExporter()); + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): NoopExporter { return new NoopExporter(); } diff --git a/src/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactory.php b/src/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactory.php index 5191ff4..7dea234 100644 --- a/src/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactory.php +++ b/src/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactory.php @@ -5,31 +5,22 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporterEndpoint; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactoryInterface; use OpenTelemetry\Contrib\Otlp\LogsExporter; -final class OtlpLogExporterFactory implements LogExporterFactoryInterface +final class OtlpLogExporterFactory extends AbstractLogExporterFactory { - public static function createExporter(ExporterDsn $dsn, ExporterOptionsInterface $options): LogsExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + return LogExporterEnum::Otlp === LogExporterEnum::tryFrom($dsn->getExporter()); + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): LogsExporter { $exporter = LogExporterEnum::fromDsn($dsn); if (LogExporterEnum::Otlp !== $exporter) { throw new \InvalidArgumentException('DSN exporter must be of type Otlp.'); } - $transport = TransportEnum::fromDsn($dsn); - if (null === $transport) { - throw new \InvalidArgumentException('Could not find a transport from DSN for this exporter factory.'); - } - - /** @var TransportFactoryInterface $transportFactory */ - $transportFactory = call_user_func( - [$transport->getFactoryClass(), 'fromExporter'], - LogExporterEndpoint::fromDsn($dsn), - $options, - ); - - return new LogsExporter($transportFactory->createTransport()); + return new LogsExporter($this->transportFactory->createTransport(LogExporterEndpoint::fromDsn($dsn), $options)); } } diff --git a/src/OpenTelemetry/Log/LogProcessor/AbstractLogProcessorFactory.php b/src/OpenTelemetry/Log/LogProcessor/AbstractLogProcessorFactory.php new file mode 100644 index 0000000..c54faad --- /dev/null +++ b/src/OpenTelemetry/Log/LogProcessor/AbstractLogProcessorFactory.php @@ -0,0 +1,13 @@ += count($processors)) { throw new \InvalidArgumentException('Processors should not be empty'); diff --git a/src/OpenTelemetry/Log/LogProcessor/NoopLogProcessorFactory.php b/src/OpenTelemetry/Log/LogProcessor/NoopLogProcessorFactory.php index 8b59aba..fa53466 100644 --- a/src/OpenTelemetry/Log/LogProcessor/NoopLogProcessorFactory.php +++ b/src/OpenTelemetry/Log/LogProcessor/NoopLogProcessorFactory.php @@ -6,11 +6,11 @@ use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface; use OpenTelemetry\SDK\Logs\Processor\NoopLogRecordProcessor; -final class NoopLogProcessorFactory implements LogProcessorFactoryInterface +final class NoopLogProcessorFactory extends AbstractLogProcessorFactory { public static function createProcessor( array $processors = [], - LogRecordExporterInterface $exporter = null, + ?LogRecordExporterInterface $exporter = null, ): LogRecordProcessorInterface { return new NoopLogRecordProcessor(); } diff --git a/src/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactory.php b/src/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactory.php index b418290..8070477 100644 --- a/src/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactory.php +++ b/src/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactory.php @@ -6,11 +6,11 @@ use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface; use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor; -final class SimpleLogProcessorFactory implements LogProcessorFactoryInterface +final class SimpleLogProcessorFactory extends AbstractLogProcessorFactory { public static function createProcessor( array $processors = [], - LogRecordExporterInterface $exporter = null, + ?LogRecordExporterInterface $exporter = null, ): LogRecordProcessorInterface { if (null === $exporter) { throw new \InvalidArgumentException('Exporter is null'); diff --git a/src/OpenTelemetry/Log/LoggerProvider/AbstractLoggerProviderFactory.php b/src/OpenTelemetry/Log/LoggerProvider/AbstractLoggerProviderFactory.php new file mode 100644 index 0000000..18f2ef0 --- /dev/null +++ b/src/OpenTelemetry/Log/LoggerProvider/AbstractLoggerProviderFactory.php @@ -0,0 +1,12 @@ +build()->getAttributeFactory()); diff --git a/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderEnum.php b/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderEnum.php index 7330829..fe02ed0 100644 --- a/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderEnum.php +++ b/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderEnum.php @@ -17,7 +17,7 @@ enum LoggerProviderEnum: string public function getFactoryClass(): string { return match ($this) { - self::Default => LoggerProviderFactory::class, + self::Default => DefaultLoggerProviderFactory::class, self::Noop => NoopLoggerProviderFactory::class, }; } diff --git a/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryInterface.php b/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryInterface.php index 3e4f275..5a0aef8 100644 --- a/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryInterface.php +++ b/src/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryInterface.php @@ -2,10 +2,10 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider; -use OpenTelemetry\API\Logs\LoggerProviderInterface; +use OpenTelemetry\SDK\Logs\LoggerProviderInterface; use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface; interface LoggerProviderFactoryInterface { - public static function createProvider(LogRecordProcessorInterface $processor): LoggerProviderInterface; + public function createProvider(LogRecordProcessorInterface $processor): LoggerProviderInterface; } diff --git a/src/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactory.php b/src/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactory.php index 29070f4..5f565ab 100644 --- a/src/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactory.php +++ b/src/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactory.php @@ -2,13 +2,13 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider; -use OpenTelemetry\API\Logs\LoggerProviderInterface; +use OpenTelemetry\SDK\Logs\LoggerProviderInterface; use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface; use OpenTelemetry\SDK\Logs\NoopLoggerProvider; -final class NoopLoggerProviderFactory implements LoggerProviderFactoryInterface +final class NoopLoggerProviderFactory extends AbstractLoggerProviderFactory { - public static function createProvider(LogRecordProcessorInterface $processor): LoggerProviderInterface + public function createProvider(LogRecordProcessorInterface $processor): LoggerProviderInterface { return new NoopLoggerProvider(); } diff --git a/src/OpenTelemetry/Metric/ExemplarFilterEnum.php b/src/OpenTelemetry/Metric/ExemplarFilterEnum.php new file mode 100644 index 0000000..3f4b9bf --- /dev/null +++ b/src/OpenTelemetry/Metric/ExemplarFilterEnum.php @@ -0,0 +1,10 @@ + new AllExemplarFilter(), + ExemplarFilterEnum::None => new NoneExemplarFilter(), + ExemplarFilterEnum::WithSampledTrace => new WithSampledTraceExemplarFilter(), + default => throw new \InvalidArgumentException(sprintf('Unknown exemplar filter: %s', $name)), + }; + } +} diff --git a/src/OpenTelemetry/Metric/MeterProvider/AbstractMeterProviderFactory.php b/src/OpenTelemetry/Metric/MeterProvider/AbstractMeterProviderFactory.php new file mode 100644 index 0000000..405c937 --- /dev/null +++ b/src/OpenTelemetry/Metric/MeterProvider/AbstractMeterProviderFactory.php @@ -0,0 +1,12 @@ + - */ - public function getClass(): string - { - return match ($this) { - self::All => AllExemplarFilter::class, - self::None => NoneExemplarFilter::class, - self::WithSampledTrace => WithSampledTraceExemplarFilter::class, - }; - } -} diff --git a/src/OpenTelemetry/Metric/MeterProvider/MeterProviderEnum.php b/src/OpenTelemetry/Metric/MeterProvider/MeterProviderEnum.php index 721cdcf..16486db 100644 --- a/src/OpenTelemetry/Metric/MeterProvider/MeterProviderEnum.php +++ b/src/OpenTelemetry/Metric/MeterProvider/MeterProviderEnum.php @@ -17,7 +17,7 @@ enum MeterProviderEnum: string public function getFactoryClass(): string { return match ($this) { - self::Default => MeterProviderFactory::class, + self::Default => DefaultMeterProviderFactory::class, self::Noop => NoopMeterProviderFactory::class, }; } diff --git a/src/OpenTelemetry/Metric/MeterProvider/NoopMeterProviderFactory.php b/src/OpenTelemetry/Metric/MeterProvider/NoopMeterProviderFactory.php index a9321ca..c82e13c 100644 --- a/src/OpenTelemetry/Metric/MeterProvider/NoopMeterProviderFactory.php +++ b/src/OpenTelemetry/Metric/MeterProvider/NoopMeterProviderFactory.php @@ -7,9 +7,9 @@ use OpenTelemetry\SDK\Metrics\MetricExporterInterface; use OpenTelemetry\SDK\Metrics\NoopMeterProvider; -final class NoopMeterProviderFactory implements MeterProviderFactoryInterface +final class NoopMeterProviderFactory extends AbstractMeterProviderFactory { - public static function createProvider(MetricExporterInterface $exporter = null, ExemplarFilterInterface $filter = null): MeterProviderInterface + public static function createProvider(?MetricExporterInterface $exporter = null, ?ExemplarFilterInterface $filter = null): MeterProviderInterface { return new NoopMeterProvider(); } diff --git a/src/OpenTelemetry/Metric/MetricExporter/AbstractMetricExporterFactory.php b/src/OpenTelemetry/Metric/MetricExporter/AbstractMetricExporterFactory.php new file mode 100644 index 0000000..37929e4 --- /dev/null +++ b/src/OpenTelemetry/Metric/MetricExporter/AbstractMetricExporterFactory.php @@ -0,0 +1,15 @@ +getExporter()); + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): ConsoleMetricExporter { assert($options instanceof MetricExporterOptions); diff --git a/src/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactory.php b/src/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactory.php index c4dc513..cf5b7d2 100644 --- a/src/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactory.php +++ b/src/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactory.php @@ -7,9 +7,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; use OpenTelemetry\SDK\Metrics\MetricExporter\InMemoryExporter; -final class InMemoryMetricExporterFactory implements MetricExporterFactoryInterface +final class InMemoryMetricExporterFactory extends AbstractMetricExporterFactory { - public static function createExporter(ExporterDsn $dsn, ExporterOptionsInterface $options): InMemoryExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + return MetricExporterEnum::InMemory === MetricExporterEnum::tryFrom($dsn->getExporter()); + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): InMemoryExporter { assert($options instanceof MetricExporterOptions); diff --git a/src/OpenTelemetry/Metric/MetricExporter/MetricExporterEnum.php b/src/OpenTelemetry/Metric/MetricExporter/MetricExporterEnum.php index 0137686..567db75 100644 --- a/src/OpenTelemetry/Metric/MetricExporter/MetricExporterEnum.php +++ b/src/OpenTelemetry/Metric/MetricExporter/MetricExporterEnum.php @@ -3,10 +3,6 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; -use OpenTelemetry\Contrib\Otlp\MetricExporter; -use OpenTelemetry\SDK\Metrics\MetricExporter\ConsoleMetricExporter; -use OpenTelemetry\SDK\Metrics\MetricExporter\InMemoryExporter; -use OpenTelemetry\SDK\Metrics\MetricExporter\NoopMetricExporter; enum MetricExporterEnum: string { @@ -16,26 +12,6 @@ enum MetricExporterEnum: string case Console = 'console'; case InMemory = 'in-memory'; - public function getFactoryClass(): string - { - return match ($this) { - self::Console => ConsoleMetricExporterFactory::class, - self::InMemory => InMemoryMetricExporterFactory::class, - self::Noop => NoopMetricExporterFactory::class, - self::Otlp => OtlpMetricExporterFactory::class, - }; - } - - public function getClass(): string - { - return match ($this) { - self::Console => ConsoleMetricExporter::class, - self::InMemory => InMemoryExporter::class, - self::Otlp => MetricExporter::class, - self::Noop => NoopMetricExporter::class, - }; - } - public static function fromDsn(ExporterDsn $dsn): self { $exporter = self::tryFrom($dsn->getExporter()); diff --git a/src/OpenTelemetry/Metric/MetricExporter/MetricExporterFactory.php b/src/OpenTelemetry/Metric/MetricExporter/MetricExporterFactory.php new file mode 100644 index 0000000..602ec92 --- /dev/null +++ b/src/OpenTelemetry/Metric/MetricExporter/MetricExporterFactory.php @@ -0,0 +1,39 @@ + $factories + */ + public function __construct(private readonly iterable $factories) + { + } + + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn, $options)) { + return true; + } + } + + return false; + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): MetricExporterInterface + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn, $options)) { + return $factory->createExporter($dsn, $options); + } + } + + throw new \InvalidArgumentException('No metric exporter supports the given DSN.'); + } +} diff --git a/src/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactory.php b/src/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactory.php index 53f6ab5..e4f016c 100644 --- a/src/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactory.php +++ b/src/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactory.php @@ -6,9 +6,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use OpenTelemetry\SDK\Metrics\MetricExporter\NoopMetricExporter; -final class NoopMetricExporterFactory implements MetricExporterFactoryInterface +final class NoopMetricExporterFactory extends AbstractMetricExporterFactory { - public static function createExporter(ExporterDsn $dsn = null, ExporterOptionsInterface $options = null): NoopMetricExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + return MetricExporterEnum::Noop === MetricExporterEnum::tryFrom($dsn->getExporter()); + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): NoopMetricExporter { return new NoopMetricExporter(); } diff --git a/src/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactory.php b/src/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactory.php index 0b52770..ee61444 100644 --- a/src/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactory.php +++ b/src/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactory.php @@ -6,33 +6,22 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactoryInterface; use OpenTelemetry\Contrib\Otlp\MetricExporter; -final class OtlpMetricExporterFactory implements MetricExporterFactoryInterface +final class OtlpMetricExporterFactory extends AbstractMetricExporterFactory { - public static function createExporter(ExporterDsn $dsn, ExporterOptionsInterface $options): MetricExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool { - assert($options instanceof MetricExporterOptions); - - $exporter = MetricExporterEnum::fromDsn($dsn); - if (MetricExporterEnum::Otlp !== $exporter) { - throw new \InvalidArgumentException('DSN exporter must be of type Otlp.'); - } + return MetricExporterEnum::Otlp === MetricExporterEnum::tryFrom($dsn->getExporter()); + } - $transport = TransportEnum::fromDsn($dsn); - if (null === $transport) { - throw new \InvalidArgumentException('Could not find a transport from DSN for this exporter factory.'); - } + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): MetricExporter + { + assert($options instanceof MetricExporterOptions); - /** @var TransportFactoryInterface $transportFactory */ - $transportFactory = call_user_func( - [$transport->getFactoryClass(), 'fromExporter'], + return new MetricExporter($this->transportFactory->createTransport( MetricExporterEndpoint::fromDsn($dsn), $options->getOtlpOptions(), - ); - - return new MetricExporter($transportFactory->createTransport(), $options->getTemporality()->toData()); + ), $options->getTemporality()->toData()); } } diff --git a/src/OpenTelemetry/Trace/SamplerFactory.php b/src/OpenTelemetry/Trace/SamplerFactory.php new file mode 100644 index 0000000..2200e11 --- /dev/null +++ b/src/OpenTelemetry/Trace/SamplerFactory.php @@ -0,0 +1,27 @@ + new AlwaysOnSampler(), + TraceSamplerEnum::AlwaysOff => new AlwaysOffSampler(), + TraceSamplerEnum::ParentBasedAlwaysOn => new ParentBased(new AlwaysOnSampler()), + TraceSamplerEnum::ParentBasedAlwaysOff => new ParentBased(new AlwaysOffSampler()), + TraceSamplerEnum::ParentBasedTraceIdRatio => new ParentBased(new TraceIdRatioBasedSampler($probability)), + TraceSamplerEnum::TraceIdRatio => new TraceIdRatioBasedSampler($probability), + default => throw new \InvalidArgumentException(sprintf('Unknown sampler: %s', $name)), + }; + } +} diff --git a/src/OpenTelemetry/Trace/SpanExporter/AbstractSpanExporterFactory.php b/src/OpenTelemetry/Trace/SpanExporter/AbstractSpanExporterFactory.php new file mode 100644 index 0000000..3cdfb82 --- /dev/null +++ b/src/OpenTelemetry/Trace/SpanExporter/AbstractSpanExporterFactory.php @@ -0,0 +1,15 @@ +createTransport(); + return TraceExporterEnum::Console === TraceExporterEnum::tryFrom($dsn->getExporter()); + } - return new ConsoleSpanExporter($transport); + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): ConsoleSpanExporter + { + return new ConsoleSpanExporter($this->transportFactory->createTransport(TraceExporterEndpoint::fromDsn($dsn), $options)); } } diff --git a/src/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactory.php b/src/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactory.php index 0f47447..5134284 100644 --- a/src/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactory.php +++ b/src/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactory.php @@ -6,9 +6,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter; -final readonly class InMemorySpanExporterFactory implements SpanExporterFactoryInterface +final readonly class InMemorySpanExporterFactory extends AbstractSpanExporterFactory { - public static function createExporter(ExporterDsn $dsn = null, ExporterOptionsInterface $options = null): InMemoryExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + return TraceExporterEnum::InMemory === TraceExporterEnum::tryFrom($dsn->getExporter()); + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): InMemoryExporter { return new InMemoryExporter(); } diff --git a/src/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactory.php b/src/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactory.php index b6410e2..d5bf684 100644 --- a/src/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactory.php +++ b/src/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactory.php @@ -5,27 +5,20 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportEnum; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactoryInterface; use OpenTelemetry\Contrib\Otlp\SpanExporter; -final readonly class OtlpSpanExporterFactory implements SpanExporterFactoryInterface +final readonly class OtlpSpanExporterFactory extends AbstractSpanExporterFactory { - public static function createExporter(ExporterDsn $dsn, ExporterOptionsInterface $options): SpanExporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool { - $exporter = TraceExporterEnum::fromDsn($dsn); - if (TraceExporterEnum::Otlp !== $exporter) { - throw new \InvalidArgumentException('DSN exporter must be of type Otlp.'); - } + return TraceExporterEnum::Otlp === TraceExporterEnum::tryFrom($dsn->getExporter()); + } - $transportFactoryClass = TransportEnum::from($dsn->getTransport())->getFactoryClass(); - /** @var TransportFactoryInterface $transportFactory */ - $transportFactory = call_user_func( - [$transportFactoryClass, 'fromExporter'], + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): SpanExporter + { + return new SpanExporter($this->transportFactory->createTransport( TraceExporterEndpoint::fromDsn($dsn), $options, - ); - - return new SpanExporter($transportFactory->createTransport()); + )); } } diff --git a/src/OpenTelemetry/Trace/SpanExporter/SpanExporterFactory.php b/src/OpenTelemetry/Trace/SpanExporter/SpanExporterFactory.php new file mode 100644 index 0000000..5ec2eb7 --- /dev/null +++ b/src/OpenTelemetry/Trace/SpanExporter/SpanExporterFactory.php @@ -0,0 +1,39 @@ + $factories + */ + public function __construct(private readonly iterable $factories) + { + } + + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn, $options)) { + return true; + } + } + + return false; + } + + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): SpanExporterInterface + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn, $options)) { + return $factory->createExporter($dsn, $options); + } + } + + throw new \InvalidArgumentException('No span exporter supports the given DSN.'); + } +} diff --git a/src/OpenTelemetry/Trace/SpanExporter/TraceExporterEnum.php b/src/OpenTelemetry/Trace/SpanExporter/TraceExporterEnum.php index fd5d236..1781fd7 100644 --- a/src/OpenTelemetry/Trace/SpanExporter/TraceExporterEnum.php +++ b/src/OpenTelemetry/Trace/SpanExporter/TraceExporterEnum.php @@ -3,11 +3,6 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; -use OpenTelemetry\Contrib\Otlp\SpanExporter as OtlpSpanExporter; -use OpenTelemetry\Contrib\Zipkin\Exporter as ZipkinSpanExporter; -use OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporter; -use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter; -use OpenTelemetry\SDK\Trace\SpanExporterInterface; enum TraceExporterEnum: string { @@ -16,32 +11,6 @@ enum TraceExporterEnum: string case Otlp = 'otlp'; case Zipkin = 'zipkin'; - /** - * @return class-string - */ - public function getFactoryClass(): string - { - return match ($this) { - self::Console => ConsoleSpanExporterFactory::class, - self::InMemory => InMemorySpanExporterFactory::class, - self::Otlp => OtlpSpanExporterFactory::class, - self::Zipkin => ZipkinSpanExporterFactory::class, - }; - } - - /** - * @return class-string - */ - public function getClass(): string - { - return match ($this) { - self::Console => ConsoleSpanExporter::class, - self::InMemory => InMemoryExporter::class, - self::Otlp => OtlpSpanExporter::class, - self::Zipkin => ZipkinSpanExporter::class, - }; - } - public static function fromDsn(ExporterDsn $dsn): self { $exporter = self::tryFrom($dsn->getExporter()); diff --git a/src/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactory.php b/src/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactory.php index 86d5057..30cb345 100644 --- a/src/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactory.php +++ b/src/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactory.php @@ -5,20 +5,20 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\PsrHttpTransportFactory; use OpenTelemetry\Contrib\Zipkin\Exporter; -final readonly class ZipkinSpanExporterFactory implements SpanExporterFactoryInterface +final readonly class ZipkinSpanExporterFactory extends AbstractSpanExporterFactory { - public static function createExporter(ExporterDsn $dsn, ExporterOptionsInterface $options): Exporter + public function supports(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): bool { - $exporter = TraceExporterEnum::fromDsn($dsn); - if (TraceExporterEnum::Zipkin !== $exporter) { - throw new \InvalidArgumentException('DSN exporter must be of type Zipkin.'); - } - - $transportFactory = PsrHttpTransportFactory::fromExporter(TraceExporterEndpoint::fromDsn($dsn), $options); + return TraceExporterEnum::Zipkin === TraceExporterEnum::tryFrom($dsn->getExporter()); + } - return new Exporter($transportFactory->createTransport()); + public function createExporter(#[\SensitiveParameter] ExporterDsn $dsn, ExporterOptionsInterface $options): Exporter + { + return new Exporter($this->transportFactory->createTransport( + TraceExporterEndpoint::fromDsn($dsn), + $options, + )); } } diff --git a/src/OpenTelemetry/Trace/SpanProcessor/AbstractSpanProcessorFactory.php b/src/OpenTelemetry/Trace/SpanProcessor/AbstractSpanProcessorFactory.php new file mode 100644 index 0000000..47d4415 --- /dev/null +++ b/src/OpenTelemetry/Trace/SpanProcessor/AbstractSpanProcessorFactory.php @@ -0,0 +1,13 @@ += count($processors)) { throw new \InvalidArgumentException('Processors should not be empty'); diff --git a/src/OpenTelemetry/Trace/SpanProcessor/NoopSpanProcessorFactory.php b/src/OpenTelemetry/Trace/SpanProcessor/NoopSpanProcessorFactory.php index 87f495f..9c216f1 100644 --- a/src/OpenTelemetry/Trace/SpanProcessor/NoopSpanProcessorFactory.php +++ b/src/OpenTelemetry/Trace/SpanProcessor/NoopSpanProcessorFactory.php @@ -6,11 +6,11 @@ use OpenTelemetry\SDK\Trace\SpanProcessor\NoopSpanProcessor; use OpenTelemetry\SDK\Trace\SpanProcessorInterface; -final class NoopSpanProcessorFactory implements SpanProcessorFactoryInterface +final class NoopSpanProcessorFactory extends AbstractSpanProcessorFactory { public static function createProcessor( array $processors = [], - SpanExporterInterface $exporter = null + ?SpanExporterInterface $exporter = null ): SpanProcessorInterface { return new NoopSpanProcessor(); } diff --git a/src/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactory.php b/src/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactory.php index e8a0f50..140a493 100644 --- a/src/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactory.php +++ b/src/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactory.php @@ -6,11 +6,11 @@ use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; use OpenTelemetry\SDK\Trace\SpanProcessorInterface; -final class SimpleSpanProcessorFactory implements SpanProcessorFactoryInterface +final class SimpleSpanProcessorFactory extends AbstractSpanProcessorFactory { public static function createProcessor( array $processors = [], - SpanExporterInterface $exporter = null + ?SpanExporterInterface $exporter = null ): SpanProcessorInterface { if (null === $exporter) { throw new \InvalidArgumentException('Exporter is null'); diff --git a/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorEnum.php b/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorEnum.php index 64ebeb4..8ca1b9d 100644 --- a/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorEnum.php +++ b/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorEnum.php @@ -2,41 +2,10 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanProcessor; -use OpenTelemetry\SDK\Trace\SpanProcessor\MultiSpanProcessor; -use OpenTelemetry\SDK\Trace\SpanProcessor\NoopSpanProcessor; -use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; -use OpenTelemetry\SDK\Trace\SpanProcessorInterface; - enum SpanProcessorEnum: string { // case Batch = 'batch'; case Multi = 'multi'; case Simple = 'simple'; case Noop = 'noop'; - - /** - * @return class-string - */ - public function getFactoryClass(): string - { - return match ($this) { - // self::Batch => BatchSpanProcessorFactory::class, - self::Multi => MultiSpanProcessorFactory::class, - self::Noop => NoopSpanProcessorFactory::class, - self::Simple => SimpleSpanProcessorFactory::class, - }; - } - - /** - * @return class-string - */ - public function getClass(): string - { - return match ($this) { - // self::Batch => BatchSpanProcessor::class, - self::Multi => MultiSpanProcessor::class, - self::Noop => NoopSpanProcessor::class, - self::Simple => SimpleSpanProcessor::class, - }; - } } diff --git a/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorFactoryInterface.php b/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorFactoryInterface.php index 4c14817..15e81c9 100644 --- a/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorFactoryInterface.php +++ b/src/OpenTelemetry/Trace/SpanProcessor/SpanProcessorFactoryInterface.php @@ -12,6 +12,6 @@ interface SpanProcessorFactoryInterface */ public static function createProcessor( array $processors = [], - SpanExporterInterface $exporter = null + ?SpanExporterInterface $exporter = null ): SpanProcessorInterface; } diff --git a/src/OpenTelemetry/Trace/TraceSamplerEnum.php b/src/OpenTelemetry/Trace/TraceSamplerEnum.php new file mode 100644 index 0000000..4c053e5 --- /dev/null +++ b/src/OpenTelemetry/Trace/TraceSamplerEnum.php @@ -0,0 +1,13 @@ += count($processors)) { throw new \InvalidArgumentException('Processors should not be empty'); diff --git a/src/OpenTelemetry/Trace/TracerProvider/NoopTracerProviderFactory.php b/src/OpenTelemetry/Trace/TracerProvider/NoopTracerProviderFactory.php index b041e78..153ca82 100644 --- a/src/OpenTelemetry/Trace/TracerProvider/NoopTracerProviderFactory.php +++ b/src/OpenTelemetry/Trace/TracerProvider/NoopTracerProviderFactory.php @@ -8,7 +8,7 @@ final class NoopTracerProviderFactory implements TracerProviderFactoryInterface { - public static function createProvider(SamplerInterface $sampler = null, array $processors = []): TracerProviderInterface + public static function createProvider(?SamplerInterface $sampler = null, array $processors = []): TracerProviderInterface { return new NoopTracerProvider(); } diff --git a/src/OpenTelemetry/Trace/TracerProvider/TraceProviderEnum.php b/src/OpenTelemetry/Trace/TracerProvider/TraceProviderEnum.php index 42c02da..101cd04 100644 --- a/src/OpenTelemetry/Trace/TracerProvider/TraceProviderEnum.php +++ b/src/OpenTelemetry/Trace/TracerProvider/TraceProviderEnum.php @@ -2,35 +2,9 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider; -use OpenTelemetry\SDK\Trace\NoopTracerProvider; -use OpenTelemetry\SDK\Trace\TracerProvider; -use OpenTelemetry\SDK\Trace\TracerProviderInterface; - enum TraceProviderEnum: string { case Default = 'default'; case Noop = 'noop'; // case Traceable = 'traceable'; - - /** - * @return class-string - */ - public function getFactoryClass(): string - { - return match ($this) { - self::Default => TracerProviderFactory::class, - self::Noop => NoopTracerProviderFactory::class, - }; - } - - /** - * @return class-string - */ - public function getClass(): string - { - return match ($this) { - self::Default => TracerProvider::class, - self::Noop => NoopTracerProvider::class, - }; - } } diff --git a/src/OpenTelemetry/Trace/TracerProvider/TraceSamplerEnum.php b/src/OpenTelemetry/Trace/TracerProvider/TraceSamplerEnum.php deleted file mode 100644 index 81b9368..0000000 --- a/src/OpenTelemetry/Trace/TracerProvider/TraceSamplerEnum.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ - public function getClass(): string - { - return match ($this) { - self::AlwaysOff => AlwaysOffSampler::class, - self::AlwaysOn => AlwaysOnSampler::class, - self::ParentBased => ParentBased::class, - self::TraceIdRatio => TraceIdRatioBasedSampler::class, - }; - } -} diff --git a/src/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryInterface.php b/src/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryInterface.php index a311f53..570b375 100644 --- a/src/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryInterface.php +++ b/src/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryInterface.php @@ -11,5 +11,5 @@ interface TracerProviderFactoryInterface /** * @param SpanProcessorInterface[] $processors */ - public static function createProvider(SamplerInterface $sampler = null, array $processors = []): TracerProviderInterface; + public static function createProvider(?SamplerInterface $sampler = null, array $processors = []): TracerProviderInterface; } diff --git a/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php b/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php index f097425..d7fab97 100644 --- a/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php +++ b/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php @@ -16,7 +16,7 @@ final class ZipkinExporterEndpoint implements ExporterEndpointInterface private function __construct( private readonly ExporterDsn $dsn, - UriFactoryInterface $uriFactory = null, + ?UriFactoryInterface $uriFactory = null, ) { if (TraceExporterEnum::Zipkin !== TraceExporterEnum::fromDsn($this->dsn)) { throw new \InvalidArgumentException('Unsupported DSN exporter for this endpoint.'); diff --git a/src/OpenTelemetry/Transport/AbstractTransportFactory.php b/src/OpenTelemetry/Transport/AbstractTransportFactory.php new file mode 100644 index 0000000..460c9c6 --- /dev/null +++ b/src/OpenTelemetry/Transport/AbstractTransportFactory.php @@ -0,0 +1,13 @@ +toTransportParams()); + return null !== $endpoint->getTransport() + && in_array(TransportEnum::tryFrom($endpoint->getTransport()), [TransportEnum::Grpc, TransportEnum::Grpcs], true); } - public static function supportExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool + public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): TransportInterface { - return str_contains($endpoint->getTransport() ?? '', 'grpc'); - } + $params = $options->toTransportParams(); - public function createTransport(): TransportInterface - { - $format = OtlpExporterFormatEnum::Grpc; - $compression = OtlpExporterCompressionEnum::tryFrom($this->params->compression) ?? OtlpExporterCompressionEnum::None; + $compression = OtlpExporterCompressionEnum::tryFrom($params->compression) ?? OtlpExporterCompressionEnum::None; return (new \OpenTelemetry\Contrib\Grpc\GrpcTransportFactory())->create( - $this->endpoint, - $format->toContentType(), - $this->params->headers, + (string) $endpoint, + OtlpExporterFormatEnum::Grpc->toContentType(), + $params->headers, $compression->toKnownValue(), - $this->params->timeout, - $this->params->retryDelay, - $this->params->maxRetries, - $this->params->caCert, - $this->params->cert, - $this->params->key, + $params->timeout, + $params->retryDelay, + $params->maxRetries, + $params->caCert, + $params->cert, + $params->key, ); } } diff --git a/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php b/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php index 870d073..4e1c710 100644 --- a/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php +++ b/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php @@ -10,24 +10,9 @@ final readonly class OtlpHttpTransportFactory implements TransportFactoryInterface { - private function __construct( - private string $endpoint, - private TransportParams $params, - ) { - } - - public static function fromExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): self - { - if (false === self::supportExporter($endpoint, $options)) { - throw new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'); - } - - return new self((string) $endpoint, $options->toTransportParams()); - } - - public static function supportExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool + public function supports(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool { - if (false === str_contains($endpoint->getTransport() ?? '', 'http')) { + if (null === $endpoint->getTransport()) { return false; } @@ -35,25 +20,26 @@ public static function supportExporter(ExporterEndpointInterface $endpoint, Expo return false; } - return true; + return in_array(TransportEnum::tryFrom($endpoint->getTransport()), [TransportEnum::Http, TransportEnum::Https], true); } - public function createTransport(): TransportInterface + public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): TransportInterface { - $format = OtlpExporterFormatEnum::tryFrom($this->params->contentType) ?? OtlpExporterFormatEnum::Json; - $compression = OtlpExporterCompressionEnum::tryFrom($this->params->contentType) ?? OtlpExporterCompressionEnum::None; + $params = $options->toTransportParams(); + $format = OtlpExporterFormatEnum::tryFrom($params->contentType) ?? OtlpExporterFormatEnum::Json; + $compression = OtlpExporterCompressionEnum::tryFrom($params->contentType) ?? OtlpExporterCompressionEnum::None; return (new \OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory())->create( - $this->endpoint, + (string) $endpoint, $format->toContentType(), - $this->params->headers, + $params->headers, $compression->toKnownValue(), - $this->params->timeout, - $this->params->retryDelay, - $this->params->maxRetries, - $this->params->caCert, - $this->params->cert, - $this->params->key, + $params->timeout, + $params->retryDelay, + $params->maxRetries, + $params->caCert, + $params->cert, + $params->key, ); } } diff --git a/src/OpenTelemetry/Transport/PsrHttpTransportFactory.php b/src/OpenTelemetry/Transport/PsrHttpTransportFactory.php index 06c9f6e..a2a195c 100644 --- a/src/OpenTelemetry/Transport/PsrHttpTransportFactory.php +++ b/src/OpenTelemetry/Transport/PsrHttpTransportFactory.php @@ -11,42 +11,29 @@ final readonly class PsrHttpTransportFactory implements TransportFactoryInterface { - private function __construct( - private string $endpoint, - private TransportParams $params, - ) { - } - - public static function fromExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): self - { - if (false === self::supportExporter($endpoint, $options)) { - throw new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'); - } - - return new self((string) $endpoint, $options->toTransportParams()); - } - - public static function supportExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool + public function supports(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool { - return str_contains($endpoint->getTransport() ?? '', 'http'); + return null !== $endpoint->getTransport() + && in_array(TransportEnum::tryFrom($endpoint->getTransport()), [TransportEnum::Http, TransportEnum::Https], true); } - public function createTransport(): TransportInterface + public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): TransportInterface { - $format = OtlpExporterFormatEnum::tryFrom($this->params->contentType) ?? OtlpExporterFormatEnum::Json; - $compression = OtlpExporterCompressionEnum::tryFrom($this->params->compression) ?? OtlpExporterCompressionEnum::None; + $params = $options->toTransportParams(); + $format = OtlpExporterFormatEnum::tryFrom($params->contentType) ?? OtlpExporterFormatEnum::Json; + $compression = OtlpExporterCompressionEnum::tryFrom($params->compression) ?? OtlpExporterCompressionEnum::None; return PsrTransportFactory::discover()->create( - $this->endpoint, + (string) $endpoint, $format->toContentType(), - $this->params->headers, + $params->headers, $compression->toKnownValue(), - $this->params->timeout, - $this->params->retryDelay, - $this->params->maxRetries, - $this->params->caCert, - $this->params->cert, - $this->params->key, + $params->timeout, + $params->retryDelay, + $params->maxRetries, + $params->caCert, + $params->cert, + $params->key, ); } } diff --git a/src/OpenTelemetry/Transport/StreamTransportFactory.php b/src/OpenTelemetry/Transport/StreamTransportFactory.php index 65d5b66..aa46699 100644 --- a/src/OpenTelemetry/Transport/StreamTransportFactory.php +++ b/src/OpenTelemetry/Transport/StreamTransportFactory.php @@ -10,42 +10,29 @@ final readonly class StreamTransportFactory implements TransportFactoryInterface { - private function __construct( - private string $endpoint, - private TransportParams $params, - ) { - } - - public static function fromExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): self - { - if (false === self::supportExporter($endpoint, $options)) { - throw new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'); - } - - return new self((string) $endpoint, $options->toTransportParams()); - } - - public static function supportExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool + public function supports(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool { - return 'stream' === $endpoint->getTransport(); + return null !== $endpoint->getTransport() + && TransportEnum::Stream === TransportEnum::tryFrom($endpoint->getTransport()); } - public function createTransport(): TransportInterface + public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): TransportInterface { - $format = OtlpExporterFormatEnum::tryFrom($this->params->contentType) ?? OtlpExporterFormatEnum::Json; - $compression = OtlpExporterCompressionEnum::tryFrom($this->params->compression) ?? OtlpExporterCompressionEnum::None; + $params = $options->toTransportParams(); + $format = OtlpExporterFormatEnum::tryFrom($params->contentType) ?? OtlpExporterFormatEnum::Json; + $compression = OtlpExporterCompressionEnum::tryFrom($params->compression) ?? OtlpExporterCompressionEnum::None; return (new \OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory())->create( - $this->endpoint, + (string) $endpoint, $format->toContentType(), - $this->params->headers, + $params->headers, $compression->toKnownValue(), - $this->params->timeout, - $this->params->retryDelay, - $this->params->maxRetries, - $this->params->caCert, - $this->params->cert, - $this->params->key, + $params->timeout, + $params->retryDelay, + $params->maxRetries, + $params->caCert, + $params->cert, + $params->key, ); } } diff --git a/src/OpenTelemetry/Transport/TransportEnum.php b/src/OpenTelemetry/Transport/TransportEnum.php index 77bbe2b..2389cb0 100644 --- a/src/OpenTelemetry/Transport/TransportEnum.php +++ b/src/OpenTelemetry/Transport/TransportEnum.php @@ -12,18 +12,6 @@ enum TransportEnum: string case Https = 'https'; case Stream = 'stream'; - /** - * @return class-string - */ - public function getFactoryClass(): string - { - return match ($this) { - self::Grpc, self::Grpcs => GrpcTransportFactory::class, - self::Http, self::Https => OtlpHttpTransportFactory::class, - self::Stream => StreamTransportFactory::class, - }; - } - public function getScheme(): ?string { return match ($this) { diff --git a/src/OpenTelemetry/Transport/TransportFactory.php b/src/OpenTelemetry/Transport/TransportFactory.php new file mode 100644 index 0000000..029d027 --- /dev/null +++ b/src/OpenTelemetry/Transport/TransportFactory.php @@ -0,0 +1,39 @@ + $factories + */ + public function __construct(private readonly iterable $factories) + { + } + + public function supports(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool + { + foreach ($this->factories as $factory) { + if ($factory->supports($endpoint, $options)) { + return true; + } + } + + return false; + } + + public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): TransportInterface + { + foreach ($this->factories as $factory) { + if ($factory->supports($endpoint, $options)) { + return $factory->createTransport($endpoint, $options); + } + } + + throw new \InvalidArgumentException('No transport supports the given endpoint.'); + } +} diff --git a/src/OpenTelemetry/Transport/TransportFactoryInterface.php b/src/OpenTelemetry/Transport/TransportFactoryInterface.php index 766888d..1ca33d0 100644 --- a/src/OpenTelemetry/Transport/TransportFactoryInterface.php +++ b/src/OpenTelemetry/Transport/TransportFactoryInterface.php @@ -8,12 +8,10 @@ interface TransportFactoryInterface { - public static function fromExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): self; - - public static function supportExporter(ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool; + public function supports(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): bool; /** * @return TransportInterface */ - public function createTransport(): TransportInterface; + public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options): TransportInterface; } diff --git a/src/Resources/config/services.php b/src/Resources/config/services.php index 4e68078..194f2ac 100644 --- a/src/Resources/config/services.php +++ b/src/Resources/config/services.php @@ -1,25 +1,19 @@ parameters() ->set('open_telemetry.bundle.name', OpenTelemetryBundle::name()) @@ -31,52 +25,27 @@ ->defaults() ->private() - ->set('open_telemetry.exporter_dsn', ExporterDsn::class) - ->abstract() - ->factory([ExporterDsn::class, 'fromString']) - - ->set('open_telemetry.exporter_options', ExporterOptionsInterface::class) - ->factory([OtlpExporterOptions::class, 'fromConfiguration']) - ->set('open_telemetry.metric_exporter_options', ExporterOptionsInterface::class) - ->factory([MetricExporterOptions::class, 'fromConfiguration']) - - ->set('open_telemetry.text_map_propagators.noop', NoopTextMapPropagator::class) - ->set('open_telemetry.propagation_getters.headers', HeadersPropagator::class) - - ->set('open_telemetry.traces.samplers.always_on', AlwaysOnSampler::class)->public() - ->set('open_telemetry.traces.samplers.always_off', AlwaysOffSampler::class)->public() - ->set('open_telemetry.traces.samplers.trace_id_ratio_based', TraceIdRatioBasedSampler::class)->public() - ->set('open_telemetry.traces.samplers.parent_based', ParentBased::class)->public() + ->set('open_telemetry.propagator.server_timing', ServerTimingPropagator::class) + ->set('open_telemetry.propagator.trace_response', TraceResponsePropagator::class) - ->set('open_telemetry.traces.exporter' /* , SpanExporterInterface::class */) - ->synthetic() - ->set('open_telemetry.traces.processor' /* , SpanProcessorInterface::class */) - ->synthetic() - ->set('open_telemetry.traces.provider' /* , TracerProviderInterface::class */) - ->synthetic() - ->set('open_telemetry.traces.tracer', Tracer::class) - ->synthetic() + ->set('open_telemetry.propagator_text_map.noop', NoopTextMapPropagator::class) + ->set('open_telemetry.propagator_text_map.multi', MultiTextMapPropagator::class) - ->set('open_telemetry.metrics.exemplar_filters.with_sampled_trace', WithSampledTraceExemplarFilter::class)->public() - ->set('open_telemetry.metrics.exemplar_filters.all', AllExemplarFilter::class)->public() - ->set('open_telemetry.metrics.exemplar_filters.none', NoneExemplarFilter::class)->public() + ->set('open_telemetry.propagation_getter.headers', HeadersPropagationGetter::class) + ->set('open_telemetry.propagation_getter.sanitize_combined_headers', SanitizeCombinedHeadersPropagationGetter::class) - ->set('open_telemetry.metrics.exporter' /* , MetricExporterInterface::class */) - ->synthetic() - ->set('open_telemetry.metrics.provider' /* , MeterProviderInterface::class */) - ->synthetic() - ->set('open_telemetry.metrics.meter', Meter::class) - ->synthetic() + ->set('open_telemetry.propagation_getter_setter.array_access', ArrayAccessGetterSetter::class) - ->set('open_telemetry.logs.exporter' /* , LogRecordExporterInterface::class */) - ->synthetic() - ->set('open_telemetry.logs.processor' /* , LogRecordProcessorInterface::class */) - ->synthetic() - ->set('open_telemetry.logs.provider' /* , LoggerProviderInterface::class */) - ->synthetic() - ->set('open_telemetry.logs.logger', Logger::class) - ->synthetic() + ->set('open_telemetry.exporter_dsn', OtlpExporterOptions::class) + ->factory([ExporterDsn::class, 'fromString']) +// ->args([ +// abstract_arg('dsn'), +// ]) - ->set('open_telemetry.logs.monolog.handler', MonologHandler::class) + ->set('open_telemetry.otlp_exporter_options', OtlpExporterOptions::class) + ->factory([OtlpExporterOptions::class, 'fromConfiguration']) +// ->args([ +// abstract_arg('options'), +// ]) ; }; diff --git a/src/Resources/config/services_logs.php b/src/Resources/config/services_logs.php new file mode 100644 index 0000000..49ca681 --- /dev/null +++ b/src/Resources/config/services_logs.php @@ -0,0 +1,103 @@ +services() + ->defaults() + ->private() + + ->set('open_telemetry.logs.monolog.handler', MonologHandler::class) + + // Exporters + ->set('open_telemetry.logs.exporter_factory.abstract', AbstractLogExporterFactory::class) + ->abstract() + ->args([ + service('open_telemetry.transport_factory'), + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.logs.exporter_factory.console', ConsoleLogExporterFactory::class) + ->parent('open_telemetry.logs.exporter_factory.abstract') + ->tag('open_telemetry.logs.exporter_factory') + + ->set('open_telemetry.logs.exporter_factory.in-memory', InMemoryLogExporterFactory::class) + ->parent('open_telemetry.logs.exporter_factory.abstract') + ->tag('open_telemetry.logs.exporter_factory') + + ->set('open_telemetry.logs.exporter_factory.noop', NoopLogExporterFactory::class) + ->parent('open_telemetry.logs.exporter_factory.abstract') + ->tag('open_telemetry.logs.exporter_factory') + + ->set('open_telemetry.logs.exporter_factory.otlp', OtlpLogExporterFactory::class) + ->parent('open_telemetry.logs.exporter_factory.abstract') + ->tag('open_telemetry.logs.exporter_factory') + + ->set('open_telemetry.logs.exporter_factory', LogExporterFactory::class) + ->args([ + tagged_iterator('open_telemetry.logs.exporter_factory'), + ]) + + ->set('open_telemetry.logs.exporter_interface', LogRecordExporterInterface::class) + ->factory([service('open_telemetry.logs.exporter_factory'), 'createExporter']) + + // Processors + ->set('open_telemetry.logs.processor_factory.abstract', AbstractLogProcessorFactory::class) + ->abstract() + ->args([ + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.logs.processor_factory.multi', MultiLogProcessorFactory::class) + ->parent('open_telemetry.logs.processor_factory.abstract') + + ->set('open_telemetry.logs.processor_factory.noop', NoopLogProcessorFactory::class) + ->parent('open_telemetry.logs.processor_factory.abstract') + + ->set('open_telemetry.logs.processor_factory.simple', SimpleLogProcessorFactory::class) + ->parent('open_telemetry.logs.processor_factory.abstract') + + ->set('open_telemetry.logs.processor_interface', LogRecordProcessorInterface::class) + + // Providers + ->set('open_telemetry.logs.provider_factory.abstract', AbstractLoggerProviderFactory::class) + ->abstract() + ->args([ + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.logs.provider_factory.noop', NoopLoggerProviderFactory::class) + ->parent('open_telemetry.logs.provider_factory.abstract') + + ->set('open_telemetry.logs.provider_factory.default', NoopLoggerProviderFactory::class) + ->parent('open_telemetry.logs.provider_factory.abstract') + + ->set('open_telemetry.logs.provider_interface', LoggerProviderInterface::class) + + // Logger + ->set('open_telemetry.logs.logger', LoggerInterface::class) + ; +}; diff --git a/src/Resources/config/services_metrics.php b/src/Resources/config/services_metrics.php new file mode 100644 index 0000000..c029c02 --- /dev/null +++ b/src/Resources/config/services_metrics.php @@ -0,0 +1,101 @@ +services() + ->defaults() + ->private() + + ->set('open_telemetry.metric_exporter_options', MetricExporterOptions::class) + ->factory([MetricExporterOptions::class, 'fromConfiguration']) +// ->args([ +// abstract_arg('options'), +// ]) + + // Exemplar Filters + ->set('open_telemetry.metrics.exemplar_factory', ExemplarFilterFactory::class) + ->factory([ExemplarFilterFactory::class, 'create']) +// ->args([ +// abstract_arg('name'), +// ]) + + // Exporters + ->set('open_telemetry.metrics.exporter_factory.abstract', AbstractMetricExporterFactory::class) + ->abstract() + ->args([ + service('open_telemetry.transport_factory'), + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.metrics.exporter_factory.console', ConsoleMetricExporterFactory::class) + ->parent('open_telemetry.metrics.exporter_factory.abstract') + ->tag('open_telemetry.metrics.exporter_factory') + + ->set('open_telemetry.metrics.exporter_factory.in-memory', InMemoryMetricExporterFactory::class) + ->parent('open_telemetry.metrics.exporter_factory.abstract') + ->tag('open_telemetry.metrics.exporter_factory') + + ->set('open_telemetry.metrics.exporter_factory.noop', NoopMetricExporterFactory::class) + ->parent('open_telemetry.metrics.exporter_factory.abstract') + ->tag('open_telemetry.metrics.exporter_factory') + + ->set('open_telemetry.metrics.exporter_factory.otlp', OtlpMetricExporterFactory::class) + ->parent('open_telemetry.metrics.exporter_factory.abstract') + ->tag('open_telemetry.metrics.exporter_factory') + + ->set('open_telemetry.metrics.exporter_factory', MetricExporterFactory::class) + ->args([ + tagged_iterator('open_telemetry.metrics.exporter_factory'), + ]) + + ->set('open_telemetry.metrics.exporter_interface', MetricExporterInterface::class) + ->factory([service('open_telemetry.metrics.exporter_factory'), 'createExporter']) +// ->args([ +// abstract_arg('dsn'), +// abstract_arg('options'), +// ]) + + // Providers + ->set('open_telemetry.metrics.provider_factory.abstract', AbstractMeterProviderFactory::class) + ->abstract() + ->args([ + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.metrics.provider_factory.noop', NoopMeterProviderFactory::class) + ->parent('open_telemetry.metrics.provider_factory.abstract') + + ->set('open_telemetry.metrics.provider_factory.default', DefaultMeterProviderFactory::class) + ->parent('open_telemetry.metrics.provider_factory.abstract') + + ->set('open_telemetry.metrics.provider_interface', MeterProviderInterface::class) +// ->args([ +// abstract_arg('exporter'), +// abstract_arg('filter'), +// ]) + + // Meter + ->set('open_telemetry.metrics.meter', MeterInterface::class) + ; +}; diff --git a/src/Resources/config/services_traces.php b/src/Resources/config/services_traces.php new file mode 100644 index 0000000..7834fd9 --- /dev/null +++ b/src/Resources/config/services_traces.php @@ -0,0 +1,105 @@ +services() + ->defaults() + ->private() + + ->set('open_telemetry.traces.sampler_factory', SamplerFactory::class) + ->factory([SamplerFactory::class, 'create']) + + // Exporters + ->set('open_telemetry.traces.exporter_factory.abstract', AbstractSpanExporterFactory::class) + ->abstract() + ->args([ + service('open_telemetry.transport_factory'), + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.traces.exporter_factory.console', ConsoleSpanExporterFactory::class) + ->parent('open_telemetry.traces.exporter_factory.abstract') + ->tag('open_telemetry.traces.exporter_factory') + + ->set('open_telemetry.traces.exporter_factory.in-memory', InMemorySpanExporterFactory::class) + ->parent('open_telemetry.traces.exporter_factory.abstract') + ->tag('open_telemetry.traces.exporter_factory') + + ->set('open_telemetry.traces.exporter_factory.otlp', OtlpSpanExporterFactory::class) + ->parent('open_telemetry.traces.exporter_factory.abstract') + ->tag('open_telemetry.traces.exporter_factory') + + ->set('open_telemetry.traces.exporter_factory.zipkin', ZipkinSpanExporterFactory::class) + ->parent('open_telemetry.traces.exporter_factory.abstract') + ->tag('open_telemetry.traces.exporter_factory') + + ->set('open_telemetry.traces.exporter_factory', SpanExporterFactory::class) + ->args([ + tagged_iterator('open_telemetry.traces.exporter_factory'), + ]) + + ->set('open_telemetry.traces.exporter_interface', SpanExporterInterface::class) + ->factory([service('open_telemetry.traces.exporter_factory'), 'createExporter']) + + // Processors + ->set('open_telemetry.traces.processor_factory.abstract', AbstractSpanProcessorFactory::class) + ->abstract() + ->args([ + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.traces.processor_factory.multi', MultiSpanProcessorFactory::class) + ->parent('open_telemetry.traces.processor_factory.abstract') + + ->set('open_telemetry.traces.processor_factory.noop', NoopSpanProcessorFactory::class) + ->parent('open_telemetry.traces.processor_factory.abstract') + + ->set('open_telemetry.traces.processor_factory.simple', SimpleSpanProcessorFactory::class) + ->parent('open_telemetry.traces.processor_factory.abstract') + + ->set('open_telemetry.traces.processor_interface', SpanProcessorInterface::class) + + // Providers + ->set('open_telemetry.traces.provider_factory.abstract', AbstractTracerProviderFactory::class) + ->abstract() + ->args([ + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.traces.provider_factory.noop', NoopTracerProviderFactory::class) + ->parent('open_telemetry.traces.provider_factory.abstract') + + ->set('open_telemetry.traces.provider_factory.default', DefaultTracerProviderFactory::class) + ->parent('open_telemetry.traces.provider_factory.abstract') + + ->set('open_telemetry.traces.provider_interface', TracerProviderInterface::class) + + // Tracer + ->set('open_telemetry.traces.tracer', TracerInterface::class) + ; +}; diff --git a/src/Resources/config/services_tracing_instrumentation.php b/src/Resources/config/services_tracing_instrumentation.php index 4dba571..3fae461 100644 --- a/src/Resources/config/services_tracing_instrumentation.php +++ b/src/Resources/config/services_tracing_instrumentation.php @@ -55,8 +55,8 @@ ->set('open_telemetry.instrumentation.http_kernel.trace.event_subscriber', TraceableHttpKernelEventSubscriber::class) ->arg('$tracer', service('open_telemetry.traces.default_tracer')) - ->arg('$propagator', service('open_telemetry.text_map_propagators.noop')) - ->arg('$propagationGetter', service('open_telemetry.propagation_getters.headers')) + ->arg('$propagator', service('open_telemetry.propagator_text_map.noop')) + ->arg('$propagationGetter', service('open_telemetry.propagation_getter.headers')) ->arg('$requestHeaders', param('open_telemetry.instrumentation.http_kernel.tracing.request_headers')) ->arg('$responseHeaders', param('open_telemetry.instrumentation.http_kernel.tracing.response_headers')) ->tag('kernel.event_subscriber') diff --git a/src/Resources/config/services_transports.php b/src/Resources/config/services_transports.php new file mode 100644 index 0000000..da38d17 --- /dev/null +++ b/src/Resources/config/services_transports.php @@ -0,0 +1,47 @@ +services() + ->defaults() + ->private() + + ->set('open_telemetry.transport_factory.abstract', AbstractTransportFactory::class) + ->abstract() + ->args([ + service('logger')->ignoreOnInvalid(), + ]) + ->tag('monolog.logger', ['channel' => 'open_telemetry']) + + ->set('open_telemetry.transport_factory.grpc', GrpcTransportFactory::class) + ->parent('open_telemetry.transport_factory.abstract') + ->tag('open_telemetry.transport_factory') + + ->set('open_telemetry.transport_factory.otlp_http', OtlpHttpTransportFactory::class) + ->parent('open_telemetry.transport_factory.abstract') + ->tag('open_telemetry.transport_factory') + + ->set('open_telemetry.transport_factory.psr_http', PsrHttpTransportFactory::class) + ->parent('open_telemetry.transport_factory.abstract') + ->tag('open_telemetry.transport_factory') + + ->set('open_telemetry.transport_factory.stream', StreamTransportFactory::class) + ->parent('open_telemetry.transport_factory.abstract') + ->tag('open_telemetry.transport_factory') + + ->set('open_telemetry.transport_factory', TransportFactory::class) + ->args([ + tagged_iterator('open_telemetry.transport_factory'), + ]) + ; +}; diff --git a/tests/Unit/Command/DummyCommandTest.php b/tests/Unit/Command/DummyCommandTest.php index 8a53bfc..4482f1b 100644 --- a/tests/Unit/Command/DummyCommandTest.php +++ b/tests/Unit/Command/DummyCommandTest.php @@ -3,13 +3,13 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Unit\Command; use FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Application\Command\DummyCommand; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Tester\CommandTester; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Application\Command\DummyCommand - */ +#[CoversClass(DummyCommand::class)] final class DummyCommandTest extends TestCase { public function testSuccessful(): void @@ -49,7 +49,7 @@ public function testThrow(): void /** * @return array}> */ - public function exitCodeProvider(): array + public static function exitCodeProvider(): array { return [ [42, ['--exit-code' => 42]], @@ -58,10 +58,9 @@ public function exitCodeProvider(): array } /** - * @dataProvider exitCodeProvider - * * @param array $args */ + #[DataProvider('exitCodeProvider')] public function testExitCode(int $exitCode, array $args): void { $commandTester = new CommandTester(new DummyCommand()); diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index 5dfee2e..49dfd1a 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -276,9 +276,8 @@ public function testReferenceConfiguration(): void provider: type: default # One of "default"; "noop", Required sampler: - type: always_on # One of "always_off"; "always_on"; "parent_based"; "trace_id_ratio", Required - ratio: ~ - parent: ~ + type: always_on # One of "always_off"; "always_on"; "parent_based_always_off"; "parent_based_always_on"; "parent_based_trace_id_ratio"; "trace_id_ratio", Required + probability: ~ processors: [] processors: diff --git a/tests/Unit/DependencyInjection/DependencyInjectionTest.php b/tests/Unit/DependencyInjection/DependencyInjectionTest.php deleted file mode 100644 index 264c13f..0000000 --- a/tests/Unit/DependencyInjection/DependencyInjectionTest.php +++ /dev/null @@ -1,9 +0,0 @@ -getContainer('logs-default-simple-otlp'); - - self::assertTrue($container->hasDefinition('open_telemetry.logs.exporters.otlp')); - self::assertTrue($container->hasDefinition('open_telemetry.logs.processors.simple')); - self::assertTrue($container->hasDefinition('open_telemetry.logs.providers.default')); - self::assertTrue($container->hasDefinition('open_telemetry.logs.loggers.main')); - - $exporter = $container->getDefinition('open_telemetry.logs.exporters.otlp'); - self::assertEquals([OtlpLogExporterFactory::class, 'createExporter'], $exporter->getFactory()); - self::assertEquals(['http+otlp://localhost'], $exporter->getArgument('$dsn')->getArguments()); - self::assertEquals([[]], $exporter->getArgument('$options')->getArguments()); - - $processor = $container->getDefinition('open_telemetry.logs.processors.simple'); - self::assertEquals([SimpleLogProcessorFactory::class, 'createProcessor'], $processor->getFactory()); - - $provider = $container->getDefinition('open_telemetry.logs.providers.default'); - self::assertEquals([LoggerProviderFactory::class, 'createProvider'], $provider->getFactory()); - - $tracer = $container->getDefinition('open_telemetry.logs.loggers.main'); - self::assertEquals([ - new Reference('open_telemetry.logs.providers.default'), - 'getLogger', - ], $tracer->getFactory()); - } - - public function testMetricsDefaultProviderOtlpExporter(): void - { - $container = $this->getContainer('metrics-default-otlp'); - - self::assertTrue($container->hasDefinition('open_telemetry.metrics.exporters.otlp')); - self::assertTrue($container->hasDefinition('open_telemetry.metrics.providers.default')); - self::assertTrue($container->hasDefinition('open_telemetry.metrics.meters.main')); - - $exporter = $container->getDefinition('open_telemetry.metrics.exporters.otlp'); - self::assertEquals([OtlpMetricExporterFactory::class, 'createExporter'], $exporter->getFactory()); - self::assertEquals(['http+otlp://localhost'], $exporter->getArgument('$dsn')->getArguments()); - self::assertEquals([[]], $exporter->getArgument('$options')->getArguments()); - - $provider = $container->getDefinition('open_telemetry.metrics.providers.default'); - self::assertEquals([MeterProviderFactory::class, 'createProvider'], $provider->getFactory()); - - $tracer = $container->getDefinition('open_telemetry.metrics.meters.main'); - self::assertEquals([ - new Reference('open_telemetry.metrics.providers.default'), - 'getMeter', - ], $tracer->getFactory()); - } - - public function testNoTracingInstrumentation(): void - { - $container = $this->getContainer('no-tracing-instrumentation'); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.cache.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.cache.trace.adapter')); - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.cache.trace.tag_aware_adapter')); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.console.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.console.trace.event_subscriber')); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.doctrine.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.doctrine.trace.event_subscriber')); - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.doctrine.trace.middleware')); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.http_client.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.http_client.trace.client')); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.http_kernel.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.http_kernel.trace.event_subscriber')); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.mailer.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.mailer.trace.event_subscriber')); - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.mailer.trace.default_transport')); - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.mailer.trace.mailer')); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.messenger.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.event_subscriber')); - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.transport')); - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.transport_factory')); - self::assertFalse($container->hasAlias('messenger.transport.open_telemetry_tracer.factory')); - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.middleware')); - self::assertFalse($container->hasAlias('messenger.middleware.open_telemetry_tracer')); - - self::assertFalse($container->getParameter('open_telemetry.instrumentation.twig.tracing.enabled')); - - self::assertFalse($container->hasDefinition('open_telemetry.instrumentation.twig.trace.extension')); - } - - public function testNoop(): void - { - $container = $this->getContainer('noop'); - - self::assertTrue($container->hasDefinition('open_telemetry.traces.tracers.main')); - self::assertTrue($container->hasDefinition('open_telemetry.traces.providers.noop')); - - $provider = $container->getDefinition('open_telemetry.traces.providers.noop'); - self::assertEquals([NoopTracerProviderFactory::class, 'createProvider'], $provider->getFactory()); - - $tracer = $container->getDefinition('open_telemetry.traces.tracers.main'); - self::assertEquals([ - new Reference('open_telemetry.traces.providers.noop'), - 'getTracer', - ], $tracer->getFactory()); - - self::assertTrue($container->hasDefinition('open_telemetry.metrics.meters.main')); - self::assertTrue($container->hasDefinition('open_telemetry.metrics.providers.noop')); - - $provider = $container->getDefinition('open_telemetry.metrics.providers.noop'); - self::assertEquals([NoopMeterProviderFactory::class, 'createProvider'], $provider->getFactory()); - - $tracer = $container->getDefinition('open_telemetry.metrics.meters.main'); - self::assertEquals([ - new Reference('open_telemetry.metrics.providers.noop'), - 'getMeter', - ], $tracer->getFactory()); - - self::assertTrue($container->hasDefinition('open_telemetry.logs.loggers.main')); - self::assertTrue($container->hasDefinition('open_telemetry.logs.providers.noop')); - - $provider = $container->getDefinition('open_telemetry.logs.providers.noop'); - self::assertEquals([NoopLoggerProviderFactory::class, 'createProvider'], $provider->getFactory()); - - $tracer = $container->getDefinition('open_telemetry.logs.loggers.main'); - self::assertEquals([ - new Reference('open_telemetry.logs.providers.noop'), - 'getLogger', - ], $tracer->getFactory()); - } - - public function testTracesDefaultProviderSimpleProcessorOtlpExporter(): void - { - $container = $this->getContainer('traces-default-simple-otlp'); - - self::assertTrue($container->hasDefinition('open_telemetry.traces.exporters.otlp')); - self::assertTrue($container->hasDefinition('open_telemetry.traces.processors.simple')); - self::assertTrue($container->hasDefinition('open_telemetry.traces.providers.default')); - self::assertTrue($container->hasDefinition('open_telemetry.traces.tracers.main')); - - $exporter = $container->getDefinition('open_telemetry.traces.exporters.otlp'); - self::assertEquals([OtlpSpanExporterFactory::class, 'createExporter'], $exporter->getFactory()); - self::assertEquals(['http+otlp://localhost'], $exporter->getArgument('$dsn')->getArguments()); - self::assertEquals([[]], $exporter->getArgument('$options')->getArguments()); - - $processor = $container->getDefinition('open_telemetry.traces.processors.simple'); - self::assertEquals([SimpleSpanProcessorFactory::class, 'createProcessor'], $processor->getFactory()); - - $provider = $container->getDefinition('open_telemetry.traces.providers.default'); - self::assertEquals([TracerProviderFactory::class, 'createProvider'], $provider->getFactory()); - - $tracer = $container->getDefinition('open_telemetry.traces.tracers.main'); - self::assertEquals([ - new Reference('open_telemetry.traces.providers.default'), - 'getTracer', - ], $tracer->getFactory()); - } - - public function testTracingInstrumentation(): void - { - $container = $this->getContainer('tracing-instrumentation'); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.cache.tracing.enabled')); - - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.cache.trace.adapter')); - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.cache.trace.tag_aware_adapter')); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.console.tracing.enabled')); - - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.console.trace.event_subscriber')); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.doctrine.tracing.enabled')); - - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.doctrine.trace.event_subscriber')); - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.doctrine.trace.middleware')); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.http_client.tracing.enabled')); - - // ToDo: Add http_client service definition - // self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.http_client.trace.client')); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.http_kernel.tracing.enabled')); - - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.http_kernel.trace.event_subscriber')); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.mailer.tracing.enabled')); - - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.mailer.trace.event_subscriber')); - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.mailer.trace.default_transport')); - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.mailer.trace.mailer')); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.messenger.tracing.enabled')); - - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.event_subscriber')); - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.transport')); - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.transport_factory')); - self::assertTrue($container->hasAlias('messenger.transport.open_telemetry_tracer.factory')); - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.messenger.trace.middleware')); - self::assertTrue($container->hasAlias('messenger.middleware.open_telemetry_tracer')); - - self::assertTrue($container->getParameter('open_telemetry.instrumentation.twig.tracing.enabled')); - - self::assertTrue($container->hasDefinition('open_telemetry.instrumentation.twig.trace.extension')); - } - - protected function getContainer(string $fixture): ContainerBuilder - { - $container = new ContainerBuilder(); - $container->registerExtension(new OpenTelemetryExtension()); - - $this->loadFixture($container, $fixture); - - $container->getCompilerPassConfig()->setOptimizationPasses([]); - $container->getCompilerPassConfig()->setRemovingPasses([]); - - $container->addCompilerPass(new CachePoolTracingPass()); - $container->addCompilerPass(new RemoveConsoleInstrumentationPass()); - $container->addCompilerPass(new RemoveDoctrineInstrumentationPass()); - $container->addCompilerPass(new HttpClientTracingPass()); - $container->addCompilerPass(new RemoveHttpKernelInstrumentationPass()); - $container->addCompilerPass(new RemoveMailerInstrumentationPass()); - $container->addCompilerPass(new RemoveMessengerInstrumentationPass()); - $container->addCompilerPass(new RemoveTwigInstrumentationPass()); - - $container->compile(); - - return $container; - } - - abstract protected function loadFixture(ContainerBuilder $container, string $fixture): void; -} diff --git a/tests/Unit/DependencyInjection/YamlOpenTelemetryExtensionTest.php b/tests/Unit/DependencyInjection/YamlOpenTelemetryExtensionTest.php deleted file mode 100644 index 0473a7f..0000000 --- a/tests/Unit/DependencyInjection/YamlOpenTelemetryExtensionTest.php +++ /dev/null @@ -1,16 +0,0 @@ -load($fixture.'.yml'); - } -} diff --git a/tests/Unit/EventSubscriber/ConsoleEventSubscriberTest.php b/tests/Unit/EventSubscriber/ConsoleEventSubscriberTest.php index 66f5a44..5b063ec 100644 --- a/tests/Unit/EventSubscriber/ConsoleEventSubscriberTest.php +++ b/tests/Unit/EventSubscriber/ConsoleEventSubscriberTest.php @@ -10,15 +10,15 @@ use OpenTelemetry\Context\ContextStorageScopeInterface; use OpenTelemetry\SDK\Trace\StatusData; use OpenTelemetry\SDK\Trace\TracerProvider; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\Symfony\Console\TraceableConsoleEventSubscriber - */ +#[CoversClass(TraceableConsoleEventSubscriber::class)] final class ConsoleEventSubscriberTest extends TestCase { private readonly TracerInterface $tracer; @@ -43,16 +43,14 @@ protected function tearDown(): void /** * @return array */ - public function consoleCommandEventDataProvider(): array + public static function consoleCommandEventDataProvider(): array { return [ [new ConsoleCommandEvent(new DummyCommand(), new ArrayInput([]), new NullOutput())], ]; } - /** - * @dataProvider consoleCommandEventDataProvider - */ + #[DataProvider('consoleCommandEventDataProvider')] public function testHandleCommandEvent(ConsoleCommandEvent $event): void { $subscriber = new TraceableConsoleEventSubscriber($this->tracer); diff --git a/tests/Unit/OpenTelemetry/Exporter/ConsoleExporterEndpointTest.php b/tests/Unit/OpenTelemetry/Exporter/ConsoleExporterEndpointTest.php index f604644..c81dba9 100644 --- a/tests/Unit/OpenTelemetry/Exporter/ConsoleExporterEndpointTest.php +++ b/tests/Unit/OpenTelemetry/Exporter/ConsoleExporterEndpointTest.php @@ -4,16 +4,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ConsoleExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ConsoleExporterEndpoint - */ +#[CoversClass(ConsoleExporterEndpoint::class)] class ConsoleExporterEndpointTest extends TestCase { - /** - * @dataProvider dsnProvider - */ + #[DataProvider('dsnProvider')] public function testFromDsn(string $dsn, string $endpoint): void { self::assertSame($endpoint, (string) ConsoleExporterEndpoint::fromDsn(ExporterDsn::fromString($dsn))); @@ -22,7 +20,7 @@ public function testFromDsn(string $dsn, string $endpoint): void /** * @return \Generator */ - public function dsnProvider(): \Generator + public static function dsnProvider(): \Generator { yield [ 'stream+console://default', diff --git a/tests/Unit/OpenTelemetry/Exporter/OtlpExporterEndpointTest.php b/tests/Unit/OpenTelemetry/Exporter/OtlpExporterEndpointTest.php index 0d4f608..d6a0e49 100644 --- a/tests/Unit/OpenTelemetry/Exporter/OtlpExporterEndpointTest.php +++ b/tests/Unit/OpenTelemetry/Exporter/OtlpExporterEndpointTest.php @@ -5,16 +5,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterEndpoint; use OpenTelemetry\API\Signals; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterEndpoint - */ +#[CoversClass(OtlpExporterEndpoint::class)] class OtlpExporterEndpointTest extends TestCase { - /** - * @dataProvider dsnProvider - */ + #[DataProvider('dsnProvider')] public function testFromDsn(string $dsn, string $endpoint, string $signal): void { self::assertSame($endpoint, (string) OtlpExporterEndpoint::fromDsn(ExporterDsn::fromString($dsn))->withSignal($signal)); @@ -23,7 +21,7 @@ public function testFromDsn(string $dsn, string $endpoint, string $signal): void /** * @return \Generator */ - public function dsnProvider(): \Generator + public static function dsnProvider(): \Generator { yield [ 'http+otlp://localhost', diff --git a/tests/Unit/OpenTelemetry/Exporter/OtlpExporterOptionsTest.php b/tests/Unit/OpenTelemetry/Exporter/OtlpExporterOptionsTest.php index 1b942b6..cd93d2c 100644 --- a/tests/Unit/OpenTelemetry/Exporter/OtlpExporterOptionsTest.php +++ b/tests/Unit/OpenTelemetry/Exporter/OtlpExporterOptionsTest.php @@ -6,6 +6,8 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterCompressionEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterFormatEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterOptions; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; /** @@ -13,6 +15,7 @@ * * @phpstan-import-type ExporterOptions from ExporterOptionsInterface */ +#[CoversClass(OtlpExporterOptions::class)] class OtlpExporterOptionsTest extends TestCase { public function testDefault(): void @@ -33,11 +36,10 @@ public function testDefault(): void } /** - * @dataProvider configurationProvider - * * @param array&ExporterOptions $configuration * @param callable(OtlpExporterOptions): void $assertion */ + #[DataProvider('configurationProvider')] public function testFromConfiguration(array $configuration, callable $assertion): void { $options = OtlpExporterOptions::fromConfiguration($configuration); @@ -51,7 +53,7 @@ public function testFromConfiguration(array $configuration, callable $assertion) * 1: callable(OtlpExporterOptions): void * }> */ - public function configurationProvider(): \Generator + public static function configurationProvider(): \Generator { yield [ ['format' => 'ndjson'], diff --git a/tests/Unit/OpenTelemetry/Log/LogExporter/ConsoleLogExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LogExporter/ConsoleLogExporterFactoryTest.php index b62e102..506659a 100644 --- a/tests/Unit/OpenTelemetry/Log/LogExporter/ConsoleLogExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Log/LogExporter/ConsoleLogExporterFactoryTest.php @@ -6,24 +6,26 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\ConsoleLogExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\StreamTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\SDK\Common\Export\Stream\StreamTransport; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\ConsoleLogExporterFactory - */ +#[CoversClass(ConsoleLogExporterFactory::class)] class ConsoleLogExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?\Exception $exception): void { if (null !== $exception) { self::expectExceptionObject($exception); } - $exporter = ConsoleLogExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new ConsoleLogExporterFactory(new TransportFactory([ + new StreamTransportFactory(), + ])))->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $transport = $reflection->getProperty('transport'); @@ -34,7 +36,7 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'stream+console://default', @@ -58,25 +60,25 @@ public function exporterProvider(): \Generator yield [ 'in-memory://default', new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'http+otlp://default', new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'grpc+otlp://default', new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'noop://default', new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; } } diff --git a/tests/Unit/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactoryTest.php index 87a47d2..c2c28a2 100644 --- a/tests/Unit/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Log/LogExporter/InMemoryLogExporterFactoryTest.php @@ -6,16 +6,15 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\InMemoryLogExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\InMemoryLogExporterFactory - */ +#[CoversClass(InMemoryLogExporterFactory::class)] class InMemoryLogExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?\Exception $exception): void { if (null !== $exception) { @@ -24,13 +23,13 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option $this->expectNotToPerformAssertions(); - InMemoryLogExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + (new InMemoryLogExporterFactory(new TransportFactory([])))->createExporter(ExporterDsn::fromString($dsn), $options); } /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'in-memory://default', diff --git a/tests/Unit/OpenTelemetry/Log/LogExporter/LogExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LogExporter/LogExporterFactoryTest.php new file mode 100644 index 0000000..90baa03 --- /dev/null +++ b/tests/Unit/OpenTelemetry/Log/LogExporter/LogExporterFactoryTest.php @@ -0,0 +1,116 @@ +getTransportFactory()), + new InMemoryLogExporterFactory($this->getTransportFactory()), + new NoopLogExporterFactory($this->getTransportFactory()), + new OtlpLogExporterFactory($this->getTransportFactory()), + ])); + + $exporter = $exporterFactory->createExporter(ExporterDsn::fromString($dsn), $options); + + self::assertInstanceOf($exporterClass, $exporter); + + if (null !== $transportClass) { + $reflection = new \ReflectionObject($exporter); + $transport = $reflection->getProperty('transport'); + + self::assertInstanceOf($transportClass, $transport->getValue($exporter)); + } + } + + /** + * @return \Generator, + * 3: ?class-string>, + * }> + */ + public static function exporterProvider(): \Generator + { + yield [ + 'stream+console://default', + new EmptyExporterOptions(), + ConsoleExporter::class, + StreamTransport::class, + ]; + + yield [ + 'in-memory://default', + new EmptyExporterOptions(), + InMemoryExporter::class, + null, + ]; + + yield [ + 'noop://default', + new EmptyExporterOptions(), + NoopExporter::class, + null, + ]; + + yield [ + 'http+otlp://default', + new OtlpExporterOptions(), + LogsExporter::class, + PsrTransport::class, + ]; + + yield [ + 'grpc+otlp://default', + new OtlpExporterOptions(), + LogsExporter::class, + GrpcTransport::class, + ]; + } +} diff --git a/tests/Unit/OpenTelemetry/Log/LogExporter/NoopLogExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LogExporter/NoopLogExporterFactoryTest.php index d6bd5b4..7ae92f0 100644 --- a/tests/Unit/OpenTelemetry/Log/LogExporter/NoopLogExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Log/LogExporter/NoopLogExporterFactoryTest.php @@ -6,16 +6,15 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\NoopLogExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\NoopLogExporterFactory - */ +#[CoversClass(NoopLogExporterFactory::class)] class NoopLogExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?\Exception $exception): void { if (null !== $exception) { @@ -24,13 +23,13 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option $this->expectNotToPerformAssertions(); - NoopLogExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + (new NoopLogExporterFactory(new TransportFactory([])))->createExporter(ExporterDsn::fromString($dsn), $options); } /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'noop://default', diff --git a/tests/Unit/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactoryTest.php index 412ea6b..c4bae1f 100644 --- a/tests/Unit/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Log/LogExporter/OtlpLogExporterFactoryTest.php @@ -6,21 +6,23 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterOptions; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\OtlpLogExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\GrpcTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\PsrHttpTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\Contrib\Grpc\GrpcTransport; use OpenTelemetry\SDK\Common\Export\Http\PsrTransport; use OpenTelemetry\SDK\Common\Export\TransportInterface; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\OtlpLogExporterFactory - */ +#[CoversClass(OtlpLogExporterFactory::class)] class OtlpLogExporterFactoryTest extends TestCase { /** - * @dataProvider exporterProvider - * * @param ?class-string> $transportClass */ + #[DataProvider('exporterProvider')] public function testCreateExporter( string $dsn, ExporterOptionsInterface $options, @@ -31,7 +33,11 @@ public function testCreateExporter( self::expectExceptionObject($exception); } - $exporter = OtlpLogExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new OtlpLogExporterFactory(new TransportFactory([ + new GrpcTransportFactory(), + new PsrHttpTransportFactory(), + ]))) + ->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $transport = $reflection->getProperty('transport'); @@ -47,7 +53,7 @@ public function testCreateExporter( * 3: ?\Exception, * }> */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'http+otlp://default', diff --git a/tests/Unit/OpenTelemetry/Log/LogExporterEndpointTest.php b/tests/Unit/OpenTelemetry/Log/LogExporterEndpointTest.php index d62b338..2496ceb 100644 --- a/tests/Unit/OpenTelemetry/Log/LogExporterEndpointTest.php +++ b/tests/Unit/OpenTelemetry/Log/LogExporterEndpointTest.php @@ -4,16 +4,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporterEndpoint; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporterEndpoint - */ +#[CoversClass(LogExporterEndpoint::class)] class LogExporterEndpointTest extends TestCase { - /** - * @dataProvider dsnProvider - */ + #[DataProvider('dsnProvider')] public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $exception): void { if (null !== $exception) { @@ -30,7 +28,7 @@ public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $excepti * 2: ?\Exception, * }> */ - public function dsnProvider(): \Generator + public static function dsnProvider(): \Generator { yield [ 'http+otlp://localhost', diff --git a/tests/Unit/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactoryTest.php index 43406e3..6c6dab8 100644 --- a/tests/Unit/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Log/LogProcessor/SimpleLogProcessorFactoryTest.php @@ -2,8 +2,11 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Unit\OpenTelemetry\Log\LogProcessor; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\EmptyExporterOptions; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogExporter\NoopLogExporterFactory; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogProcessor\SimpleLogProcessorFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use PHPUnit\Framework\TestCase; /** @@ -13,7 +16,14 @@ class SimpleLogProcessorFactoryTest extends TestCase { public function testCreateProcessor(): void { - SimpleLogProcessorFactory::createProcessor(exporter: NoopLogExporterFactory::createExporter()); + SimpleLogProcessorFactory::createProcessor( + [], + (new NoopLogExporterFactory(new TransportFactory([]))) + ->createExporter( + ExporterDsn::fromString('null://default'), + EmptyExporterOptions::fromConfiguration([]), + ), + ); self::expectExceptionObject(new \InvalidArgumentException('Exporter is null')); diff --git a/tests/Unit/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryTest.php index b6e21a4..29bd1f3 100644 --- a/tests/Unit/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Log/LoggerProvider/LoggerProviderFactoryTest.php @@ -2,12 +2,12 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Unit\OpenTelemetry\Log\LoggerProvider; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\LoggerProviderFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\DefaultLoggerProviderFactory; use OpenTelemetry\SDK\Logs\Processor\NoopLogRecordProcessor; use PHPUnit\Framework\TestCase; /** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\LoggerProviderFactory + * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\DefaultLoggerProviderFactory */ class LoggerProviderFactoryTest extends TestCase { @@ -15,6 +15,6 @@ public function testCreateProvider(): void { self::expectNotToPerformAssertions(); - LoggerProviderFactory::createProvider(new NoopLogRecordProcessor()); + (new DefaultLoggerProviderFactory())->createProvider(new NoopLogRecordProcessor()); } } diff --git a/tests/Unit/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactoryTest.php b/tests/Unit/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactoryTest.php index bca4d80..158d67b 100644 --- a/tests/Unit/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Log/LoggerProvider/NoopLoggerProviderFactoryTest.php @@ -15,6 +15,6 @@ public function testCreateProvider(): void { self::expectNotToPerformAssertions(); - NoopLoggerProviderFactory::createProvider(new NoopLogRecordProcessor()); + (new NoopLoggerProviderFactory())->createProvider(new NoopLogRecordProcessor()); } } diff --git a/tests/Unit/OpenTelemetry/Metric/MeterProvider/MeterProviderFactoryTest.php b/tests/Unit/OpenTelemetry/Metric/MeterProvider/MeterProviderFactoryTest.php index 0bd9231..e9b997d 100644 --- a/tests/Unit/OpenTelemetry/Metric/MeterProvider/MeterProviderFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Metric/MeterProvider/MeterProviderFactoryTest.php @@ -2,13 +2,16 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Unit\OpenTelemetry\Metric\MeterProvider; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\MeterProviderFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\EmptyExporterOptions; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\DefaultMeterProviderFactory; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\NoopMetricExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\NoneExemplarFilter; use PHPUnit\Framework\TestCase; /** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\MeterProviderFactory + * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\DefaultMeterProviderFactory */ class MeterProviderFactoryTest extends TestCase { @@ -16,8 +19,11 @@ public function testCreateProvider(): void { self::expectNotToPerformAssertions(); - MeterProviderFactory::createProvider( - NoopMetricExporterFactory::createExporter(), + DefaultMeterProviderFactory::createProvider( + (new NoopMetricExporterFactory(new TransportFactory([])))->createExporter( + ExporterDsn::fromString('null://default'), + EmptyExporterOptions::fromConfiguration([]), + ), new NoneExemplarFilter(), ); } diff --git a/tests/Unit/OpenTelemetry/Metric/MetricExporter/ConsoleMetricExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Metric/MetricExporter/ConsoleMetricExporterFactoryTest.php index 79d2e4f..ee077e6 100644 --- a/tests/Unit/OpenTelemetry/Metric/MetricExporter/ConsoleMetricExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Metric/MetricExporter/ConsoleMetricExporterFactoryTest.php @@ -7,24 +7,23 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\ConsoleMetricExporterFactory; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\MetricTemporalityEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\SDK\Metrics\Data\Temporality; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\ConsoleMetricExporterFactory - */ +#[CoversClass(ConsoleMetricExporterFactory::class)] class ConsoleMetricExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?string $temporality, ?\Exception $exception): void { if (null !== $exception) { self::expectExceptionObject($exception); } - $exporter = ConsoleMetricExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new ConsoleMetricExporterFactory(new TransportFactory([])))->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $reflectedTemporality = $reflection->getProperty('temporality'); @@ -40,7 +39,7 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option * 3: ?\Exception, * }> */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'stream+console://default', diff --git a/tests/Unit/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactoryTest.php index 77ab00a..e47764a 100644 --- a/tests/Unit/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Metric/MetricExporter/InMemoryMetricExporterFactoryTest.php @@ -7,24 +7,23 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\InMemoryMetricExporterFactory; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\MetricTemporalityEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\SDK\Metrics\Data\Temporality; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\InMemoryMetricExporterFactory - */ +#[CoversClass(InMemoryMetricExporterFactory::class)] class InMemoryMetricExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?string $temporality, ?\Exception $exception): void { if (null !== $exception) { self::expectExceptionObject($exception); } - $exporter = InMemoryMetricExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new InMemoryMetricExporterFactory(new TransportFactory([])))->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $reflectedTemporality = $reflection->getProperty('temporality'); @@ -40,7 +39,7 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option * 3: ?\Exception, * }> */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'stream+console://default', diff --git a/tests/Unit/OpenTelemetry/Metric/MetricExporter/MetricExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Metric/MetricExporter/MetricExporterFactoryTest.php new file mode 100644 index 0000000..4442aa9 --- /dev/null +++ b/tests/Unit/OpenTelemetry/Metric/MetricExporter/MetricExporterFactoryTest.php @@ -0,0 +1,115 @@ +getTransportFactory()), + new InMemoryMetricExporterFactory($this->getTransportFactory()), + new NoopMetricExporterFactory($this->getTransportFactory()), + new OtlpMetricExporterFactory($this->getTransportFactory()), + ])); + + $exporter = $exporterFactory->createExporter(ExporterDsn::fromString($dsn), $options); + + self::assertInstanceOf($exporterClass, $exporter); + + if (null !== $transportClass) { + $reflection = new \ReflectionObject($exporter); + $transport = $reflection->getProperty('transport'); + + self::assertInstanceOf($transportClass, $transport->getValue($exporter)); + } + } + + /** + * @return \Generator, + * 3: ?class-string>, + * }> + */ + public static function exporterProvider(): \Generator + { + yield [ + 'stream+console://default', + new MetricExporterOptions(), + ConsoleMetricExporter::class, + // This exporter has no transport + null, + ]; + + yield [ + 'in-memory://default', + new MetricExporterOptions(), + InMemoryExporter::class, + null, + ]; + + yield [ + 'noop://default', + new MetricExporterOptions(), + NoopMetricExporter::class, + null, + ]; + + yield [ + 'http+otlp://default', + new MetricExporterOptions(), + MetricExporter::class, + PsrTransport::class, + ]; + + yield [ + 'grpc+otlp://default', + new MetricExporterOptions(), + MetricExporter::class, + GrpcTransport::class, + ]; + } +} diff --git a/tests/Unit/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactoryTest.php index 46ce30c..b8f7f68 100644 --- a/tests/Unit/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Metric/MetricExporter/NoopMetricExporterFactoryTest.php @@ -6,16 +6,15 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\NoopMetricExporterFactory; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\NoopMetricExporterFactory - */ +#[CoversClass(NoopMetricExporterFactory::class)] class NoopMetricExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?\Exception $exception): void { if (null !== $exception) { @@ -24,7 +23,7 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option self::expectNotToPerformAssertions(); } - NoopMetricExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + (new NoopMetricExporterFactory(new TransportFactory([])))->createExporter(ExporterDsn::fromString($dsn), $options); } /** @@ -34,7 +33,7 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option * 2: ?\Exception, * }> */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'stream+console://default', diff --git a/tests/Unit/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactoryTest.php index 2b32b27..97536be 100644 --- a/tests/Unit/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Metric/MetricExporter/OtlpMetricExporterFactoryTest.php @@ -6,24 +6,28 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\OtlpMetricExporterFactory; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\GrpcTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\OtlpHttpTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\SDK\Metrics\Data\Temporality; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\OtlpMetricExporterFactory - */ +#[CoversClass(OtlpMetricExporterFactory::class)] class OtlpMetricExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?string $temporality, ?\Exception $exception): void { if (null !== $exception) { self::expectExceptionObject($exception); } - $exporter = OtlpMetricExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new OtlpMetricExporterFactory(new TransportFactory([ + new GrpcTransportFactory(), + new OtlpHttpTransportFactory(), + ])))->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $reflectedTemporality = $reflection->getProperty('temporality'); @@ -39,7 +43,7 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option * 3: ?\Exception, * }> */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'http+otlp://default', @@ -59,21 +63,21 @@ public function exporterProvider(): \Generator 'noop://default', new MetricExporterOptions(), null, - new \InvalidArgumentException('DSN exporter must be of type Otlp.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'stream+console://default', new MetricExporterOptions(), null, - new \InvalidArgumentException('DSN exporter must be of type Otlp.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'in-memory://default', new MetricExporterOptions(), null, - new \InvalidArgumentException('DSN exporter must be of type Otlp.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ diff --git a/tests/Unit/OpenTelemetry/Metric/MetricExporterEndpointTest.php b/tests/Unit/OpenTelemetry/Metric/MetricExporterEndpointTest.php index f17204d..aa2d111 100644 --- a/tests/Unit/OpenTelemetry/Metric/MetricExporterEndpointTest.php +++ b/tests/Unit/OpenTelemetry/Metric/MetricExporterEndpointTest.php @@ -4,16 +4,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterEndpoint; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterEndpoint - */ +#[CoversClass(MetricExporterEndpoint::class)] class MetricExporterEndpointTest extends TestCase { - /** - * @dataProvider dsnProvider - */ + #[DataProvider('dsnProvider')] public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $exception): void { if (null !== $exception) { @@ -30,7 +28,7 @@ public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $excepti * 2: ?\Exception, * }> */ - public function dsnProvider(): \Generator + public static function dsnProvider(): \Generator { yield [ 'http+otlp://localhost', diff --git a/tests/Unit/OpenTelemetry/Metric/MetricExporterOptionsTest.php b/tests/Unit/OpenTelemetry/Metric/MetricExporterOptionsTest.php index 135751d..3210673 100644 --- a/tests/Unit/OpenTelemetry/Metric/MetricExporterOptionsTest.php +++ b/tests/Unit/OpenTelemetry/Metric/MetricExporterOptionsTest.php @@ -7,13 +7,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterFormatEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\MetricTemporalityEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; /** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions - * * @phpstan-import-type ExporterOptions from ExporterOptionsInterface */ +#[CoversClass(MetricExporterOptions::class)] class MetricExporterOptionsTest extends TestCase { public function testDefault(): void @@ -37,11 +38,10 @@ public function testDefault(): void } /** - * @dataProvider configurationProvider - * * @param array&ExporterOptions $configuration * @param callable(MetricExporterOptions): void $assertion */ + #[DataProvider('configurationProvider')] public function testFromConfiguration(array $configuration, callable $assertion): void { $options = MetricExporterOptions::fromConfiguration($configuration); @@ -55,7 +55,7 @@ public function testFromConfiguration(array $configuration, callable $assertion) * 1: callable(MetricExporterOptions): void * }> */ - public function configurationProvider(): \Generator + public static function configurationProvider(): \Generator { yield [ ['temporality' => 'cumulative'], diff --git a/tests/Unit/OpenTelemetry/Trace/SamplerFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/SamplerFactoryTest.php new file mode 100644 index 0000000..5671f66 --- /dev/null +++ b/tests/Unit/OpenTelemetry/Trace/SamplerFactoryTest.php @@ -0,0 +1,79 @@ +getDescription()); + } + + /** + * @return \Generator, + * 2: string, + * 3: float|null, + * }> + */ + public static function samplerProvider(): \Generator + { + yield [ + 'always_off', + AlwaysOffSampler::class, + 'AlwaysOffSampler', + null, + ]; + + yield [ + 'always_on', + AlwaysOnSampler::class, + 'AlwaysOnSampler', + null, + ]; + + yield [ + 'parent_based_always_off', + ParentBased::class, + 'ParentBased+AlwaysOffSampler', + null, + ]; + + yield [ + 'parent_based_always_on', + ParentBased::class, + 'ParentBased+AlwaysOnSampler', + null, + ]; + + yield [ + 'parent_based_trace_id_ratio', + ParentBased::class, + 'ParentBased+TraceIdRatioBasedSampler{0.600000}', + 0.6, + ]; + + yield [ + 'trace_id_ratio', + TraceIdRatioBasedSampler::class, + 'TraceIdRatioBasedSampler{0.200000}', + 0.2, + ]; + } +} diff --git a/tests/Unit/OpenTelemetry/Trace/SpanExporter/ConsoleSpanExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/SpanExporter/ConsoleSpanExporterFactoryTest.php index 34ec857..4345139 100644 --- a/tests/Unit/OpenTelemetry/Trace/SpanExporter/ConsoleSpanExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Trace/SpanExporter/ConsoleSpanExporterFactoryTest.php @@ -6,24 +6,26 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\ConsoleSpanExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\StreamTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\SDK\Common\Export\Stream\StreamTransport; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\ConsoleSpanExporterFactory - */ +#[CoversClass(ConsoleSpanExporterFactory::class)] class ConsoleSpanExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?\Exception $exception): void { if (null !== $exception) { self::expectExceptionObject($exception); } - $exporter = ConsoleSpanExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new ConsoleSpanExporterFactory(new TransportFactory([ + new StreamTransportFactory(), + ])))->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $transport = $reflection->getProperty('transport'); @@ -34,7 +36,7 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'stream+console://default', @@ -43,10 +45,9 @@ public function exporterProvider(): \Generator ]; yield [ - // This DSN is valid but given the context of the transport, the failure is expected. - 'stream+console://default/var/log/symfony.log', + 'stream+console://default/tmp/symfony.log', new EmptyExporterOptions(), - new \ErrorException('fopen(/var/log/symfony.log): Failed to open stream: Permission denied'), + null, ]; yield [ @@ -58,19 +59,19 @@ public function exporterProvider(): \Generator yield [ 'in-memory://default', new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'http+otlp://default', new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'grpc+otlp://default', new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ diff --git a/tests/Unit/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactoryTest.php index da93018..4aa37b7 100644 --- a/tests/Unit/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Trace/SpanExporter/InMemorySpanExporterFactoryTest.php @@ -6,16 +6,15 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\InMemorySpanExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\InMemorySpanExporterFactory - */ +#[CoversClass(InMemorySpanExporterFactory::class)] class InMemorySpanExporterFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateExporter(string $dsn, ExporterOptionsInterface $options, ?\Exception $exception): void { if (null !== $exception) { @@ -24,13 +23,13 @@ public function testCreateExporter(string $dsn, ExporterOptionsInterface $option $this->expectNotToPerformAssertions(); - InMemorySpanExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + (new InMemorySpanExporterFactory(new TransportFactory([])))->createExporter(ExporterDsn::fromString($dsn), $options); } /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'in-memory://default', diff --git a/tests/Unit/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactoryTest.php index 0008979..ab888fe 100644 --- a/tests/Unit/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Trace/SpanExporter/OtlpSpanExporterFactoryTest.php @@ -6,21 +6,23 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterOptions; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\OtlpSpanExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\GrpcTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\OtlpHttpTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\Contrib\Grpc\GrpcTransport; use OpenTelemetry\SDK\Common\Export\Http\PsrTransport; use OpenTelemetry\SDK\Common\Export\TransportInterface; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\OtlpSpanExporterFactory - */ +#[CoversClass(OtlpSpanExporterFactory::class)] class OtlpSpanExporterFactoryTest extends TestCase { /** - * @dataProvider exporterProvider - * * @param ?class-string> $transportClass */ + #[DataProvider('exporterProvider')] public function testCreateExporter( string $dsn, ExporterOptionsInterface $options, @@ -31,7 +33,10 @@ public function testCreateExporter( self::expectExceptionObject($exception); } - $exporter = OtlpSpanExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new OtlpSpanExporterFactory(new TransportFactory([ + new GrpcTransportFactory(), + new OtlpHttpTransportFactory(), + ])))->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $transport = $reflection->getProperty('transport'); @@ -47,7 +52,7 @@ public function testCreateExporter( * 3: ?\Exception, * }> */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'http+otlp://default', @@ -67,21 +72,21 @@ public function exporterProvider(): \Generator 'stream+console://default', new OtlpExporterOptions(), null, - new \InvalidArgumentException('DSN exporter must be of type Otlp.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'http+zipkin://default', new OtlpExporterOptions(), null, - new \InvalidArgumentException('DSN exporter must be of type Otlp.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ 'in-memory://default', new OtlpExporterOptions(), null, - new \InvalidArgumentException('DSN exporter must be of type Otlp.'), + new \InvalidArgumentException('No transport supports the given endpoint.'), ]; yield [ diff --git a/tests/Unit/OpenTelemetry/Trace/SpanExporter/SpanExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/SpanExporter/SpanExporterFactoryTest.php new file mode 100644 index 0000000..4bf23d2 --- /dev/null +++ b/tests/Unit/OpenTelemetry/Trace/SpanExporter/SpanExporterFactoryTest.php @@ -0,0 +1,116 @@ +getTransportFactory()), + new InMemorySpanExporterFactory($this->getTransportFactory()), + new OtlpSpanExporterFactory($this->getTransportFactory()), + new ZipkinSpanExporterFactory($this->getTransportFactory()), + ])); + + $exporter = $exporterFactory->createExporter(ExporterDsn::fromString($dsn), $options); + + self::assertInstanceOf($exporterClass, $exporter); + + if (null !== $transportClass) { + $reflection = new \ReflectionObject($exporter); + $transport = $reflection->getProperty('transport'); + + self::assertInstanceOf($transportClass, $transport->getValue($exporter)); + } + } + + /** + * @return \Generator, + * 3: ?class-string>, + * }> + */ + public static function exporterProvider(): \Generator + { + yield [ + 'stream+console://default', + new EmptyExporterOptions(), + ConsoleSpanExporter::class, + // This exporter has no transport + null, + ]; + + yield [ + 'in-memory://default', + new EmptyExporterOptions(), + InMemoryExporter::class, + null, + ]; + + yield [ + 'http+otlp://default', + new OtlpExporterOptions(), + SpanExporter::class, + PsrTransport::class, + ]; + + yield [ + 'grpc+otlp://default', + new OtlpExporterOptions(), + SpanExporter::class, + GrpcTransport::class, + ]; + + yield [ + 'http+zipkin://default', + new EmptyExporterOptions(), + ZipkinExporter::class, + PsrTransport::class, + ]; + } +} diff --git a/tests/Unit/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactoryTest.php index 2f90fe2..5185a24 100644 --- a/tests/Unit/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Trace/SpanExporter/ZipkinSpanExporterFactoryTest.php @@ -6,20 +6,21 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterOptions; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\ZipkinSpanExporterFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\PsrHttpTransportFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use OpenTelemetry\SDK\Common\Export\Http\PsrTransport; use OpenTelemetry\SDK\Common\Export\TransportInterface; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\ZipkinSpanExporterFactory - */ +#[CoversClass(ZipkinSpanExporterFactory::class)] class ZipkinSpanExporterFactoryTest extends TestCase { /** - * @dataProvider exporterProvider - * * @param ?class-string> $transportClass */ + #[DataProvider('exporterProvider')] public function testCreateExporter( string $dsn, ExporterOptionsInterface $options, @@ -30,7 +31,9 @@ public function testCreateExporter( self::expectExceptionObject($exception); } - $exporter = ZipkinSpanExporterFactory::createExporter(ExporterDsn::fromString($dsn), $options); + $exporter = (new ZipkinSpanExporterFactory(new TransportFactory([ + new PsrHttpTransportFactory(), + ])))->createExporter(ExporterDsn::fromString($dsn), $options); $reflection = new \ReflectionObject($exporter); $transport = $reflection->getProperty('transport'); @@ -46,7 +49,7 @@ public function testCreateExporter( * 3: ?\Exception, * }> */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ 'http+zipkin://default', diff --git a/tests/Unit/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactoryTest.php index 09d0308..eaafa7c 100644 --- a/tests/Unit/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Trace/SpanProcessor/SimpleSpanProcessorFactoryTest.php @@ -2,8 +2,11 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Unit\OpenTelemetry\Trace\SpanProcessor; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\EmptyExporterOptions; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\InMemorySpanExporterFactory; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanProcessor\SimpleSpanProcessorFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportFactory; use PHPUnit\Framework\TestCase; /** @@ -13,7 +16,13 @@ class SimpleSpanProcessorFactoryTest extends TestCase { public function testCreateProcessor(): void { - SimpleSpanProcessorFactory::createProcessor(exporter: InMemorySpanExporterFactory::createExporter()); + SimpleSpanProcessorFactory::createProcessor( + [], + (new InMemorySpanExporterFactory(new TransportFactory([]))) + ->createExporter( + ExporterDsn::fromString('null://default'), + EmptyExporterOptions::fromConfiguration([]), + )); self::expectExceptionObject(new \InvalidArgumentException('Exporter is null')); diff --git a/tests/Unit/OpenTelemetry/Trace/TraceExporterEndpointTest.php b/tests/Unit/OpenTelemetry/Trace/TraceExporterEndpointTest.php index 3cc1195..b366c2f 100644 --- a/tests/Unit/OpenTelemetry/Trace/TraceExporterEndpointTest.php +++ b/tests/Unit/OpenTelemetry/Trace/TraceExporterEndpointTest.php @@ -4,16 +4,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint - */ +#[CoversClass(TraceExporterEndpoint::class)] class TraceExporterEndpointTest extends TestCase { - /** - * @dataProvider dsnProvider - */ + #[DataProvider('dsnProvider')] public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $exception): void { if (null !== $exception) { @@ -30,7 +28,7 @@ public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $excepti * 2: ?\Exception * }> */ - public function dsnProvider(): \Generator + public static function dsnProvider(): \Generator { yield [ 'http+otlp://localhost', diff --git a/tests/Unit/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryTest.php b/tests/Unit/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryTest.php index 2230ae2..f1a7737 100644 --- a/tests/Unit/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Trace/TracerProvider/TracerProviderFactoryTest.php @@ -3,20 +3,20 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Tests\Unit\OpenTelemetry\Trace\TracerProvider; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanProcessor\NoopSpanProcessorFactory; -use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\TracerProviderFactory; +use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\DefaultTracerProviderFactory; use PHPUnit\Framework\TestCase; /** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\TracerProviderFactory + * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TracerProvider\DefaultTracerProviderFactory */ class TracerProviderFactoryTest extends TestCase { public function testCreateProvider(): void { - TracerProviderFactory::createProvider(processors: [NoopSpanProcessorFactory::createProcessor()]); + DefaultTracerProviderFactory::createProvider(processors: [NoopSpanProcessorFactory::createProcessor()]); self::expectExceptionObject(new \InvalidArgumentException('Processors should not be empty')); - TracerProviderFactory::createProvider(); + DefaultTracerProviderFactory::createProvider(); } } diff --git a/tests/Unit/OpenTelemetry/Trace/ZipkinExporterEndpointTest.php b/tests/Unit/OpenTelemetry/Trace/ZipkinExporterEndpointTest.php index c6372be..1858656 100644 --- a/tests/Unit/OpenTelemetry/Trace/ZipkinExporterEndpointTest.php +++ b/tests/Unit/OpenTelemetry/Trace/ZipkinExporterEndpointTest.php @@ -4,16 +4,14 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\ZipkinExporterEndpoint; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint - */ +#[CoversClass(ZipkinExporterEndpoint::class)] class ZipkinExporterEndpointTest extends TestCase { - /** - * @dataProvider dsnProvider - */ + #[DataProvider('dsnProvider')] public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $exception): void { if (null !== $exception) { @@ -30,7 +28,7 @@ public function testFromDsn(string $dsn, ?string $endpoint, ?\Exception $excepti * 2: ?\Exception * }> */ - public function dsnProvider(): \Generator + public static function dsnProvider(): \Generator { yield [ 'http+zipkin://localhost', diff --git a/tests/Unit/OpenTelemetry/Transport/GrpcTransportFactoryTest.php b/tests/Unit/OpenTelemetry/Transport/GrpcTransportFactoryTest.php index 9c31a0a..7f7f052 100644 --- a/tests/Unit/OpenTelemetry/Transport/GrpcTransportFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Transport/GrpcTransportFactoryTest.php @@ -12,75 +12,71 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporterOptions; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\GrpcTransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\GrpcTransportFactory - */ +#[CoversClass(GrpcTransportFactory::class)] class GrpcTransportFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateTransportFromExporter( ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options, - ?\Exception $exception, + bool $shouldSupport, ): void { - if (null !== $exception) { - self::expectExceptionObject($exception); - } else { - $this->expectNotToPerformAssertions(); - } + $factory = new GrpcTransportFactory(); - $factory = GrpcTransportFactory::fromExporter($endpoint, $options); + self::assertSame($shouldSupport, $factory->supports($endpoint, $options)); - $factory->createTransport(); + if ($shouldSupport) { + $factory->createTransport($endpoint, $options); + } } /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('grpc+otlp://localhost')), new OtlpExporterOptions(), - null, + true, ]; yield [ MetricExporterEndpoint::fromDsn(ExporterDsn::fromString('grpc+otlp://localhost')), new MetricExporterOptions(), - null, + true, ]; yield [ LogExporterEndpoint::fromDsn(ExporterDsn::fromString('grpc+otlp://localhost')), new OtlpExporterOptions(), - null, + true, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new OtlpExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('stream+console://default')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('in-memory://default')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; } } diff --git a/tests/Unit/OpenTelemetry/Transport/OtlpHttpTransportFactoryTest.php b/tests/Unit/OpenTelemetry/Transport/OtlpHttpTransportFactoryTest.php index f43192d..21e8829 100644 --- a/tests/Unit/OpenTelemetry/Transport/OtlpHttpTransportFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Transport/OtlpHttpTransportFactoryTest.php @@ -13,81 +13,77 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\ZipkinExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\OtlpHttpTransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\OtlpHttpTransportFactory - */ +#[CoversClass(OtlpHttpTransportFactory::class)] class OtlpHttpTransportFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateTransportFromExporter( ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options, - ?\Exception $exception, + bool $shouldSupport, ): void { - if (null !== $exception) { - self::expectExceptionObject($exception); - } else { - $this->expectNotToPerformAssertions(); - } + $factory = new OtlpHttpTransportFactory(); - $factory = OtlpHttpTransportFactory::fromExporter($endpoint, $options); + self::assertSame($shouldSupport, $factory->supports($endpoint, $options)); - $factory->createTransport(); + if ($shouldSupport) { + $factory->createTransport($endpoint, $options); + } } /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new OtlpExporterOptions(), - null, + true, ]; yield [ MetricExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new MetricExporterOptions(), - null, + true, ]; yield [ LogExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new OtlpExporterOptions(), - null, + true, ]; yield [ ZipkinExporterEndpoint::fromDsn(ExporterDsn::fromString('http+zipkin://localhost')), new OtlpExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('grpc+otlp://localhost')), new OtlpExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('stream+console://default')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('in-memory://default')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; } } diff --git a/tests/Unit/OpenTelemetry/Transport/PsrHttpTransportFactoryTest.php b/tests/Unit/OpenTelemetry/Transport/PsrHttpTransportFactoryTest.php index 4d0ee5a..b6c9b2a 100644 --- a/tests/Unit/OpenTelemetry/Transport/PsrHttpTransportFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Transport/PsrHttpTransportFactoryTest.php @@ -13,81 +13,77 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\ZipkinExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\PsrHttpTransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\PsrHttpTransportFactory - */ +#[CoversClass(PsrHttpTransportFactory::class)] class PsrHttpTransportFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateTransportFromExporter( ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options, - ?\Exception $exception, + bool $shouldSupport, ): void { - if (null !== $exception) { - self::expectExceptionObject($exception); - } else { - $this->expectNotToPerformAssertions(); - } + $factory = new PsrHttpTransportFactory(); - $factory = PsrHttpTransportFactory::fromExporter($endpoint, $options); + self::assertSame($shouldSupport, $factory->supports($endpoint, $options)); - $factory->createTransport(); + if ($shouldSupport) { + $factory->createTransport($endpoint, $options); + } } /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new OtlpExporterOptions(), - null, + true, ]; yield [ MetricExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new MetricExporterOptions(), - null, + true, ]; yield [ LogExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new OtlpExporterOptions(), - null, + true, ]; yield [ ZipkinExporterEndpoint::fromDsn(ExporterDsn::fromString('http+zipkin://localhost')), new EmptyExporterOptions(), - null, + true, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('grpc+otlp://localhost')), new OtlpExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('stream+console://default')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('in-memory://default')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; } } diff --git a/tests/Unit/OpenTelemetry/Transport/StreamTransportFactoryTest.php b/tests/Unit/OpenTelemetry/Transport/StreamTransportFactoryTest.php index e759838..65b8762 100644 --- a/tests/Unit/OpenTelemetry/Transport/StreamTransportFactoryTest.php +++ b/tests/Unit/OpenTelemetry/Transport/StreamTransportFactoryTest.php @@ -13,88 +13,83 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\TraceExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\ZipkinExporterEndpoint; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\StreamTransportFactory; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\StreamTransportFactory - */ +#[CoversClass(StreamTransportFactory::class)] class StreamTransportFactoryTest extends TestCase { - /** - * @dataProvider exporterProvider - */ + #[DataProvider('exporterProvider')] public function testCreateTransportFromExporter( ExporterEndpointInterface $endpoint, ExporterOptionsInterface $options, - ?\Exception $exception, + bool $shouldSupport, ): void { - if (null !== $exception) { - self::expectExceptionObject($exception); - } else { - $this->expectNotToPerformAssertions(); - } + $factory = new StreamTransportFactory(); - $factory = StreamTransportFactory::fromExporter($endpoint, $options); + self::assertSame($shouldSupport, $factory->supports($endpoint, $options)); - $factory->createTransport(); + if ($shouldSupport) { + $factory->createTransport($endpoint, $options); + } } /** * @return \Generator */ - public function exporterProvider(): \Generator + public static function exporterProvider(): \Generator { yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('stream+console://default')), new EmptyExporterOptions(), - null, + true, ]; yield [ - // This DSN is valid but given the context of the transport, the failure is expected. - TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('stream+console://default/var/log/symfony.log')), + TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('stream+console://default/tmp/symfony.log')), new EmptyExporterOptions(), - new \ErrorException('fopen(/var/log/symfony.log): Failed to open stream: Permission denied'), + true, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('in-memory://default')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new OtlpExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ MetricExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new MetricExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ LogExporterEndpoint::fromDsn(ExporterDsn::fromString('http+otlp://localhost')), new OtlpExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ ZipkinExporterEndpoint::fromDsn(ExporterDsn::fromString('http+zipkin://localhost')), new EmptyExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; yield [ TraceExporterEndpoint::fromDsn(ExporterDsn::fromString('grpc+otlp://localhost')), new OtlpExporterOptions(), - new \InvalidArgumentException('Unsupported exporter endpoint or options for this transport.'), + false, ]; } } diff --git a/tests/Unit/OpenTelemetry/Transport/TransportFactoryTest.php b/tests/Unit/OpenTelemetry/Transport/TransportFactoryTest.php new file mode 100644 index 0000000..974f4d0 --- /dev/null +++ b/tests/Unit/OpenTelemetry/Transport/TransportFactoryTest.php @@ -0,0 +1,142 @@ +, bool> $supportedEndpoints + */ + #[DataProvider('transportProvider')] + public function testCreateTransport( + ExporterDsn $dsn, + ExporterOptionsInterface $options, + array $supportedEndpoints, + ?string $expectedTransportClass + ): void { + $factory = new TransportFactory([ + new GrpcTransportFactory(), + new OtlpHttpTransportFactory(), + new PsrHttpTransportFactory(), + new StreamTransportFactory(), + ]); + + foreach ($supportedEndpoints as $endpointClass => $supported) { + if (true === $supported) { + $endpoint = $endpointClass::fromDsn($dsn); + self::assertTrue($factory->supports($endpoint, $options)); + $transport = $factory->createTransport($endpoint, $options); + self::assertInstanceOf($expectedTransportClass, $transport); + } else { + self::expectExceptionMessageMatches('#Unsupported .*#'); + $endpoint = $endpointClass::fromDsn($dsn); + self::assertFalse($factory->supports($endpoint, $options)); + } + } + } + + /** + * @return \Generator, bool>, + * 3: ?class-string>, + * }> + */ + public static function transportProvider(): \Generator + { + yield [ + ExporterDsn::fromString('stream+console://default'), + new EmptyExporterOptions(), + [ + LogExporterEndpoint::class => true, + MetricExporterEndpoint::class => true, + TraceExporterEndpoint::class => true, + ZipkinExporterEndpoint::class => false, + ConsoleExporterEndpoint::class => true, + OtlpExporterEndpoint::class => false, + ], + StreamTransport::class, + ]; + + yield [ + ExporterDsn::fromString('http+zipkin://default'), + new EmptyExporterOptions(), + [ + LogExporterEndpoint::class => false, + MetricExporterEndpoint::class => false, + TraceExporterEndpoint::class => true, + ZipkinExporterEndpoint::class => true, + ConsoleExporterEndpoint::class => false, + OtlpExporterEndpoint::class => false, + ], + PsrTransport::class, + ]; + + yield [ + ExporterDsn::fromString('http+otlp://default'), + new EmptyExporterOptions(), + [ + LogExporterEndpoint::class => true, + MetricExporterEndpoint::class => true, + TraceExporterEndpoint::class => true, + ZipkinExporterEndpoint::class => false, + ConsoleExporterEndpoint::class => false, + OtlpExporterEndpoint::class => true, + ], + PsrTransport::class, + ]; + + yield [ + ExporterDsn::fromString('grpc+otlp://default'), + new EmptyExporterOptions(), + [ + LogExporterEndpoint::class => true, + MetricExporterEndpoint::class => true, + TraceExporterEndpoint::class => true, + ZipkinExporterEndpoint::class => false, + ConsoleExporterEndpoint::class => false, + OtlpExporterEndpoint::class => true, + ], + GrpcTransport::class, + ]; + + yield [ + ExporterDsn::fromString('noop://default'), + new EmptyExporterOptions(), + [ + LogExporterEndpoint::class => false, + MetricExporterEndpoint::class => false, + TraceExporterEndpoint::class => false, + ZipkinExporterEndpoint::class => false, + ConsoleExporterEndpoint::class => false, + OtlpExporterEndpoint::class => false, + ], + null, + ]; + } +} diff --git a/tests/Unit/OpenTelemetry/Transport/TransportParamsTest.php b/tests/Unit/OpenTelemetry/Transport/TransportParamsTest.php index d51a7a1..b1604f0 100644 --- a/tests/Unit/OpenTelemetry/Transport/TransportParamsTest.php +++ b/tests/Unit/OpenTelemetry/Transport/TransportParamsTest.php @@ -6,11 +6,11 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterFormatEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterOptions; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportParams; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -/** - * @coversDefaultClass \FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportParams - */ +#[CoversClass(TransportParams::class)] class TransportParamsTest extends TestCase { public function testCreateDefault(): void @@ -29,8 +29,6 @@ public function testCreateDefault(): void } /** - * @dataProvider otlpExporterOptionProvider - * * @param array{ * contentType: string, * headers: array, @@ -43,6 +41,7 @@ public function testCreateDefault(): void * key: ?string, * } $expected */ + #[DataProvider('otlpExporterOptionProvider')] public function testFromOtlpExporterOptions(OtlpExporterOptions $options, array $expected): void { $params = $options->toTransportParams(); @@ -74,7 +73,7 @@ public function testFromOtlpExporterOptions(OtlpExporterOptions $options, array * } * }> */ - public function otlpExporterOptionProvider(): \Generator + public static function otlpExporterOptionProvider(): \Generator { yield [ new OtlpExporterOptions(),