Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

otel: conceal unwrapping for global async instrument registration #5881

Merged
merged 19 commits into from
Oct 18, 2024

Conversation

jmacd
Copy link
Contributor

@jmacd jmacd commented Oct 10, 2024

Two defects are fixed here. However, note that async instrument delegation appears to have been broken a long time.

Internalizes and tests the behavior of the Global MeterProvider. This moves the call to Unwrap() out of the SDK, fully concealing it within the internal/global package (using an un-exported method).

This adds a test for the new functionality. While this test is not comprehensive, because it doesn't test every instrument variation, it explicitly tests that both the NewCallback function and the Observe functions receive objects constructed by the alternate SDK.

Fixes #5827

Copy link

codecov bot commented Oct 10, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.6%. Comparing base (81b2a33) to head (99a6b40).
Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main   #5881   +/-   ##
=====================================
  Coverage   84.5%   84.6%           
=====================================
  Files        272     272           
  Lines      22853   22861    +8     
=====================================
+ Hits       19323   19343   +20     
+ Misses      3181    3173    -8     
+ Partials     349     345    -4     

see 4 files with indirect coverage changes

@dashpole
Copy link
Contributor

dashpole commented Oct 10, 2024

Is this broken for our SDK as well?

if u, ok := inst.(interface {
Unwrap() metric.Observable
}); ok {
inst = u.Unwrap()
}

@dashpole dashpole added this to the v1.31.0 milestone Oct 10, 2024
@jmacd
Copy link
Contributor Author

jmacd commented Oct 10, 2024

I'm mildly confused by this. My expectation was that the internal/global package would hide details about the delgation and that SDKs would not need to unwrap themselves. Investigating!

@jmacd
Copy link
Contributor Author

jmacd commented Oct 10, 2024

@dashpole PTAL

You pointed me to more tests w/ more nuance. The TestGlobalInstRegisterCallback test in sdk/metric exercises a case with mixed use of pre-registration and post-registration instruments. I've corrected this PR to pass all tests.

The unwrap() method is non-exported again. SDKs should not need to call such a method.

@jmacd
Copy link
Contributor Author

jmacd commented Oct 10, 2024

For what it's worth, I ran the tests in otel-launcher-go that had broken and they are fixed by this PR.

Copy link
Contributor

@dashpole dashpole left a comment

Choose a reason for hiding this comment

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

I tried to figure out why the unwrapping was done in the SDK in #3584, but can't figure it out. This LGTM, but I would really like @MrAlias to review if he remembers why this was done

@jmacd jmacd changed the title (internal/global/meter.go): Fix unwrapping for global async instrument registration (internal/global/meter.go): Unwrapping for global async instrument registration Oct 10, 2024
@jmacd
Copy link
Contributor Author

jmacd commented Oct 10, 2024

@dashpole As we discussed, I'll leave this open.
I think it is safe to release this repo as-is. The fact that unwrap() is called, doing nothing, appears harmless for OTel-Go SDK users. For the alternate SDK user, I can work around this by calling Unwrap(). I would be glad to see this PR applied after the release, but I'll accept if you decide to keep calling Unwrap() the SDK's responsibility. If so, I'd propose to add a public Unwrap interface and documentation. I'll leave it up to you and @MrAlias. Thanks!

@jmacd jmacd changed the title (internal/global/meter.go): Unwrapping for global async instrument registration (internal/global/meter.go): Conceal unwrapping for global async instrument registration Oct 10, 2024
Copy link
Contributor

@dashpole dashpole left a comment

Choose a reason for hiding this comment

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

I would like to wait to merge this until after the release.

@pellared
Copy link
Member

Do we want to make a patch release after this is merged?

@dashpole
Copy link
Contributor

Do we want to make a patch release after this is merged?

I don't think so. This fixes a bug for alternative SDKs. Based on #5881 (comment), @jmacd is going to work around the issue in the meantime.

@MrAlias MrAlias modified the milestones: v1.31.0, v1.32.0 Oct 14, 2024
jmacd added a commit to lightstep/otel-launcher-go that referenced this pull request Oct 15, 2024
**Description:** Updates to OTel-Go 1.31 require minor LS Metric SDK
fixes (see Unwrap()), discussed and fixed in the upstream PR
open-telemetry/opentelemetry-go#5881. The
Unwrap() calls here are to work around the problem until fully fixed
upstream.

**Link to tracking Issue:**
open-telemetry/opentelemetry-go#5827 explains
how we got here.

Part of #794.

**Testing:** Incomplete. Existing tests were logging messages about
foreign instruments in the asynchronous call path, but nothing failed as
a result.
@jmacd
Copy link
Contributor Author

