Skip to content

Commit

Permalink
support refactored otlp export config (#1477)
Browse files Browse the repository at this point in the history
upstream config now splits otlp exporters into otlp_http and otlp_grpc

* use const, remove insecure from otlp_http config

* Apply suggestions from code review

Co-authored-by: Tobias Bachert <git@b-privat.de>

* set default endpoints, fix review feedback

* move endpoint out of yaml anchor

* convert timeouts from millis to seconds

---------

Co-authored-by: Tobias Bachert <git@b-privat.de>
  • Loading branch information
brettmc and Nevay authored Jan 20, 2025
1 parent 29b7da4 commit a4119f9
Show file tree
Hide file tree
Showing 12 changed files with 452 additions and 64 deletions.
13 changes: 9 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@
"open-telemetry/exporter-otlp": "1.0.x-dev",
"open-telemetry/exporter-zipkin": "1.0.x-dev",
"open-telemetry/extension-propagator-b3": "1.0.x-dev",
"open-telemetry/extension-propagator-cloudtrace": "1.0.x-dev",
"open-telemetry/extension-propagator-jaeger": "0.0.2",
"open-telemetry/gen-otlp-protobuf": "1.0.x-dev",
"open-telemetry/sdk": "1.0.x-dev",
"open-telemetry/sdk-configuration": "0.1.x-dev",
"open-telemetry/sdk-contrib": "1.0.x-dev",
"open-telemetry/sem-conv": "1.0.x-dev"
"open-telemetry/sem-conv": "1.0.x-dev",
"open-telemetry/transport-grpc": "1.0.x-dev"
},
"autoload": {
"psr-4": {
Expand Down Expand Up @@ -137,18 +139,21 @@
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SamplerParentBased",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SamplerTraceIdRatioBased",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterConsole",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterOtlp",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterOtlpGrpc",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterOtlpHttp",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterZipkin",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanProcessorBatch",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanProcessorSimple",

"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\AggregationResolverDefault",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterConsole",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterOtlp",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterOtlpGrpc",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterOtlpHttp",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricReaderPeriodic",

"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterConsole",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterOtlp",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterOtlpGrpc",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterOtlpHttp",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordProcessorBatch",
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordProcessorSimple",

Expand Down
1 change: 1 addition & 0 deletions src/API/Common/Time/ClockInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface ClockInterface
public const NANOS_PER_SECOND = 1_000_000_000;
public const NANOS_PER_MILLISECOND = 1_000_000;
public const NANOS_PER_MICROSECOND = 1_000;
public const MILLIS_PER_SECOND = 1_000;

/**
* Returns the current epoch wall-clock timestamp in nanoseconds
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace OpenTelemetry\Config\SDK\ComponentProvider\Logs;

use Nevay\SPI\ServiceProviderDependency\PackageDependency;
use OpenTelemetry\API\Common\Time\ClockInterface;
use OpenTelemetry\API\Signals;
use OpenTelemetry\Config\SDK\Configuration\ComponentProvider;
use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry;
Expand All @@ -23,11 +24,11 @@
* @implements ComponentProvider<LogRecordExporterInterface>
*/
#[PackageDependency('open-telemetry/exporter-otlp', '^1.0.5')]
final class LogRecordExporterOtlp implements ComponentProvider
#[PackageDependency('open-telemetry/transport-grpc', '^1')]
final class LogRecordExporterOtlpGrpc implements ComponentProvider
{
/**
* @param array{
* protocol: 'http/protobuf'|'http/json'|'grpc',
* endpoint: string,
* certificate: ?string,
* client_key: ?string,
Expand All @@ -41,16 +42,15 @@ final class LogRecordExporterOtlp implements ComponentProvider
*/
public function createPlugin(array $properties, Context $context): LogRecordExporterInterface
{
$protocol = $properties['protocol'];

$protocol = Protocols::GRPC;
$headers = array_column($properties['headers'], 'value', 'name') + MapParser::parse($properties['headers_list']);

return new LogsExporter(Registry::transportFactory($protocol)->create(
endpoint: $properties['endpoint'] . OtlpUtil::path(Signals::LOGS, $protocol),
contentType: Protocols::contentType($protocol),
headers: $headers,
compression: $properties['compression'],
timeout: $properties['timeout'],
timeout: $properties['timeout'] / ClockInterface::MILLIS_PER_SECOND,
cacert: $properties['certificate'],
cert: $properties['client_certificate'],
key: $properties['client_certificate'],
Expand All @@ -59,11 +59,10 @@ public function createPlugin(array $properties, Context $context): LogRecordExpo

public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition
{
$node = $builder->arrayNode('otlp');
$node = $builder->arrayNode('otlp_grpc');
$node
->children()
->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc'])->end()
->scalarNode('endpoint')->isRequired()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('endpoint')->defaultValue('http://localhost:4317')->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_key')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
Expand All @@ -77,7 +76,7 @@ public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $buil
->end()
->scalarNode('headers_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->enumNode('compression')->values(['gzip'])->defaultNull()->end()
->integerNode('timeout')->min(0)->defaultValue(10)->end()
->integerNode('timeout')->min(0)->defaultValue(10000)->end()
->booleanNode('insecure')->defaultNull()->end()
->end()
;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Config\SDK\ComponentProvider\Logs;

use Nevay\SPI\ServiceProviderDependency\PackageDependency;
use OpenTelemetry\API\Common\Time\ClockInterface;
use OpenTelemetry\Config\SDK\Configuration\ComponentProvider;
use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry;
use OpenTelemetry\Config\SDK\Configuration\Context;
use OpenTelemetry\Config\SDK\Configuration\Validation;
use OpenTelemetry\Contrib\Otlp\ContentTypes;
use OpenTelemetry\Contrib\Otlp\LogsExporter;
use OpenTelemetry\SDK\Common\Configuration\Parser\MapParser;
use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
use OpenTelemetry\SDK\Registry;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;

/**
* @implements ComponentProvider<LogRecordExporterInterface>
*/
#[PackageDependency('open-telemetry/exporter-otlp', '^1.0.5')]
final class LogRecordExporterOtlpHttp implements ComponentProvider
{
/**
* @param array{
* endpoint: string,
* certificate: ?string,
* client_key: ?string,
* client_certificate: ?string,
* headers: list<array{name: string, value: string}>,
* headers_list: ?string,
* compression: 'gzip'|null,
* timeout: int<0, max>,
* encoding: 'protobuf'|'json',
* } $properties
*/
public function createPlugin(array $properties, Context $context): LogRecordExporterInterface
{
$headers = array_column($properties['headers'], 'value', 'name') + MapParser::parse($properties['headers_list']);

return new LogsExporter(Registry::transportFactory('http')->create(
endpoint: $properties['endpoint'],
contentType: match ($properties['encoding']) {
'protobuf' => ContentTypes::PROTOBUF,
'json' => ContentTypes::JSON,
},
headers: $headers,
compression: $properties['compression'],
timeout: $properties['timeout'] / ClockInterface::MILLIS_PER_SECOND,
cacert: $properties['certificate'],
cert: $properties['client_certificate'],
key: $properties['client_certificate'],
));
}

public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition
{
$node = $builder->arrayNode('otlp_http');
$node
->children()
->enumNode('encoding')->defaultValue('protobuf')->values(['protobuf', 'json'])->end()
->scalarNode('endpoint')->defaultValue('http://localhost:4318/v1/logs')->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_key')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->arrayNode('headers')
->arrayPrototype()
->children()
->scalarNode('name')->isRequired()->cannotBeEmpty()->end()
->scalarNode('value')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->end()
->end()
->end()
->scalarNode('headers_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->enumNode('compression')->values(['gzip'])->defaultNull()->end()
->integerNode('timeout')->min(0)->defaultValue(10000)->end()
->end()
;

return $node;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace OpenTelemetry\Config\SDK\ComponentProvider\Metrics;

use Nevay\SPI\ServiceProviderDependency\PackageDependency;
use OpenTelemetry\API\Common\Time\ClockInterface;
use OpenTelemetry\API\Signals;
use OpenTelemetry\Config\SDK\Configuration\ComponentProvider;
use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry;
Expand All @@ -24,11 +25,11 @@
* @implements ComponentProvider<MetricExporterInterface>
*/
#[PackageDependency('open-telemetry/exporter-otlp', '^1.0.5')]
final class MetricExporterOtlp implements ComponentProvider
#[PackageDependency('open-telemetry/transport-grpc', '^1')]
final class MetricExporterOtlpGrpc implements ComponentProvider
{
/**
* @param array{
* protocol: 'http/protobuf'|'http/json'|'grpc',
* endpoint: string,
* certificate: ?string,
* client_key: ?string,
Expand All @@ -44,7 +45,7 @@ final class MetricExporterOtlp implements ComponentProvider
*/
public function createPlugin(array $properties, Context $context): MetricExporterInterface
{
$protocol = $properties['protocol'];
$protocol = Protocols::GRPC;

$headers = array_column($properties['headers'], 'value', 'name') + MapParser::parse($properties['headers_list']);

Expand All @@ -59,7 +60,7 @@ public function createPlugin(array $properties, Context $context): MetricExporte
contentType: Protocols::contentType($protocol),
headers: $headers,
compression: $properties['compression'],
timeout: $properties['timeout'],
timeout: $properties['timeout'] / ClockInterface::MILLIS_PER_SECOND,
cacert: $properties['certificate'],
cert: $properties['client_certificate'],
key: $properties['client_certificate'],
Expand All @@ -68,11 +69,10 @@ public function createPlugin(array $properties, Context $context): MetricExporte

public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition
{
$node = $builder->arrayNode('otlp');
$node = $builder->arrayNode('otlp_grpc');
$node
->children()
->enumNode('protocol')->isRequired()->values(['http/protobuf', 'http/json', 'grpc'])->end()
->scalarNode('endpoint')->isRequired()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('endpoint')->defaultValue('http://localhost:4317')->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_key')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
Expand All @@ -86,7 +86,7 @@ public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $buil
->end()
->scalarNode('headers_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->enumNode('compression')->values(['gzip'])->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->integerNode('timeout')->min(0)->defaultValue(10)->end()
->integerNode('timeout')->min(0)->defaultValue(10000)->end()
->booleanNode('insecure')->defaultNull()->end()
->enumNode('temporality_preference')
->values(['cumulative', 'delta', 'lowmemory'])
Expand Down
102 changes: 102 additions & 0 deletions src/Config/SDK/ComponentProvider/Metrics/MetricExporterOtlpHttp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Config\SDK\ComponentProvider\Metrics;

use Nevay\SPI\ServiceProviderDependency\PackageDependency;
use OpenTelemetry\API\Common\Time\ClockInterface;
use OpenTelemetry\Config\SDK\Configuration\ComponentProvider;
use OpenTelemetry\Config\SDK\Configuration\ComponentProviderRegistry;
use OpenTelemetry\Config\SDK\Configuration\Context;
use OpenTelemetry\Config\SDK\Configuration\Validation;
use OpenTelemetry\Contrib\Otlp\ContentTypes;
use OpenTelemetry\Contrib\Otlp\MetricExporter;
use OpenTelemetry\SDK\Common\Configuration\Parser\MapParser;
use OpenTelemetry\SDK\Metrics\Data\Temporality;
use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
use OpenTelemetry\SDK\Registry;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;

/**
* @implements ComponentProvider<MetricExporterInterface>
*/
#[PackageDependency('open-telemetry/exporter-otlp', '^1.0.5')]
final class MetricExporterOtlpHttp implements ComponentProvider
{
/**
* @param array{
* encoding: 'protobuf'|'json',
* endpoint: string,
* certificate: ?string,
* client_key: ?string,
* client_certificate: ?string,
* headers: list<array{name: string, value: string}>,
* headers_list: ?string,
* compression: 'gzip'|null,
* timeout: int<0, max>,
* temporality_preference: 'cumulative'|'delta'|'lowmemory',
* default_histogram_aggregation: 'explicit_bucket_histogram|base2_exponential_bucket_histogram',
* } $properties
*/
public function createPlugin(array $properties, Context $context): MetricExporterInterface
{
$headers = array_column($properties['headers'], 'value', 'name') + MapParser::parse($properties['headers_list']);

$temporality = match ($properties['temporality_preference']) {
'cumulative' => Temporality::CUMULATIVE,
'delta' => Temporality::DELTA,
'lowmemory' => null,
};

return new MetricExporter(Registry::transportFactory('http')->create(
endpoint: $properties['endpoint'],
contentType: match ($properties['encoding']) {
'protobuf' => ContentTypes::PROTOBUF,
'json' => ContentTypes::JSON,
},
headers: $headers,
compression: $properties['compression'],
timeout: $properties['timeout'] / ClockInterface::MILLIS_PER_SECOND,
cacert: $properties['certificate'],
cert: $properties['client_certificate'],
key: $properties['client_certificate'],
), $temporality);
}

public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition
{
$node = $builder->arrayNode('otlp_http');
$node
->children()
->enumNode('encoding')->defaultValue('protobuf')->values(['protobuf', 'json'])->end()
->scalarNode('endpoint')->defaultValue('http://localhost:4318/v1/metrics')->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_key')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->arrayNode('headers')
->arrayPrototype()
->children()
->scalarNode('name')->isRequired()->cannotBeEmpty()->end()
->scalarNode('value')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->end()
->end()
->end()
->scalarNode('headers_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->enumNode('compression')->values(['gzip'])->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->integerNode('timeout')->min(0)->defaultValue(10000)->end()
->enumNode('temporality_preference')
->values(['cumulative', 'delta', 'lowmemory'])
->defaultValue('cumulative')
->end()
->enumNode('default_histogram_aggregation')
->values(['explicit_bucket_histogram', 'base2_exponential_bucket_histogram'])
->defaultValue('explicit_bucket_histogram')
->end()
->end()
;

return $node;
}
}
Loading

0 comments on commit a4119f9

Please sign in to comment.