Skip to content

Commit c577dcb

Browse files
jack-bergmaryliag
andauthored
Add option to programmatically customization declarative config components, add supplementary guidance (#4777)
Resolves #4583. We've had discussions in the declarative config SIG recently about how programmatic configuration interacts with declarative config. Questions of what should take priority, and whether there should be options to programmatically customize (#4583) to address concepts which are not expressible in declarative config. The goal here is to avoid the type of spec ambiguity which resulted SDKs having such different behavior in environment variable <> programmatic configuration intersection. Declarative configuration is green field and for a short time longer is still experimental, and so we are not bound by historical constraints. Reading through the relevant specs, I do not think there is any ambiguity about configuration interface priority. `create` returns resolved top-level SDK components. If a SDK supports updating components, then the components returned by `create` will be subject to whatever semantics the SDK already has decided for how updates occur to SDK components programmatically created to begin with. To make this clear, I opted to add a new supplementary guidelines document to give advice to implementers without cluttering or adding more normative language. On a related note, I thought it was pertinent to address #4583 simultaneously, but adding explicit language to allow (i.e. normative MAY) implementations of `create` to allow programmatic customization of SDK components as they are initialized. cc/ @open-telemetry/configuration-approvers, @JamieDanielson, @maryliag, @pellared --------- Co-authored-by: Marylia Gutierrez <marylia.gutierrez@grafana.com>
1 parent e111347 commit c577dcb

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ release.
6565

6666
- Clarifies that guidance related to boolean environment variables is not applicable
6767
to other configuration interfaces. ([#4723](https://github.com/open-telemetry/opentelemetry-specification/pull/4723))
68+
- Declarative configuration: add optional programmatic customization to
69+
`create`, and add related supplemental guidelines.
70+
([#4777](https://github.com/open-telemetry/opentelemetry-specification/pull/4777))
6871

6972
## v1.51.0 (2025-11-17)
7073

specification/configuration/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Declarative configuration consists of the following main components:
5555
operations to parse configuration files and interpret the configuration data
5656
model.
5757

58+
See also [supplementary guidelines](./supplementary-guidelines.md).
59+
5860
### Other Mechanisms
5961

6062
Additional configuration mechanisms SHOULD be provided in whatever

specification/configuration/sdk.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,29 @@ This SHOULD return an error if it encounters an error in `configuration` (i.e.
302302
fail fast) in accordance with
303303
initialization [error handling principles](../error-handling.md#basic-error-handling-principles).
304304

305+
SDK implementations MAY provide options to allow programmatic customization of
306+
the components initialized by `Create`. This allows configuration of concepts which
307+
are not yet or may never be representable in the configuration model. For example,
308+
java OTLP exporters allow configuration of the [ExecutorService](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html),
309+
a niche but important option for applications which need strict control of thread pools.
310+
This programmatic customization might take the form of passing an optional callback to
311+
`Create`, invoked with each SDK subcomponent (or a subset of SDK component types) as
312+
they are initialized. For example, consider the following snippet:
313+
314+
```yaml
315+
file_format: 1.0
316+
tracer_provider:
317+
processors:
318+
- batch:
319+
exporter:
320+
otlp_http:
321+
```
322+
323+
The callback would be invoked with the SDK representation of an OTLP HTTP exporter, a
324+
Batch SpanProcessor, and a Tracer Provider. This pattern provides the opportunity
325+
to programmatically configure lower-level without needing to walk to a particular
326+
component from the resolved top level SDK components.
327+
305328
TODO: define behavior if some portion of configuration model is not supported
306329

307330
#### Register ComponentProvider
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Supplementary Guidelines
2+
3+
Note: this document is NOT a spec, it is provided to support the declarative config
4+
[API](./api.md) and [SDK](./sdk.md) specifications, it does NOT add any extra
5+
requirements to the existing specifications.
6+
7+
<details>
8+
<summary>Table of Contents</summary>
9+
10+
<!-- toc -->
11+
12+
- [Configuration interface prioritization and `create`](#configuration-interface-prioritization-and-create)
13+
- [Programmatic customization and `create`](#programmatic-customization-and-create)
14+
15+
<!-- tocstop -->
16+
17+
</details>
18+
19+
## Configuration interface prioritization and `create`
20+
21+
With the [environment variable](./sdk-environment-variables.md) configuration
22+
interface, the spec failed to answer the question of whether programmatic or
23+
environment variable configuration took precedence. This led to differences in
24+
implementations that were ultimately stabilized and difficult to resolve after
25+
the fact.
26+
27+
With declarative config, we don't have ambiguity around configuration interface
28+
precedence:
29+
30+
* [`parse`](./sdk.md#parse) is responsible for parsing config file contents and
31+
returning the corresponding in-memory data model. Along the way, it
32+
performs [environment variable substitution](./data-model.md#environment-variable-substitution).
33+
* [`create`](./sdk.md#create) is responsible for interpreting an in-memory
34+
config data model and creating SDK components.
35+
36+
There is no precedence ambiguity with the environment variable configuration
37+
interface: The language of `parse` and `create` is explicit about
38+
responsibilities and makes no mention of merging environment variables outside
39+
of environment variable substitution.
40+
Furthermore, [OTEL_EXPERIMENTAL_CONFIG_FILE](./sdk-environment-variables.md#declarative-configuration)
41+
explicitly states that the environment variable configuration scheme is ignored.
42+
43+
There is no precedence ambiguity with
44+
the [programmatic configuration interface](./README.md#programmatic): `create`
45+
consumes an in-memory config data model and creates SDK components. According to
46+
the trace, metric, and log specs, SDKs MAY support updating the config, but
47+
there is no conflict with declarative config which doesn't already exist.
48+
However, the SDK handles programmatic config updates to SDK components which
49+
originally programmatically configured applies here as well. If an SDK supports
50+
it, all programmatic config updates are applied after `create` initializes SDK
51+
components and therefore take precedence. The semantics of what programmatic
52+
config updates are allowed and how they merge with existing SDK components are
53+
out of scope for declarative config.
54+
55+
## Programmatic customization and `create`
56+
57+
While `create` does provide an optional mechanism for programmatic
58+
customization, its use should be considered a code smell, to be addressed by
59+
improving the declarative config data model.
60+
61+
For example, the fact that configuration of dynamic authentication for OTLP
62+
exporters is not possible to express with declarative config should not
63+
encourage the OpenTelemetry community to have better programmatic customization.
64+
Instead, we should pursue adding authentication as an SDK extension plugin
65+
interface and modeling this new plugin in declarative config.

0 commit comments

Comments
 (0)