jmacd commented Oct 16, 2024

I worked around the problem as stated above, so I consider this a nice-to-have low priority fix. The workaround, in case anyone else cares, is

	if unwrapped, ok := inst.(interface {
		Unwrap() metric.Observable
	}); ok {
		inst = unwrapped.Unwrap()
	}

I needed to do this in two places related to asynchronous instrument handling. The global package hides this detail as far as synchronous instruments are concerned. Link.

@pellared pellared changed the title (internal/global/meter.go): Conceal unwrapping for global async instrument registration otel: conceal unwrapping for global async instrument registration Oct 16, 2024
@pellared pellared added the pkg:API Related to an API package label Oct 16, 2024
internal/global/meter.go Outdated Show resolved Hide resolved
@MrAlias MrAlias merged commit 2578acc into open-telemetry:main Oct 18, 2024
32 checks passed
@jmacd jmacd deleted the jmacd/unwrap branch October 18, 2024 21:56
pellared added a commit that referenced this pull request Nov 8, 2024
### Added

- Add `go.opentelemetry.io/otel/sdk/metric/exemplar.AlwaysOffFilter`,
which can be used to disable exemplar recording. (#5850)
- Add `go.opentelemetry.io/otel/sdk/metric.WithExemplarFilter`, which
can be used to configure the exemplar filter used by the metrics SDK.
(#5850)
- Add `ExemplarReservoirProviderSelector` and
`DefaultExemplarReservoirProviderSelector` to
`go.opentelemetry.io/otel/sdk/metric`, which defines the exemplar
reservoir to use based on the aggregation of the metric. (#5861)
- Add `ExemplarReservoirProviderSelector` to
`go.opentelemetry.io/otel/sdk/metric.Stream` to allow using views to
configure the exemplar reservoir to use for a metric. (#5861)
- Add `ReservoirProvider`, `HistogramReservoirProvider` and
`FixedSizeReservoirProvider` to
`go.opentelemetry.io/otel/sdk/metric/exemplar` to make it convenient to
use providers of Reservoirs. (#5861)
- The `go.opentelemetry.io/otel/semconv/v1.27.0` package.
The package contains semantic conventions from the `v1.27.0` version of
the OpenTelemetry Semantic Conventions. (#5894)
- Add `Attributes attribute.Set` field to `Scope` in
`go.opentelemetry.io/otel/sdk/instrumentation`. (#5903)
- Add `Attributes attribute.Set` field to `ScopeRecords` in
`go.opentelemetry.io/otel/log/logtest`. (#5927)
- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` adds
instrumentation scope attributes. (#5934)
- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` adds
instrumentation scope attributes. (#5934)
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`
adds instrumentation scope attributes. (#5935)
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`
adds instrumentation scope attributes. (#5935)
- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` adds
instrumentation scope attributes. (#5933)
- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` adds
instrumentation scope attributes. (#5933)
- `go.opentelemetry.io/otel/exporters/prometheus` adds instrumentation
scope attributes in `otel_scope_info` metric as labels. (#5932)

### Changed

- Support scope attributes and make them as identifying for `Tracer` in
`go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/trace`.
(#5924)
- Support scope attributes and make them as identifying for `Meter` in
`go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/metric`.
(#5926)
- Support scope attributes and make them as identifying for `Logger` in
`go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/log`.
(#5925)
- Make schema URL and scope attributes as identifying for `Tracer` in
`go.opentelemetry.io/otel/bridge/opentracing`. (#5931)
- Clear unneeded slice elements to allow GC to collect the objects in
`go.opentelemetry.io/otel/sdk/metric` and
`go.opentelemetry.io/otel/sdk/trace`. (#5804)

### Fixed

- Global MeterProvider registration unwraps global instrument Observers,
the undocumented Unwrap() methods are now private. (#5881)
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`
now keeps the metadata already present in the context when `WithHeaders`
is used. (#5892)
- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` now
keeps the metadata already present in the context when `WithHeaders` is
used. (#5911)
- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` now
keeps the metadata already present in the context when `WithHeaders` is
used. (#5915)
- Fix `go.opentelemetry.io/otel/exporters/prometheus` trying to add
exemplars to Gauge metrics, which is unsupported. (#5912)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
(#5944)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#5944)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
(#5944)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
(#5944)
- Fix incorrect metrics generated from callbacks when multiple readers
are used in `go.opentelemetry.io/otel/sdk/metric`. (#5900)

### Removed

- Remove all examples under `go.opentelemetry.io/otel/example` as they
are moved to [Contrib
repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples).
(#5930)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg:API Related to an API package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Regression: Delegation broken for global meterproviders
5 participants