Skip to content

Comments

feat(config): Add exporter customizers for declarative config (#6576)#8081

Open
MikeGoldsmith wants to merge 12 commits intoopen-telemetry:mainfrom
honeycombio:mike/exporter-customizers-clean
Open

feat(config): Add exporter customizers for declarative config (#6576)#8081
MikeGoldsmith wants to merge 12 commits intoopen-telemetry:mainfrom
honeycombio:mike/exporter-customizers-clean

Conversation

@MikeGoldsmith
Copy link
Member

Summary

Adds exporter customizers to DeclarativeConfigurationCustomizer for programmatic customization of SpanExporter, MetricExporter, and LogRecordExporter instances created from declarative configuration.

Fixes #6576

Changes

  • Added addSpanExporterCustomizer(), addMetricExporterCustomizer(), addLogRecordExporterCustomizer() to DeclarativeConfigurationCustomizer
  • Customizers compose in SPI registration order via mergeBiFunctionCustomizer() in DeclarativeConfigurationBuilder
  • Factories apply customizers after component creation with fail-fast null checks
  • Comprehensive tests: builder composition, factory application, integration end-to-end

- Add SpanExporter/MetricExporter/LogRecordExporter customizers to DeclarativeConfigurationCustomizer
- Customizers compose in SPI registration order
- Apply in factories after component creation, before return
- Null returns throw DeclarativeConfigException
- Tests: factory unit tests, builder composition tests, integration tests
@MikeGoldsmith MikeGoldsmith requested a review from a team as a code owner February 13, 2026 14:49
@codecov
Copy link

codecov bot commented Feb 13, 2026

Codecov Report

❌ Patch coverage is 94.54545% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.32%. Comparing base (284a64f) to head (d977871).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...or/fileconfig/DeclarativeConfigurationBuilder.java 89.65% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##               main    #8081   +/-   ##
=========================================
  Coverage     90.32%   90.32%           
- Complexity     7607     7617   +10     
=========================================
  Files           839      839           
  Lines         22888    22940   +52     
  Branches       2283     2289    +6     
=========================================
+ Hits          20673    20721   +48     
- Misses         1506     1508    +2     
- Partials        709      711    +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@jack-berg jack-berg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm supportive of these customizers because even though we want to encourage modeling all properties that matter in the opentelemetry-configuration schema, it will never be possible to cover all cases (e.g. think the executor service used to eval async requests), and we'll want an escape hatch to leverage when a a property hasn't yet been modeled in declarative config but will be.

The exporters are a good place to start because there are known gaps in the what can be expressed in declarative config (i.e. authenticators).

Let's hold off modeling additional customizers (e.g. span processors, propagators, etc) until there are concrete requests by end users or distributions which require them.

Reduces noise of 3 separate setter calls for exporter customizers.
Context stores builder ref and delegates customizer access.

Note: Built using Claude Sonnet 4.5
…nfig

- Change customizer signature to use Class<T> for type-safe filtering
- Add DeclarativeConfigProperties parameter for access to config
- Consolidate type cast in ExporterCustomizer constructor
- Handle null returns gracefully with logging instead of exception
…ilder

- Rename ExporterCustomizer -> Customizer (concept isn't exporter-specific)
- Move null-check/type-check into Customizer.maybeCustomize(); throw
  DeclarativeConfigException if customizer returns null (fail-fast)
- Add exporter customizer methods to DeclarativeConfigurationCustomizer
  interface and DeclarativeConfigurationBuilder
- Add setBuilder/getBuilder to DeclarativeConfigContext; getBuilder uses
  requireNonNull (missing builder is a programming error)
- Wire builder into DeclarativeConfiguration.create() and all three
  exporter factory classes

Claude Sonnet 4.6 assisted with this change.
Each factory test now has four new cases:
- create_Customizer: generic customizer applied to all exporters
- create_Customizer_TypeSafe: type-specific customizer with builder access
- create_Customizer_TypeMismatch: verifies customizer not called for wrong type
- create_Customizer_ReturnsNull: verifies DeclarativeConfigException thrown

Claude Sonnet 4.6 assisted with this change.
- Update file_format from 1.0-rc.1 to 1.0-rc.3 in create tests
- Add context.setBuilder() to @beforeeach in all factory tests that
  indirectly call exporter factories (processor, reader, provider tests)

Claude Sonnet 4.6 assisted with this change.
…nto mike/exporter-customizers-clean

# Conflicts:
#	sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java
@MikeGoldsmith
Copy link
Member Author

I think I've worked through all of your feedback @jack-berg, please take another look 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How should AutoConfigurationCustomizer work when file configuration is used

2 participants