Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add sdk-config 0.3 support for key/value headers and attributes
Browse files Browse the repository at this point in the history
- headers and attributes are now arrays with `key` and `value` elements
- headers can optionally contain a `headers_list` element which supports a lower-priority CSV of key/value entries
- attributes can optionally contain an `attributes_list` element which supports a lower-priority CSV of key/value entries
brettmc committed Nov 7, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 1aae9dd commit cb0a9eb
Showing 8 changed files with 111 additions and 34 deletions.
4 changes: 3 additions & 1 deletion examples/load_config.yaml
Original file line number Diff line number Diff line change
@@ -2,7 +2,9 @@ file_format: '0.3'

resource:
attributes:
service.name: opentelemetry-demo
- name: service.name
value: opentelemetry-demo
attributes_list: service.name=unused,example.foo=foo_value,example.bar=bar_value

propagators:
composite: [ tracecontext, baggage ]
3 changes: 2 additions & 1 deletion examples/load_config_env.yaml
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@ disabled: ${OTEL_SDK_DISABLED}

resource:
attributes:
service.name: ${OTEL_SERVICE_NAME}
- name: service.name
value: ${OTEL_SERVICE_NAME}

propagators:
composite: [ tracecontext, baggage ]
16 changes: 13 additions & 3 deletions src/Config/SDK/ComponentProvider/Logs/LogRecordExporterOtlp.php
Original file line number Diff line number Diff line change
@@ -31,7 +31,8 @@ final class LogRecordExporterOtlp implements ComponentProvider
* certificate: ?string,
* client_key: ?string,
* client_certificate: ?string,
* headers: array<string, string>,
* headers: array,
* headers_list: ?string,
* compression: 'gzip'|null,
* timeout: int<0, max>,
* } $properties
@@ -40,10 +41,13 @@ public function createPlugin(array $properties, Context $context): LogRecordExpo
{
$protocol = $properties['protocol'];

$headers_list = array_column(array_map(fn ($item) => explode('=', $item), explode(',', $properties['headers_list'] ?? '')), 1, 0);
$headers = array_column($properties['headers'], 'value', 'name') + $headers_list;

return new LogsExporter(Registry::transportFactory($protocol)->create(
endpoint: $properties['endpoint'] . OtlpUtil::path(Signals::LOGS, $protocol),
contentType: Protocols::contentType($protocol),
headers: $properties['headers'],
headers: $headers,
compression: $properties['compression'],
timeout: $properties['timeout'],
cacert: $properties['certificate'],
@@ -63,8 +67,14 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit
->scalarNode('client_key')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->arrayNode('headers')
->scalarPrototype()->end()
->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(10)->end()
->end()
16 changes: 13 additions & 3 deletions src/Config/SDK/ComponentProvider/Metrics/MetricExporterOtlp.php
Original file line number Diff line number Diff line change
@@ -32,7 +32,8 @@ final class MetricExporterOtlp implements ComponentProvider
* certificate: ?string,
* client_key: ?string,
* client_certificate: ?string,
* headers: array<string, string>,
* headers: array,
* headers_list: ?string,
* compression: 'gzip'|null,
* timeout: int<0, max>,
* temporality_preference: 'cumulative'|'delta'|'lowmemory',
@@ -43,6 +44,9 @@ public function createPlugin(array $properties, Context $context): MetricExporte
{
$protocol = $properties['protocol'];

$headers_list = array_column(array_map(fn ($item) => explode('=', $item), explode(',', $properties['headers_list'] ?? '')), 1, 0);
$headers = array_column($properties['headers'], 'value', 'name') + $headers_list;

$temporality = match ($properties['temporality_preference']) {
'cumulative' => Temporality::CUMULATIVE,
'delta' => Temporality::DELTA,
@@ -52,7 +56,7 @@ public function createPlugin(array $properties, Context $context): MetricExporte
return new MetricExporter(Registry::transportFactory($protocol)->create(
endpoint: $properties['endpoint'] . OtlpUtil::path(Signals::METRICS, $protocol),
contentType: Protocols::contentType($protocol),
headers: $properties['headers'],
headers: $headers,
compression: $properties['compression'],
timeout: $properties['timeout'],
cacert: $properties['certificate'],
@@ -72,8 +76,14 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit
->scalarNode('client_key')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->arrayNode('headers')
->scalarPrototype()->end()
->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(10)->end()
->enumNode('temporality_preference')
19 changes: 16 additions & 3 deletions src/Config/SDK/ComponentProvider/OpenTelemetrySdk.php
Original file line number Diff line number Diff line change
@@ -56,6 +56,7 @@ final class OpenTelemetrySdk implements ComponentProvider
* disabled: bool,
* resource: array{
* attributes: array,
* attributes_list: ?string,
* schema_url: ?string,
* },
* attribute_limits: array{
@@ -113,10 +114,12 @@ public function createPlugin(array $properties, Context $context): SdkBuilder
if ($properties['disabled']) {
return $sdkBuilder;
}

$attribute_list = array_column(array_map(fn ($item) => explode('=', $item), explode(',', $properties['resource']['attributes_list'] ?? '')), 1, 0);
$attributes = array_column($properties['resource']['attributes'], 'value', 'name');
//todo merge with attributes_list
$resource = ResourceInfoFactory::defaultResource()
->merge(ResourceInfo::create(
attributes: Attributes::create($properties['resource']['attributes']),
attributes: Attributes::create($attributes + $attribute_list),
schemaUrl: $properties['resource']['schema_url'],
));

@@ -284,8 +287,18 @@ private function getResourceConfig(): ArrayNodeDefinition
->addDefaultsIfNotSet()
->children()
->arrayNode('attributes')
->variablePrototype()->end()
->arrayPrototype()
->children()
->scalarNode('name')->isRequired()->end()
->variableNode('value')->isRequired()->end()
// @todo use type to validate and/or cast attributes
->enumNode('type')->defaultNull()
->values(['string', 'bool', 'int', 'double', 'string_array', 'bool_array', 'int_array', 'double_array'])
->end()
->end()
->end()
->end()
->scalarNode('attributes_list')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('schema_url')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->end();

16 changes: 13 additions & 3 deletions src/Config/SDK/ComponentProvider/Trace/SpanExporterOtlp.php
Original file line number Diff line number Diff line change
@@ -31,7 +31,8 @@ final class SpanExporterOtlp implements ComponentProvider
* certificate: ?string,
* client_key: ?string,
* client_certificate: ?string,
* headers: array<string, string>,
* headers: array,
* headers_list: ?string,
* compression: 'gzip'|null,
* timeout: int<0, max>,
* } $properties
@@ -40,10 +41,13 @@ public function createPlugin(array $properties, Context $context): SpanExporterI
{
$protocol = $properties['protocol'];

$headers_list = array_column(array_map(fn ($item) => explode('=', $item), explode(',', $properties['headers_list'] ?? '')), 1, 0);
$headers = array_column($properties['headers'], 'value', 'name') + $headers_list;

return new SpanExporter(Registry::transportFactory($protocol)->create(
endpoint: $properties['endpoint'] . OtlpUtil::path(Signals::TRACE, $protocol),
contentType: Protocols::contentType($protocol),
headers: $properties['headers'],
headers: $headers,
compression: $properties['compression'],
timeout: $properties['timeout'],
cacert: $properties['certificate'],
@@ -63,8 +67,14 @@ public function getConfig(ComponentProviderRegistry $registry): ArrayNodeDefinit
->scalarNode('client_key')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->scalarNode('client_certificate')->defaultNull()->validate()->always(Validation::ensureString())->end()->end()
->arrayNode('headers')
->scalarPrototype()->end()
->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(10)->end()
->end()
3 changes: 2 additions & 1 deletion tests/Integration/Config/configurations/anchors.yaml
Original file line number Diff line number Diff line change
@@ -9,7 +9,8 @@ exporters:
client_key: /app/cert.pem
client_certificate: /app/cert.pem
headers:
api-key: !!str 1234
- name: api-key
value: "str 1234"
compression: gzip
timeout: 10000

68 changes: 49 additions & 19 deletions tests/Integration/Config/configurations/kitchen-sink.yaml
Original file line number Diff line number Diff line change
@@ -74,11 +74,13 @@ logger_provider:
#
# Environment variable: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE
client_certificate: /app/cert.pem
# Configure headers.
#
# Environment variable: OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_LOGS_HEADERS
# Configure headers. Entries have higher priority than entries from .headers_list.
headers:
api-key: "1234"
- name: api-key
value: "1234"
# Configure headers. Entries have lower priority than entries from .headers.
# The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.
headers_list: "api-key=1234"
# Configure compression.
#
# Environment variable: OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION
@@ -138,11 +140,13 @@ meter_provider:
#
# Environment variable: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE
client_certificate: /app/cert.pem
# Configure headers.
#
# Environment variable: OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_METRICS_HEADERS
# Configure headers. Entries have higher priority than entries from .headers_list.
headers:
api-key: !!str 1234
- name: api-key
value: "1234"
# Configure headers. Entries have lower priority than entries from .headers.
# The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.
headers_list: "api-key=1234"
# Configure compression.
#
# Environment variable: OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION
@@ -244,11 +248,13 @@ tracer_provider:
#
# Environment variable: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE
client_certificate: /app/cert.pem
# Configure headers.
#
# Environment variable: OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TRACES_HEADERS
# Configure headers. Entries have higher priority than entries from .headers_list.
headers:
api-key: !!str 1234
- name: api-key
value: "1234"
# Configure headers. Entries have lower priority than entries from .headers.
# The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.
headers_list: "api-key=1234"
# Configure compression.
#
# Environment variable: OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_TRACES_COMPRESSION
@@ -340,14 +346,38 @@ tracer_provider:

# Configure resource for all signals.
resource:
# Configure resource attributes.
#
# Environment variable: OTEL_RESOURCE_ATTRIBUTES
# Configure resource attributes. Entries have higher priority than entries from .resource.attributes_list.
# Entries must contain .name nand .value, and may optionally include .type, which defaults ot "string" if not set. The value must match the type. Values for .type include: string, bool, int, double, string_array, bool_array, int_array, double_array.
attributes:
# Configure `service.name` resource attribute
#
# Environment variable: OTEL_SERVICE_NAME
service.name: !!str "unknown_service"
- name: service.name
value: unknown_service
- name: string_key
value: value
type: string
- name: bool_key
value: true
type: bool
- name: int_key
value: 1
type: int
- name: double_key
value: 1.1
type: double
- name: string_array_key
value: [ "value1", "value2" ]
type: string_array
- name: bool_array_key
value: [ true, false ]
type: bool_array
- name: int_array_key
value: [ 1, 2 ]
type: int_array
- name: double_array_key
value: [ 1.1, 2.2 ]
type: double_array
# Configure resource attributes. Entries have lower priority than entries from .resource.attributes.
# The value is a list of comma separated key-value pairs matching the format of OTEL_RESOURCE_ATTRIBUTES. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details.
attributes_list: "service.namespace=my-namespace,service.version=1.0.0"
# Configure the resource schema URL.
schema_url: https://opentelemetry.io/schemas/1.27.0

0 comments on commit cb0a9eb

Please sign in to comment.