diff --git a/README.md b/README.md index 02f3dd8..cc1b2cd 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,54 @@ - Composer +# How to use -- Monolog +### Serviceprovider +```php +TelemetryServiceProvider::class +``` + +### Using TelemetryService to log +```php +use \Webgrip\TelemetryService\Core\Domain\Services\TelemetryServiceInterface; + +class Foo +{ + public function __construct(private TelemetryServiceInterface $telemetryService) { + } + + public function bar() + { + $this->telemetryService->logger()->debug('Hello World'); + $this->telemetryService->logger()->info('Hello World'); + $this->telemetryService->logger()->warning('Hello World'); + // ... + } +} +``` + + +### Using TelemetryService to trace +```php +use \Webgrip\TelemetryService\Core\Domain\Services\TelemetryServiceInterface; + +class Foo +{ + public function __construct(private TelemetryServiceInterface $telemetryService) { + } + + public function bar() + { + $tracer = $this->telemetryService->tracer(); + $span = $tracer->spanBuilder('foo')->startSpan(); + + $span->addEvent('bar'); + $span->setAttributes(['foo' => 'bar']); + $span->recordException(new \Exception('Hello World')); + $span->addLink('foo', 'bar'); + // ... + + $span->end(); + } +} +``` diff --git a/src/Core/Application/Application.php b/src/Core/Application/Application.php deleted file mode 100644 index d2d5f13..0000000 --- a/src/Core/Application/Application.php +++ /dev/null @@ -1,38 +0,0 @@ -addDefinitions( - [ - Configuration::class => $configuration, - ClientInterface::class => create(Client::class), - OpenTelemetryCollectorFactoryInterface::class => create(OpenTelemetryCollectorFactory::class), - LoggerProviderFactoryInterface::class => create(LoggerProviderFactory::class), - ] - ); - - $this->defineDependencies($containerBuilder); - CommandServiceProvider::register($containerBuilder); - - $this->container = $containerBuilder->build(); - } -} diff --git a/src/Core/Application/Factories/OpenTelemetryCollectorFactoryInterface.php b/src/Core/Application/Factories/OpenTelemetryCollectorFactoryInterface.php deleted file mode 100644 index 0017b8f..0000000 --- a/src/Core/Application/Factories/OpenTelemetryCollectorFactoryInterface.php +++ /dev/null @@ -1,11 +0,0 @@ -configuration; + + $container->set(ResourceInfo::class, function (Container $container) use ($configuration) { + return ResourceInfo::create( + Attributes::create([ + ResourceAttributes::DEPLOYMENT_ENVIRONMENT_NAME => $configuration->get('applicationEnvironmentName'), + ResourceAttributes::SERVICE_NAMESPACE => $configuration->get('applicationNamespace'), + ResourceAttributes::SERVICE_NAME => $configuration->get('applicationName'), + ResourceAttributes::SERVICE_VERSION => $configuration->get('applicationVersion'), + ]) + ); + }); + + $container->set(LoggerProviderFactoryInterface::class, function (Container $container) use ($configuration) { + return new LoggerProviderFactory( + $configuration + ); + }); + + $container->set(TracerProviderFactoryInterface::class, function (Container $container) use ($configuration) { + return new TracerProviderFactory( + $configuration + ); + }); + + $container->set(TelemetryServiceFactoryInterface::class, function (Container $container) { + return new TelemetryServiceFactory( + $container->get(LoggerProviderFactoryInterface::class), + $container->get(TracerProviderFactoryInterface::class), + $container->get(Client::class) + ); + }); + + $container->set(TelemetryServiceInterface::class, function (Container $container) use ($configuration) { + return $container->get(TelemetryServiceFactoryInterface::class)->create( + $configuration, + $container->get(LoggerInterface::class) + ); + }); + } + +} diff --git a/src/Core/Domain/Services/TelemetryServiceInterface.php b/src/Core/Domain/Services/TelemetryServiceInterface.php index 11e241f..c5f9ae6 100644 --- a/src/Core/Domain/Services/TelemetryServiceInterface.php +++ b/src/Core/Domain/Services/TelemetryServiceInterface.php @@ -3,8 +3,10 @@ namespace Webgrip\TelemetryService\Core\Domain\Services; use OpenTelemetry\API\Trace\TracerInterface; +use Psr\Log\LoggerInterface; interface TelemetryServiceInterface { + public function logger(): LoggerInterface; public function tracer(): TracerInterface; } diff --git a/src/Infrastructure/Configuration/Configuration.php b/src/Infrastructure/Configuration/Configuration.php deleted file mode 100644 index c2e5d9f..0000000 --- a/src/Infrastructure/Configuration/Configuration.php +++ /dev/null @@ -1,28 +0,0 @@ -create( - 'http://' . $this->configuration->otelCollectorHost . ':4318' . '/v1/logs', + 'http://' . $this->configuration->get('otelCollectorHost') . ':4318' . '/v1/logs', 'application/json' ); diff --git a/src/Infrastructure/Factories/OpenTelemetryCollectorFactory.php b/src/Infrastructure/Factories/OpenTelemetryCollectorFactory.php deleted file mode 100644 index 004be1c..0000000 --- a/src/Infrastructure/Factories/OpenTelemetryCollectorFactory.php +++ /dev/null @@ -1,45 +0,0 @@ -client->get($collector->getHealthCheckPath()); - $statusCode = $response->getStatusCode(); - - if (Response::HTTP_NO_CONTENT !== $statusCode) { - throw new CancellationException('Health check failed. Status code: ' . $statusCode); - } - } catch (GuzzleException | CancellationException $e) { - if ($throwExceptionWhenHealthCheckFails) { - throw $e; - } - - $collector = new NoopOpenTelemetryCollector($configuration); - } - - return $collector; - } -} diff --git a/src/Infrastructure/Factories/TelemetryServiceFactory.php b/src/Infrastructure/Factories/TelemetryServiceFactory.php index 476ed14..73b6846 100644 --- a/src/Infrastructure/Factories/TelemetryServiceFactory.php +++ b/src/Infrastructure/Factories/TelemetryServiceFactory.php @@ -2,26 +2,83 @@ namespace Webgrip\TelemetryService\Infrastructure\Factories; +use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Promise\CancellationException; +use Monolog\Logger; +use OpenTelemetry\API\Logs\NoopLoggerProvider; +use OpenTelemetry\API\Trace\NoopTracerProvider; +use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Resource\ResourceInfo; +use OpenTelemetry\SemConv\ResourceAttributes; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\Http\Client\ClientInterface; +use Symfony\Component\HttpFoundation\Response; use Webgrip\TelemetryService\Core\Application\Factories\LoggerProviderFactoryInterface; use Webgrip\TelemetryService\Core\Application\Factories\TelemetryServiceFactoryInterface; use Webgrip\TelemetryService\Core\Application\Factories\TracerProviderFactoryInterface; use Webgrip\TelemetryService\Infrastructure\Services\TelemetryService; +use Webgrip\TelemetryService\Infrastructure\Telemetry\NoopOpenTelemetryCollector; final class TelemetryServiceFactory implements TelemetryServiceFactoryInterface { + /** + * @param LoggerProviderFactoryInterface $loggerProviderFactory + * @param TracerProviderFactoryInterface $tracerProviderFactory + * @param ClientInterface $client + */ public function __construct( private LoggerProviderFactoryInterface $loggerProviderFactory, - private TracerProviderFactoryInterface $tracerProviderFactory + private TracerProviderFactoryInterface $tracerProviderFactory, + private ClientInterface $client, ) { } - public function create(ResourceInfo $resourceInfo): TelemetryService + /** + * @param ContainerInterface $configuration + * @param Logger $logger + * @param $throwExceptionWhenHealthCheckFails + * @return TelemetryService + * @throws ContainerExceptionInterface + * @throws GuzzleException + * @throws NotFoundExceptionInterface + */ + public function create(ContainerInterface $configuration, Logger $logger, $throwExceptionWhenHealthCheckFails = true): TelemetryService { + $resourceInfo = ResourceInfo::create( + Attributes::create([ + ResourceAttributes::DEPLOYMENT_ENVIRONMENT_NAME => $configuration->get('applicationEnvironmentName'), + ResourceAttributes::SERVICE_NAMESPACE => $configuration->get('applicationNamespace'), + ResourceAttributes::SERVICE_NAME => $configuration->get('applicationName'), + ResourceAttributes::SERVICE_VERSION => $configuration->get('applicationVersion'), + ]) + ); + + try { + $response = $this->client->get('http://'. $configuration->get('otelCollectorHost') .':13133'); + $statusCode = $response->getStatusCode(); + + if (!in_array($statusCode, [Response::HTTP_OK, Response::HTTP_NO_CONTENT])) { + throw new CancellationException('Health check failed. Status code: ' . $statusCode); + } + } catch (GuzzleException | CancellationException $e) { + if ($throwExceptionWhenHealthCheckFails) { + throw $e; + } + + return new TelemetryService( + new NoopLoggerProvider(), + new NoopTracerProvider(), + $logger + ); + } + return new TelemetryService( $this->loggerProviderFactory->create($resourceInfo), - $this->tracerProviderFactory->create($resourceInfo) + $this->tracerProviderFactory->create($resourceInfo), + $logger ); } } diff --git a/src/Infrastructure/Factories/TracerProviderFactory.php b/src/Infrastructure/Factories/TracerProviderFactory.php index c0ba15a..cb9daab 100644 --- a/src/Infrastructure/Factories/TracerProviderFactory.php +++ b/src/Infrastructure/Factories/TracerProviderFactory.php @@ -9,23 +9,34 @@ use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler; use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; use OpenTelemetry\SDK\Trace\TracerProvider; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Webgrip\TelemetryService\Core\Application\Factories\TracerProviderFactoryInterface; -use Webgrip\TelemetryService\Infrastructure\Configuration\Configuration; -final class TracerProviderFactory implements TracerProviderFactoryInterface +final readonly class TracerProviderFactory implements TracerProviderFactoryInterface { + /** + * @param ContainerInterface $configuration + */ public function __construct( - private readonly Configuration $configuration + private ContainerInterface $configuration ) { } + /** + * @param ResourceInfo $resourceInfo + * @return TracerProviderInterface + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function create(ResourceInfo $resourceInfo): TracerProviderInterface { $otlpHttpTransportFactory = new OtlpHttpTransportFactory(); $transport = $otlpHttpTransportFactory->create( - 'http://' . $this->configuration->otelCollectorHost . ':4317' . '/v1/traces', + 'http://' . $this->configuration->get('otelCollectorHost') . ':4318' . '/v1/traces', 'application/json' ); diff --git a/src/Infrastructure/Telemetry/NoopOpenTelemetryCollector.php b/src/Infrastructure/Telemetry/NoopOpenTelemetryCollector.php deleted file mode 100644 index 1fd79d1..0000000 --- a/src/Infrastructure/Telemetry/NoopOpenTelemetryCollector.php +++ /dev/null @@ -1,29 +0,0 @@ -resource = ResourceInfoFactory::emptyResource()->merge( - ResourceInfo::create( - Attributes::create([ - ResourceAttributes::DEPLOYMENT_ENVIRONMENT_NAME => $this->configuration->applicationEnvironmentName, - ResourceAttributes::SERVICE_NAMESPACE => $this->configuration->applicationNamespace, - ResourceAttributes::SERVICE_NAME => $this->configuration->applicationName, - ResourceAttributes::SERVICE_VERSION => $this->configuration->applicationVersion, - ]) - ) - ); - } - - public function getHealthCheckPath(): string - { - return self::$healthCheckProtocol . $this->configuration->otelCollectorHost . self::$healthCheckPort; - } -} diff --git a/src/index.php b/src/index.php deleted file mode 100644 index 1cfbabe..0000000 --- a/src/index.php +++ /dev/null @@ -1,36 +0,0 @@ -create($configuration); - -$tracerProviderFactory = new \Webgrip\TelemetryService\Infrastructure\Factories\TracerProviderFactory($configuration); -$tracerProvider = $tracerProviderFactory->create($openTelemetryCollector->resource); - -$loggerProviderFactory = new \Webgrip\TelemetryService\Infrastructure\Factories\LoggerProviderFactory($configuration); -$loggerProvider = $loggerProviderFactory->create($openTelemetryCollector->resource); - -$telemetryServiceFactory = new \Webgrip\TelemetryService\Infrastructure\Factories\TelemetryServiceFactory(); -$telemetryService = $telemetryServiceFactory->create($openTelemetryCollector->resource); - -$telemetryService->x(); - - - -$openTelemetryCollectorFactory->create - -