opentelemetry-java icon indicating copy to clipboard operation
opentelemetry-java copied to clipboard

Make `AutoConfiguredOpenTelemetrySdk`'s `resource` and `config` readable

Open cyrille-leclerc opened this issue 11 months ago • 4 comments

Is your feature request related to a problem? Please describe.

Authors of OpenTelemetry integrations like the OpenTelemetry Maven Extension and the Jenkins OpenTelemetry Plugin are interested in read-only access to the config and resource loaded by the AutoConfiguredOpenTelemetrySdk during the build() creation method in order to ease troubleshooting and finding produced traces & metrics showing users the noteworthy

  • Actual config like the exporters
  • Actual resourcelike service.name and service.namespace

Describe the solution you'd like

Accessors to resource and config .

A solution to access the config is already available with i.o.s.autoconfigure.internal.AutoConfigureUtil#getConfig() | getStructuredConfig() .

I imagined:

  • Either introduce AutoConfigureUtil#getResource()
  • Or make #getResource(), getConfig(), and getStructuredConfig() public on AutoConfiguredOpenTelemetrySdk

This use cas is discussed with @SylvainJuge on

  • https://github.com/open-telemetry/opentelemetry-java-contrib/pull/1434#pullrequestreview-2488186232

Describe alternatives you've considered

Today we rely on Java reflection in the Jenkisn OTel Plugin: https://github.com/open-telemetry/opentelemetry-java-contrib/pull/1434/files#diff-d2ce824d3b67fe3fe10a6aee588ea13e40a93d71743dc2982e2fc1d3ae797b0f

Additional context

cyrille-leclerc avatar Dec 09 '24 19:12 cyrille-leclerc

If its for troubleshooting purposes, have you considered just calling AutoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk().toString()?

We're pretty good about including all the useful config properties in the string output. I think it should be common practice to print out the resolved OpenTelemetrySdk string representation in a logger. Probably at a fine granularity log level so users opt into it. Note that this is what the otel java agent does.

At you've probably noted AutoConfigureUtil and all its methods are internal and subject to breaking change.

The problem with accessing the autoconfigured resource is that in all the cases I've seen so far, its always been the wrong thing to do.

The problem with accessing the autoconfigured config is that we're going in a direction where the config will either be ConfigProperties (if using env vars / system properties), or StructuredConfigProperties (if using declarative config). I'm quite sure even if we document that only one or the other is non-null, callers will still open issues frustrated that ConfigProperties is null.

jack-berg avatar Dec 09 '24 19:12 jack-berg

Thanks Jack, I'll try the toString() solution.

cyrille-leclerc avatar Dec 10 '24 17:12 cyrille-leclerc

Hi, I'd also like this. I manage the instrumentation layer for a few thousand engineers deploying code to several different environments. What I would like to be able to do is sanity check the provided configuration, as well as e.g. try to open a socket to the configured endpoint, check if anything is listening, and report metrics / provide a URL to internal documentation if not.

I have spent the last few hours reading through the code and I'm similarly confused why there needs to be a distinction between config properties and structured config properties - at the end of the day you can only read one value out, set one value for e.g. the batch log processing queue size, etc.

I would not like to recreate most/all of this logic myself but I'm not sure what other options I have.

kevinburke avatar Mar 14 '25 04:03 kevinburke

I have spent the last few hours reading through the code and I'm similarly confused why there needs to be a distinction between config properties and structured config properties - at the end of the day you can only read one value out, set one value for e.g. the batch log processing queue size, etc.

The way information is structured and accessed is too different for the flat config scheme + ConfigProperties as compared to the structured config scheme + DeclarativeConfigProperties (previously called StructuredConfigProperties).

Flat config consists of config file expressed like (either via property file, system properties, env vars, or some combination):

otel.metrics.exporter=otlp,console
otel.exporter.otlp.endpoint=http://localhost:4318
otel.metric.export.internal=30s

And you read properties out using ConfigProperties and something like:

List<String> metricExporters = configProperties.getList("otel.metrics.exporter");
String otlpEndpoint = configProperties.getString("otel.exporter.otlp.endpoint");
int exportInterval = configProperties.getDuration("otel.metric.export.interval");

This flat structure is very limiting in terms of how you can express desired config. For example, how would you indicate that you want to export to two different OTLP destinations with different configs? How would you express view configuration? Its not that you can't express these things. Rather, its difficult, and you end up jumping through hooops and coming up with encoding schemes.

And so otel as a project set out to support a config scheme that was language agnostic, and supported expressing structured data. Declarative config is the result, and encodes data using YAML with the equivalent of the example above being something like:

meter_provider:
  readers:
    - periodic:
         interval: 30_000
         exporter:
           otlp_http:
             endpoint: http://localhost:4318/v1/metrics
    - periodic:
         exporter:
           console:

The ConfigProperties API, designed around accessing data encoded in a flat scheme of key/value pairs, has no analog here. What should configProperties.getList("otel.metrics.exporter") return? For users and distributions accustomed to ConfigProperties API and a corresponding flat scheme, trying retrofit the API to represent a world with YAML and structured data would lead to confusion probably bugs.

So instead of trying to jam a square peg into a round hole, we have a clean split. We introduce a new DeclarativeConfigProperties API which is designed explicitly for the YAML / structured config world. We continue to support but eventually deprecate the flat config scheme with ConfigProperties. The price for this clean break is that distributions / power users customizing configuration need to be aware of both config modes. But better for these users to have to explicitly write similar logic for both config modes than to write the logic "once" and have to be implicitly aware of the differences and likely be brittle / buggy as a result.

jack-berg avatar Jun 11 '25 19:06 jack-berg