-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add exemplars to the metric SDK as an experimental feature #4455
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
Changes from 7 commits
593a45b
c37db57
becb3a0
141afc0
778c62e
99f6b14
0486576
c423127
1d571d5
b997bd3
ac0cf70
ebe1807
e694fb8
623ed1b
6a94b22
c4d8381
0741f43
f77205f
11bace0
d2171e7
27bc3e7
b044f34
b729954
6d2dfaa
3b4a1b5
4460389
925675f
bb1c495
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // Copyright The OpenTelemetry Authors | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package metric // import "go.opentelemetry.io/otel/sdk/metric" | ||
|
|
||
| import ( | ||
| "os" | ||
|
|
||
| "go.opentelemetry.io/otel/sdk/metric/internal/exemplar" | ||
| "go.opentelemetry.io/otel/sdk/metric/internal/x" | ||
| ) | ||
|
|
||
| // reservoirFunc returns the appropriately configured exemplar reservoir | ||
| // creation func based on the passed InstrumentKind and user defined | ||
| // environment variables. | ||
| // | ||
| // Note: This will only return non-nil values when the experimental exemplar | ||
| // feature is enabled. | ||
| func reservoirFunc[N int64 | float64](agg Aggregation) func() exemplar.Reservoir[N] { | ||
| if !x.Enabled(x.Exemplars) { | ||
| return nil | ||
| } | ||
|
|
||
| // https://github.com/open-telemetry/opentelemetry-specification/blob/d4b241f451674e8f611bb589477680341006ad2b/specification/configuration/sdk-environment-variables.md#exemplar | ||
| const filterEnvKey = "OTEL_METRICS_EXEMPLAR_FILTER" | ||
|
|
||
| var fltr exemplar.Filter[N] | ||
| switch os.Getenv(filterEnvKey) { | ||
| case "always_on": | ||
| fltr = exemplar.AlwaysSample[N] | ||
| case "always_off": | ||
| fltr = exemplar.NeverSample[N] | ||
| case "trace_based": | ||
| fallthrough | ||
| default: | ||
| fltr = exemplar.TraceBasedSample[N] | ||
| } | ||
|
|
||
| // TODO: This is not defined by the specification, nor is the mechanism to | ||
| // configure it. | ||
| const defaultFixedSize = 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI - I'm planning to update the specification here witha I'm not sure if Go suffers from the same contention issues, but might be worth benchmarking.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, that's interesting. I need to look into it. My guess is this would also benefit in using that value (which is pretty accessible). |
||
|
|
||
| // https://github.com/open-telemetry/opentelemetry-specification/blob/d4b241f451674e8f611bb589477680341006ad2b/specification/metrics/sdk.md#exemplar-defaults | ||
| resF := func() func() exemplar.Reservoir[N] { | ||
| a, ok := agg.(AggregationExplicitBucketHistogram) | ||
| if ok && len(a.Boundaries) > 1 { | ||
| cp := make([]float64, len(a.Boundaries)) | ||
| copy(cp, a.Boundaries) | ||
| return func() exemplar.Reservoir[N] { | ||
| bounds := cp | ||
| return exemplar.Histogram[N](bounds) | ||
| } | ||
| } | ||
|
|
||
| return func() exemplar.Reservoir[N] { | ||
| return exemplar.FixedSize[N](defaultFixedSize) | ||
| } | ||
| }() | ||
|
|
||
| return func() exemplar.Reservoir[N] { | ||
| return exemplar.Filtered[N](resF(), fltr) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI - #2421 - I think we're going to recommend that the filter is a configuration setting on the SDK (likely meter provider).
IIUC the architecture, this would still be feasible in Go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense to me, but we will have to wait for exemplars to become stable to add it to the stable API interface of the SDK.
I was talking with @dashpole and I was also wondering if we even need exemplar filters to start here. Might be something to consider at the spec level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open-telemetry/opentelemetry-specification#3820 <- The interface no longer needs to be exposed to users, but the configuration needs to be SDK-wide.