Skip to content

Define bound instrument API in metric/x - #8760

Merged
dashpole merged 10 commits into
open-telemetry:mainfrom
dashpole:bound-instruments-api
Sep 3, 2026
Merged

dashpole merged 10 commits into
open-telemetry:mainfrom
dashpole:bound-instruments-api

Conversation

@dashpole

@dashpole dashpole commented Aug 15, 2026 •

Copy link
Copy Markdown
Contributor

This is part 1 of #8759

@codecov

codecov Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.5%. Comparing base (5bac29f) to head (94f0839).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##            main   #8760     +/-   ##
=======================================
- Coverage   88.5%   88.5%   -0.1%     
=======================================
  Files        331     331             
  Lines      21012   21012             
=======================================
- Hits       18602   18600      -2     
- Misses      2410    2412      +2     
Files with missing lines Coverage Δ
metric/x/options.go 42.8% <ø> (ø)

... and 2 files with indirect coverage changes

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces the initial (stage 1) experimental “Bind” extension API surface in go.opentelemetry.io/otel/metric/x, aligning with the ongoing work tracked in #8759 to support bound instruments as an optimization for repeated attribute sets.

Changes:

  • Add experimental *Binder interfaces in metric/x that expose Bind(attrs ...attribute.KeyValue) for synchronous instruments.
  • Add a documentation example showing how callers can type-assert for binder support and fall back when unavailable.
  • Add a changelog entry describing the new experimental extension interfaces.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
metric/x/bound.go Defines the experimental *Binder interfaces for binding attributes ahead of time.
metric/x/example_test.go Adds a usage example demonstrating feature detection and fallback behavior.
CHANGELOG.md Documents the addition of the experimental binder interfaces in the Unreleased section.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread metric/x/bound.go Outdated
Comment thread metric/x/example_test.go
Comment thread CHANGELOG.md Outdated
@dashpole
dashpole marked this pull request as ready for review August 15, 2026 02:41
@dashpole
dashpole requested a lite review from Copilot August 15, 2026 13:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comment thread metric/x/bound.go Outdated
@dashpole
dashpole force-pushed the bound-instruments-api branch from 8572832 to 2ce590d Compare August 24, 2026 19:11

@MrAlias MrAlias left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I want to revisit the rollout plan for bound instruments. The earlier prototypes have moved toward putting this experimental support on regular sdk/metric instrument values. After tracing the SDK-first/API-second transition, I think that is the wrong host for the experiment.

The SDK release that precedes a stable API change needs to implement the exact API we choose to stabilize. This experiment currently uses a Bind method that returns the existing metric instrument types, but that is part of what we still need to evaluate; the stable API could instead use a dedicated bound-instrument type. I do not want us to make the regular sdk/metric instrument methods the place where we iterate on that choice.

Could we update #8759 to prototype this through an experimental sdk/metric/x façade, backed by whatever shared internal pipeline and aggregation extraction is needed? That would let us evaluate the API and implementation while keeping the experimental concrete instruments out of the regular SDK. When the experiment converges, we can add the final implementation to sdk/metric, release it, and add the stable API in the following release.

I recognize this reverses the direction of the earlier prototype work. I think the separation is necessary, and I would like to agree on this rollout before treating #8354 or similar work as the merge path for regular sdk/metric.

@dashpole
dashpole marked this pull request as draft August 26, 2026 13:35
@dashpole

Copy link
Copy Markdown
Contributor Author

Converting to draft while we discuss in #8759

@MrAlias MrAlias left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM outside of mentioned clean-up.

Comment thread metric/x/bound.go Outdated
Comment thread CHANGELOG.md Outdated
@dashpole
dashpole force-pushed the bound-instruments-api branch from 8d29cb2 to bf20df9 Compare August 31, 2026 19:45
@dashpole
dashpole marked this pull request as ready for review September 3, 2026 12:51
@dashpole

dashpole commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

@MrAlias Do you want to merge this now so we can use it for prototypes? Or do you want to wait until we have a better understanding of how we plan to structure the SDK's implementation? Feel free to merge if you are happy with it.

@dashpole
dashpole merged commit c84884a into open-telemetry:main Sep 3, 2026
51 checks passed
@dashpole
dashpole deleted the bound-instruments-api branch September 3, 2026 16:51
pellared added a commit that referenced this pull request Oct 2, 2026
This release contains the first stable release of the OpenTelemetry Go
Logs API and SDK.
Our project stability guarantees now apply to the following modules:

- `go.opentelemetry.io/otel/log`
- `go.opentelemetry.io/otel/sdk/log`

