diff --git a/composer.json b/composer.json index 23defc8..7365dfe 100644 --- a/composer.json +++ b/composer.json @@ -22,8 +22,9 @@ ], "require": { "php": ">=8.2", + "guzzlehttp/guzzle": "^7.9", + "guzzlehttp/psr7": "^2.7", "monolog/monolog": "^3.8", - "nyholm/psr7": "^1.8", "open-telemetry/api": "^1", "open-telemetry/context": "^1", "open-telemetry/opentelemetry-logger-monolog": "^1", @@ -32,12 +33,9 @@ "open-telemetry/sdk": "^1", "open-telemetry/sem-conv": "^1", "open-telemetry/symfony-sdk-bundle": "^0", - "php-http/discovery": "^1.20", - "psr/http-factory": "^1.1", "symfony/config": "^7.2", "symfony/dependency-injection": "^7.2", "symfony/event-dispatcher": "^7.2", - "symfony/http-client": "^7.2", "zenstruck/dsn": "^0.2", "zenstruck/uri": "^2.3" }, @@ -53,7 +51,6 @@ "doctrine/doctrine-migrations-bundle": "^3.4", "doctrine/orm": "^2.18 || ^3.3", "ergebnis/composer-normalize": "^2.45", - "guzzlehttp/promises": "^2.0", "matthiasnoback/symfony-config-test": "^5.2", "matthiasnoback/symfony-dependency-injection-test": "^6.0", "mcaskill/composer-exclude-files": "^4.0", @@ -61,13 +58,13 @@ "open-telemetry/exporter-otlp": "^1", "open-telemetry/exporter-zipkin": "^1", "open-telemetry/transport-grpc": "^1", - "php-http/httplug": "^2.4", "phpunit/phpunit": "^11.5", "pyrech/composer-changelogs": "^2.1", "roave/security-advisories": "dev-master", "symfony/browser-kit": "^7.2", "symfony/cache": "^7.2", "symfony/framework-bundle": "^7.2", + "symfony/http-client": "^7.2", "symfony/http-kernel": "^7.2", "symfony/mailer": "^7.2", "symfony/messenger": "^7.2", @@ -114,7 +111,7 @@ "allow-plugins": { "ergebnis/composer-normalize": true, "mcaskill/composer-exclude-files": true, - "php-http/discovery": true, + "php-http/discovery": false, "pyrech/composer-changelogs": true, "symfony/runtime": false, "tbachert/spi": false diff --git a/docs/src/user-guide/getting-started.md b/docs/src/user-guide/getting-started.md index 7ba1ca7..f7aefc3 100644 --- a/docs/src/user-guide/getting-started.md +++ b/docs/src/user-guide/getting-started.md @@ -8,11 +8,16 @@ Run the following command to install it in your application: composer require friendsofopentelemetry/opentelemetry-bundle ``` -OpenTelemetry SDK uses `tbachert/spi`, a Composer plugin that register services by loading files from autoload files, this provides a way to instance services required by OpenTelemetry to work in any applications. -The purpose is similar to a container, but this not how it should be handled within a Symfony application. +### Notes -For a complete and clean installation, when requiring our bundle, you will be asked to choose to enable this plugin. We advise you to say **no**. -We also advise you to install `mcaskill/composer-exclude-files` Composer plugin and exclude OpenTelemetry files from autoload: +#### OpenTelemetry SDK and `tbachert/spi` + +The OpenTelemetry SDK uses `tbachert/spi`, a Composer plugin that registers services by loading files from the autoload configuration. This acts similarly to a container but is not the recommended approach for managing services in Symfony applications. + +To ensure a clean and optimal setup: + +- When prompted during installation, do not enable the `tbachert/spi` plugin. +- Install the `mcaskill/composer-exclude-files` Composer plugin and exclude OpenTelemetry files from the autoload process by adding the following configuration to your composer.json file: ```json { @@ -24,6 +29,13 @@ We also advise you to install `mcaskill/composer-exclude-files` Composer plugin } ``` +#### HTTP PSR Discovery and `php-http/discovery` + +You may also be prompted to enable the `php-http/discovery` Composer plugin. This plugin allows libraries to discover HTTP PSR implementations dynamically. While this is required by many OpenTelemetry dependencies, our bundle relies directly on Guzzle HTTP for simplicity. + +- Recommendation: Enable the plugin if your application requires it, but this is optional. +- If you believe relying directly on Guzzle HTTP is not ideal, please open an issue to share your feedback. As this package is in active Alpha development, we are open to exploring better solutions. + ### Supported Versions There is no stable version yet, so you can use the `dev` version to install the bundle. diff --git a/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php b/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php index e40a6e0..56b557c 100644 --- a/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php +++ b/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php @@ -2,7 +2,7 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\Symfony\HttpClient; -use Nyholm\Psr7\Uri; +use GuzzleHttp\Psr7\Uri; use OpenTelemetry\API\Trace\SpanKind; use OpenTelemetry\API\Trace\TracerInterface; use OpenTelemetry\Context\Context; diff --git a/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php b/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php index 74e79d1..73eb8da 100644 --- a/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php +++ b/src/OpenTelemetry/Exporter/OtlpExporterEndpoint.php @@ -3,7 +3,7 @@ namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportEnum; -use Http\Discovery\Psr17FactoryDiscovery; +use GuzzleHttp\Psr7\HttpFactory; use OpenTelemetry\API\Signals; use OpenTelemetry\Contrib\Otlp\HttpEndpointResolverInterface; use OpenTelemetry\Contrib\Otlp\OtlpUtil; @@ -11,24 +11,22 @@ final class OtlpExporterEndpoint implements ExporterEndpointInterface { - private UriFactoryInterface $uriFactory; private ?string $signal = null; private TransportEnum $transport; private function __construct( private readonly ExporterDsn $dsn, - ?UriFactoryInterface $uriFactory = null, + private readonly UriFactoryInterface $uriFactory, ) { if ('otlp' !== $this->dsn->getExporter()) { throw new \RuntimeException('Provided DSN exporter is not compatible with this endpoint.'); } - $this->uriFactory = $uriFactory ?? Psr17FactoryDiscovery::findUriFactory(); $this->transport = TransportEnum::from($this->dsn->getTransport()); } public static function fromDsn(ExporterDsn $dsn): self { - return new self($dsn); + return new self($dsn, new HttpFactory()); } public function withSignal(string $signal): self diff --git a/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php b/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php index d7fab97..8b66ddb 100644 --- a/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php +++ b/src/OpenTelemetry/Trace/ZipkinExporterEndpoint.php @@ -6,28 +6,26 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterEndpointInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Trace\SpanExporter\TraceExporterEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Transport\TransportEnum; -use Http\Discovery\Psr17FactoryDiscovery; +use GuzzleHttp\Psr7\HttpFactory; use Psr\Http\Message\UriFactoryInterface; final class ZipkinExporterEndpoint implements ExporterEndpointInterface { - private UriFactoryInterface $uriFactory; private ?TransportEnum $transport; private function __construct( private readonly ExporterDsn $dsn, - ?UriFactoryInterface $uriFactory = null, + private readonly UriFactoryInterface $uriFactory, ) { if (TraceExporterEnum::Zipkin !== TraceExporterEnum::fromDsn($this->dsn)) { throw new \InvalidArgumentException('Unsupported DSN exporter for this endpoint.'); } - $this->uriFactory = $uriFactory ?? Psr17FactoryDiscovery::findUriFactory(); $this->transport = TransportEnum::fromDsn($this->dsn); } public static function fromDsn(ExporterDsn $dsn): self { - return new self($dsn); + return new self($dsn, new HttpFactory()); } public function __toString() diff --git a/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php b/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php index f8acbe1..207caa8 100644 --- a/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php +++ b/src/OpenTelemetry/Transport/OtlpHttpTransportFactory.php @@ -6,6 +6,10 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterCompressionEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterFormatEnum; +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\HttpFactory; +use OpenTelemetry\SDK\Common\Export\Http\PsrTransport; +use OpenTelemetry\SDK\Common\Export\Http\PsrUtils; use OpenTelemetry\SDK\Common\Export\TransportInterface; final readonly class OtlpHttpTransportFactory implements TransportFactoryInterface @@ -29,17 +33,16 @@ public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $format = $params->contentType ?? OtlpExporterFormatEnum::Json->toContentType(); $compression = OtlpExporterCompressionEnum::tryFrom($params->compression) ?? OtlpExporterCompressionEnum::None; - return (new \OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory())->create( + return new PsrTransport( + new Client(), + new HttpFactory(), + new HttpFactory(), (string) $endpoint, $format, $params->headers, - $compression->toKnownValue(), - $params->timeout, + PsrUtils::compression(OtlpExporterCompressionEnum::None === $compression ? null : $compression->toKnownValue()), $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 fac7992..ee78155 100644 --- a/src/OpenTelemetry/Transport/PsrHttpTransportFactory.php +++ b/src/OpenTelemetry/Transport/PsrHttpTransportFactory.php @@ -6,7 +6,10 @@ use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterCompressionEnum; use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterFormatEnum; -use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory; +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\HttpFactory; +use OpenTelemetry\SDK\Common\Export\Http\PsrTransport; +use OpenTelemetry\SDK\Common\Export\Http\PsrUtils; use OpenTelemetry\SDK\Common\Export\TransportInterface; final readonly class PsrHttpTransportFactory implements TransportFactoryInterface @@ -23,17 +26,16 @@ public function createTransport(#[\SensitiveParameter] ExporterEndpointInterface $format = $params->contentType ?? OtlpExporterFormatEnum::Json->toContentType(); $compression = OtlpExporterCompressionEnum::tryFrom($params->compression) ?? OtlpExporterCompressionEnum::None; - return (new PsrTransportFactory())->create( + return new PsrTransport( + new Client(), + new HttpFactory(), + new HttpFactory(), (string) $endpoint, $format, $params->headers, - $compression->toKnownValue(), - $params->timeout, + PsrUtils::compression($compression->toKnownValue()), $params->retryDelay, $params->maxRetries, - $params->caCert, - $params->cert, - $params->key, ); } }