Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sdk builder #845

Merged
merged 5 commits into from
Oct 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions examples/sdk_builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

declare(strict_types=1);

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;
use OpenTelemetry\API\Common\Instrumentation\CachedInstrumentation;
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\Contrib\Otlp\MetricExporter;
use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory;
use OpenTelemetry\SDK\Common\Time\ClockFactory;
use OpenTelemetry\SDK\Metrics\MeterProvider;
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SDK\Sdk;
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessorBuilder;
use OpenTelemetry\SDK\Trace\TracerProvider;

require __DIR__ . '/../vendor/autoload.php';

echo 'Starting SDK builder example' . PHP_EOL;

\OpenTelemetry\SDK\Common\Log\LoggerHolder::set(new \Monolog\Logger('grpc', [new \Monolog\Handler\StreamHandler('php://stderr')]));

$resource = ResourceInfoFactory::defaultResource();
$spanExporter = new InMemoryExporter();

$reader = new ExportingReader(
new MetricExporter(
(new PsrTransportFactory(new Client(), new HttpFactory(), new HttpFactory()))
->create('http://collector:4318/v1/metrics', 'application/x-protobuf')
),
ClockFactory::getDefault()
);

$meterProvider = MeterProvider::builder()
->setResource($resource)
->addReader($reader)
->build();

$tracerProvider = TracerProvider::builder()
->addSpanProcessor(
(new BatchSpanProcessorBuilder($spanExporter))
->setMeterProvider($meterProvider)
->build()
)
->setResource($resource)
->setSampler(new ParentBased(new AlwaysOnSampler()))
->build();

Sdk::builder()
->setTracerProvider($tracerProvider)
->setMeterProvider($meterProvider)
->setPropagator(TraceContextPropagator::getInstance())
->setAutoShutdown(true)
->buildAndRegisterGlobal();

$instrumentation = new CachedInstrumentation('example');
$tracer = $instrumentation->tracer();

$root = $tracer->spanBuilder('root')->startSpan();
$scope = $root->activate();
for ($i=0; $i < 100; $i++) {
if ($i%8 === 0) {
$reader->collect();
}
$tracer->spanBuilder('span-' . $i)
->startSpan()
->end();
usleep(50000);
}
$scope->detach();
$root->end();
$reader->shutdown();

echo 'Finished SDK builder example' . PHP_EOL;
9 changes: 7 additions & 2 deletions src/SDK/Metrics/MeterProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
use OpenTelemetry\SDK\Metrics\MetricFactory\StreamFactory;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\SDK;
use OpenTelemetry\SDK\Sdk;

