You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-25 22:41:46 +02:00
Add selector of exemplar reservoir providers to metric.Stream configuration (#5861)
Resolve https://github.com/open-telemetry/opentelemetry-go/issues/5249 ### Spec > exemplar_reservoir: A functional type that generates an exemplar reservoir a MeterProvider will use when storing exemplars. This functional type needs to be a factory or callback similar to aggregation selection functionality which allows different reservoirs to be chosen by the aggregation. > Users can provide an exemplar_reservoir, but it is up to their discretion. Therefore, the stream configuration parameter needs to be structured to accept an exemplar_reservoir, but MUST NOT obligate a user to provide one. If the user does not provide an exemplar_reservoir value, the MeterProvider MUST apply a [default exemplar reservoir](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar-defaults). Also, > the reservoir MUST be given the Attributes associated with its timeseries point either at construction so that additional sampling performed by the reservoir has access to all attributes from a measurement in the "offer" method. ### Changes In sdk/metric/exemplar, add: * `exemplar.ReservoirProvider` * `exemplar.HistogramReservoirProvider` * `exemplar.FixedSizeReservoirProvider` In sdk/metric, add: * `metric.ExemplarReservoirProviderSelector` (func Aggregation -> ReservoirProvider) * `metric.DefaultExemplarReservoirProviderSelector` (our default implementation) * `ExemplarReservoirProviderSelector` added to `metric.Stream` Note: the only required public types are `metric.ExemplarReservoirProviderSelector` and `ExemplarReservoirProviderSelector` in `metric.Stream`. Others are for convenience and readability. ### Alternatives considered #### Add ExemplarReservoirProvider directly to metric.Stream, instead of ExemplarReservoirProviderSelector This would mean users can configure a `func() exemplar.Reservoir` instead of a `func(Aggregation) func() exemplar.Reservoir`. I don't think this complies with the statement: `This functional type needs to be a factory or callback similar to aggregation selection functionality which allows different reservoirs to be chosen by the aggregation.`. I'm interpreting "allows different reservoirs to be chosen by the aggregation" as meaning "allows different reservoirs to be chosen **based on the** aggregation", rather than meaning that the aggregation is somehow choosing the reservoir. ### Future work There is some refactoring I plan to do after this to simplify the interaction between the internal/aggregate and exemplar package. I've omitted that from this PR to keep the diff smaller. --------- Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> Co-authored-by: Robert Pająk <pellared@hotmail.com>
This commit is contained in:
@@ -242,6 +242,31 @@ func ExampleNewView_exponentialHistogram() {
|
||||
)
|
||||
}
|
||||
|
||||
func ExampleNewView_exemplarreservoirproviderselector() {
|
||||
// Create a view that makes all metrics use a different exemplar reservoir.
|
||||
view := metric.NewView(
|
||||
metric.Instrument{Name: "*"},
|
||||
metric.Stream{
|
||||
ExemplarReservoirProviderSelector: func(agg metric.Aggregation) exemplar.ReservoirProvider {
|
||||
// This example uses a fixed-size reservoir with a size of 10
|
||||
// for explicit bucket histograms instead of the default
|
||||
// bucket-aligned reservoir.
|
||||
if _, ok := agg.(metric.AggregationExplicitBucketHistogram); ok {
|
||||
return exemplar.FixedSizeReservoirProvider(10)
|
||||
}
|
||||
// Fall back to the default reservoir otherwise.
|
||||
return metric.DefaultExemplarReservoirProviderSelector(agg)
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// The created view can then be registered with the OpenTelemetry metric
|
||||
// SDK using the WithView option.
|
||||
_ = metric.NewMeterProvider(
|
||||
metric.WithView(view),
|
||||
)
|
||||
}
|
||||
|
||||
func ExampleWithExemplarFilter_disabled() {
|
||||
// Use exemplar.AlwaysOffFilter to disable exemplar collection.
|
||||
_ = metric.NewMeterProvider(
|
||||
|
||||
Reference in New Issue
Block a user