See our [versioning
policy](https://github.com/open-telemetry/opentelemetry-go/blob/main/VERSIONING.md)
for more information about these stability guarantees.

### Added

- Add `String` method for `KeyValue` type in
`go.opentelemetry.io/otel/attribute`. (#8205)
- Add `String` method for `Set` type in
`go.opentelemetry.io/otel/attribute`. (#8347)
- Add `WithMaxExportBatchSize` to `go.opentelemetry.io/otel/sdk/metric`
to configure the maximum export batch size for `PeriodicReader`. (#8960)
- Add `WithAttributeValueDepthLimit`, `DefaultAttributeValueDepthLimit`,
and `SpanLimits.AttributeValueDepthLimit` in
`go.opentelemetry.io/otel/sdk/trace` to configure the maximum depth of
span, event, link, and instrumentation scope attribute values. (#8938)
- Add `WithAttributeValueDepthLimit` in
`go.opentelemetry.io/otel/sdk/log` to configure the maximum depth of log
record and instrumentation scope attribute values. (#8938)
- Add `WithMaxResponseSize` to
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`,
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`, and
  `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8941)
- Add experimental `ProbabilitySampler` in
`go.opentelemetry.io/otel/sdk/trace/x` that conforms to the
[OpenTelemetry specification's threshold-based sampling
algorithm](https://opentelemetry.io/docs/specs/otel/trace/sdk/#probabilitysampler).
(#8123)
- Add experimental `*Binder` extension interfaces in
`go.opentelemetry.io/otel/metric/x` for instruments that support binding
attributes ahead of time. (#8760)
- Add the experimental `Finisher` synchronous metric instrument
extension interface to `go.opentelemetry.io/otel/metric/x`. (#8906)

### Changed

- Use the [OpenTelemetry Attribute Collection representation for
non-OTLP
protocols](https://opentelemetry.io/docs/specs/otel/common/#attribute-collection-representation-for-non-otlp)
for metric data diffs in
`go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#8993)
- Apply a maximum depth of 64 by default to span, event, link, log
record, and instrumentation scope attribute values in
`go.opentelemetry.io/otel/sdk/trace` and
`go.opentelemetry.io/otel/sdk/log`. (#8938)
- Reduce allocations when applying attribute value length limits in
`go.opentelemetry.io/otel/sdk/trace` and
`go.opentelemetry.io/otel/sdk/log` by rebuilding composite values only
when truncation is needed. (#8912)
- Decode `traceparent` using a hex lookup table in
`go.opentelemetry.io/otel/propagation`, which rejects the
specification-disallowed upper-case characters without a separate scan
of the header. (#8739)
- Decode all characters at constant indices in `TraceIDFromHex` and
`SpanIDFromHex` in `go.opentelemetry.io/otel/trace` to eliminate bounds
checks. (#8740)

### Fixed

- Count valid U+FFFD replacement characters toward attribute value
length limits in `go.opentelemetry.io/otel/trace`,
`go.opentelemetry.io/otel/sdk/trace`, and
`go.opentelemetry.io/otel/sdk/log`.
- Truncate string attribute values to empty strings when the configured
length limit is zero, including malformed UTF-8, in
`go.opentelemetry.io/otel/trace`, `go.opentelemetry.io/otel/sdk/trace`,
and `go.opentelemetry.io/otel/sdk/log`. (#9054)
- Fix a data race in `NewPeriodicReader` where `r.inst` was assigned
after the background goroutine was launched in
`go.opentelemetry.io/otel/sdk/metric`. (#9028)
- Prevent precision loss for large `int64` values in `Sum`, `Histogram`,
and `ExponentialHistogram` aggregations in
`go.opentelemetry.io/otel/sdk/metric`. (#8981)
- Ensure `grpc.DialOption` values passed via `WithDialOption` take
precedence over conflicting internally-computed defaults in
  `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`,
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`, and
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
(#8805, #8834, #8836)
- Treat overflowing `OTEL_METRIC_EXPORT_INTERVAL` and
`OTEL_METRIC_EXPORT_TIMEOUT` values as invalid in
`go.opentelemetry.io/otel/sdk/metric`. (#8800)
- Prevent a panic in `NewFixedSizeReservoir` and
`FixedSizeReservoirProvider` when given a negative size in
`go.opentelemetry.io/otel/sdk/metric/exemplar`; negative sizes are now
clamped to zero, consistent with a size of zero. (#8832)
- Preserve exponential histogram `ZeroThreshold` during OTLP metric
export in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8801)
- Ensure metric helpers in `go.opentelemetry.io/otel/semconv/v1.32.0`,
`go.opentelemetry.io/otel/semconv/v1.33.0`, and
`go.opentelemetry.io/otel/semconv/v1.34.0` record measurements only once
when no attributes are provided. (#8849)
- Treat empty `OTEL_TRACES_SAMPLER` and `OTEL_TRACES_SAMPLER_ARG` values
as unset in `go.opentelemetry.io/otel/sdk/trace`. (#8873)
- Normalize global `OTEL_EXPORTER_OTLP_ENDPOINT` path joining in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` so
trailing-slash base URLs do not produce double-slash log export paths.
(#8864)
- Prevent a deadlock when formatting an error passed to `RecordError`
calls back into the span in `go.opentelemetry.io/otel/sdk/trace`.
(#8815)
- Prevent `SimpleSpanProcessor.Shutdown` from panicking when constructed
with a nil exporter in `go.opentelemetry.io/otel/sdk/trace`. (#8844)
- Propagate invalid exponential histogram scale errors to Prometheus
exporter self-observability metrics in
`go.opentelemetry.io/otel/exporters/prometheus`. (#8839)
- Retain instrument advisory attributes configured with
`go.opentelemetry.io/otel/metric/x.WithDefaultAttributes` when a
matching View in `go.opentelemetry.io/otel/sdk/metric` does not specify
an attribute filter. (#8859)
- Ignore HTTP URL paths when building OTLP/gRPC metric exporter targets
from `OTEL_EXPORTER_OTLP_ENDPOINT` and
`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`, while preserving `unix://` and
`unix-abstract://` targets; treat `unix-abstract://` endpoints as
insecure in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#8862)
- Ignore HTTP(S) paths when deriving gRPC trace exporter endpoints from
`OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
(#8852)
- Bound memory used while parsing dense W3C property metadata by storing
it compactly and materializing `Property` values on demand in
`go.opentelemetry.io/otel/baggage` and
`go.opentelemetry.io/otel/propagation`.

### Removed

- Remove the experimental `OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE`
environment variable in `go.opentelemetry.io/otel/sdk/metric`.
  Use the `WithMaxExportBatchSize` option instead. (#8960)
@pellared pellared added this to the v1.47.0 milestone Oct 2, 2026
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.

4 participants