final class MeterProvider implements MeterProviderInterface
{
Expand Down Expand Up @@ -65,7 +65,7 @@ public function getMeter(
?string $schemaUrl = null,
iterable $attributes = []
): MeterInterface {
if ($this->closed || SDK::isDisabled()) {
if ($this->closed || Sdk::isDisabled()) { //@todo create meter provider from factory, and move Sdk::isDisabled() there
return new NoopMeter();
}

Expand Down Expand Up @@ -117,4 +117,9 @@ public function forceFlush(): bool

return $success;
}

public static function builder(): MeterProviderBuilder
{
return new MeterProviderBuilder();
}
}
60 changes: 60 additions & 0 deletions src/SDK/Metrics/MeterProviderBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Metrics;

use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
use OpenTelemetry\SDK\Common\Time\ClockFactory;
use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
use OpenTelemetry\SDK\Metrics\StalenessHandler\ImmediateStalenessHandlerFactory;
use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;

class MeterProviderBuilder
{
// @var array<MetricReaderInterface>
private array $metricReaders = [];
private ?ResourceInfo $resource = null;

public function registerMetricReader(MetricReaderInterface $reader): self
{
$this->metricReaders[] = $reader;

return $this;
}

public function setResource(ResourceInfo $resource): self
{
$this->resource = $resource;

return $this;
}

public function addReader(MetricReaderInterface $reader): self
{
$this->metricReaders[] = $reader;

return $this;
}

/**
* @psalm-suppress PossiblyInvalidArgument
*/
public function build(): MeterProviderInterface
{
return new MeterProvider(
null,
$this->resource ?? ResourceInfoFactory::emptyResource(),
ClockFactory::getDefault(),
Attributes::factory(),
new InstrumentationScopeFactory(Attributes::factory()),
$this->metricReaders,
new CriteriaViewRegistry(),
new WithSampledTraceExemplarFilter(),
new ImmediateStalenessHandlerFactory(),
);
}
}
26 changes: 26 additions & 0 deletions src/SDK/Metrics/NoopMeterProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Metrics;

use OpenTelemetry\API\Metrics\MeterInterface;
use OpenTelemetry\API\Metrics\Noop\NoopMeter;

class NoopMeterProvider implements MeterProviderInterface
{
public function shutdown(): bool
{
return true;
}

public function forceFlush(): bool
{
return true;
}

public function getMeter(string $name, ?string $version = null, ?string $schemaUrl = null, iterable $attributes = []): MeterInterface
{
return new NoopMeter();
}
}
16 changes: 0 additions & 16 deletions src/SDK/SDK.php

This file was deleted.

53 changes: 53 additions & 0 deletions src/SDK/Sdk.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK;

use OpenTelemetry\API\Metrics\MeterProviderInterface;
use OpenTelemetry\API\Trace\TracerProviderInterface;
use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
use OpenTelemetry\SDK\Common\Environment\EnvironmentVariables;
use OpenTelemetry\SDK\Common\Environment\Variables;

class Sdk
{
private TracerProviderInterface $tracerProvider;
private MeterProviderInterface $meterProvider;
private TextMapPropagatorInterface $propagator;

public function __construct(
TracerProviderInterface $tracerProvider,
MeterProviderInterface $meterProvider,
TextMapPropagatorInterface $propagator
) {
$this->tracerProvider = $tracerProvider;
$this->meterProvider = $meterProvider;
$this->propagator = $propagator;
}

public static function isDisabled(): bool
{
return EnvironmentVariables::getBoolean(Variables::OTEL_SDK_DISABLED);
}

public static function builder(): SdkBuilder
{
return new SdkBuilder();
}

public function getTracerProvider(): TracerProviderInterface
{
return $this->tracerProvider;
}

public function getMeterProvider(): MeterProviderInterface
{
return $this->meterProvider;
}

public function getPropagator(): TextMapPropagatorInterface
{
return $this->propagator;
}
}
84 changes: 84 additions & 0 deletions src/SDK/SdkBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK;

use OpenTelemetry\API\Common\Instrumentation\Configurator;
use OpenTelemetry\Context\Context;
use OpenTelemetry\Context\Propagation\NoopTextMapPropagator;
use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
use OpenTelemetry\Context\ScopeInterface;
use OpenTelemetry\SDK\Common\Future\CancellationInterface;
use OpenTelemetry\SDK\Common\Util\ShutdownHandler;
use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
use OpenTelemetry\SDK\Metrics\NoopMeterProvider;
use OpenTelemetry\SDK\Trace\NoopTracerProvider;
use OpenTelemetry\SDK\Trace\TracerProviderInterface;

class SdkBuilder
{
private ?TracerProviderInterface $tracerProvider = null;
private ?MeterProviderInterface $meterProvider = null;
private ?TextMapPropagatorInterface $propagator = null;
private bool $autoShutdown = false;

/**
* Automatically shut down providers on process completion. If not set, the user is responsible for calling `shutdown`.
*/
public function setAutoShutdown(bool $shutdown): self
{
$this->autoShutdown = $shutdown;

return $this;
}

public function setTracerProvider(TracerProviderInterface $provider): self
{
$this->tracerProvider = $provider;

return $this;
}

public function setMeterProvider(MeterProviderInterface $meterProvider): self
{
$this->meterProvider = $meterProvider;

return $this;
}

public function setPropagator(TextMapPropagatorInterface $propagator): self
{
$this->propagator = $propagator;

return $this;
}

brettmc marked this conversation as resolved.
Show resolved Hide resolved
public function build(): Sdk
{
$tracerProvider = $this->tracerProvider ?? new NoopTracerProvider();
$meterProvider = $this->meterProvider ?? new NoopMeterProvider();
if ($this->autoShutdown) {
ShutdownHandler::register(fn (?CancellationInterface $cancellation = null): bool => $tracerProvider->shutdown($cancellation));
ShutdownHandler::register(fn (): bool => $meterProvider->shutdown());
}

return new Sdk(
$tracerProvider,
$meterProvider,
$this->propagator ?? NoopTextMapPropagator::getInstance(),
);
}

public function buildAndRegisterGlobal(): ScopeInterface
{
$sdk = $this->build();
$context = Configurator::create()
->withPropagator($sdk->getPropagator())
->withTracerProvider($sdk->getTracerProvider())
->withMeterProvider($sdk->getMeterProvider())
->storeInContext();

return Context::storage()->attach($context);
}
}
41 changes: 41 additions & 0 deletions src/SDK/Trace/SpanProcessor/BatchSpanProcessorBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Trace\SpanProcessor;

use OpenTelemetry\SDK\Common\Time\ClockFactory;
use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
use OpenTelemetry\SDK\Trace\SpanExporterInterface;

class BatchSpanProcessorBuilder
{
private SpanExporterInterface $exporter;
private ?MeterProviderInterface $meterProvider = null;

public function __construct(SpanExporterInterface $exporter)
{
$this->exporter = $exporter;
}

public function setMeterProvider(MeterProviderInterface $meterProvider): self
{
$this->meterProvider = $meterProvider;

return $this;
}

public function build(): BatchSpanProcessor
{
return new BatchSpanProcessor(
$this->exporter,
ClockFactory::getDefault(),
BatchSpanProcessor::DEFAULT_MAX_QUEUE_SIZE,
BatchSpanProcessor::DEFAULT_SCHEDULE_DELAY,
BatchSpanProcessor::DEFAULT_EXPORT_TIMEOUT,
BatchSpanProcessor::DEFAULT_MAX_EXPORT_BATCH_SIZE,
true,
$this->meterProvider
);
}
}
Loading