Skip to content

Commit 52d2f66

Browse files
shivanthzenMrAlias
andauthored
Add support for native histogram exemplars (#6772)
Added support for exemplars in exponential histograms. Closes #5777 --------- Co-authored-by: Tyler Yahn <[email protected]>
1 parent d464abf commit 52d2f66

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
4848
See the [migration documentation](./semconv/v1.36.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.34.0.`(#7032)
4949
- Add experimental self-observability span metrics in `go.opentelemetry.io/otel/sdk/trace`.
5050
Check the `go.opentelemetry.io/otel/sdk/trace/internal/x` package documentation for more information. (#7027)
51+
- Add native histogram exemplar support in `go.opentelemetry.io/otel/exporters/prometheus`. (#6772)
5152

5253
### Changed
5354

exporters/prometheus/exporter.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,7 @@ func addExponentialHistogramMetric[N int64 | float64](
382382
otel.Handle(err)
383383
continue
384384
}
385-
386-
// TODO(GiedriusS): add exemplars here after https://github.com/prometheus/client_golang/pull/1654#pullrequestreview-2434669425 is done.
385+
m = addExemplars(m, dp.Exemplars, labelNamer)
387386
ch <- m
388387
}
389388
}

exporters/prometheus/exporter_test.go

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,18 @@ func TestExemplars(t *testing.T) {
11131113
escapingScheme: model.NoEscaping,
11141114
validationScheme: model.UTF8Validation,
11151115
},
1116+
{
1117+
name: "exponential histogram",
1118+
recordMetrics: func(ctx context.Context, meter otelmetric.Meter) {
1119+
hist, err := meter.Int64Histogram("exponential_histogram")
1120+
require.NoError(t, err)
1121+
hist.Record(ctx, 9, attrsOpt)
1122+
},
1123+
expectedExemplarValue: 9,
1124+
expectedLabels: expectedNonEscapedLabels,
1125+
escapingScheme: model.NoEscaping,
1126+
validationScheme: model.UTF8Validation,
1127+
},
11161128
} {
11171129
t.Run(tc.name, func(t *testing.T) {
11181130
originalEscapingScheme := model.NameEscapingScheme
@@ -1144,13 +1156,24 @@ func TestExemplars(t *testing.T) {
11441156
metric.WithReader(exporter),
11451157
metric.WithResource(res),
11461158
metric.WithView(metric.NewView(
1147-
metric.Instrument{Name: "*"},
1159+
metric.Instrument{Name: "foo"},
11481160
metric.Stream{
11491161
// filter out all attributes so they are added as filtered
11501162
// attributes to the exemplar
11511163
AttributeFilter: attribute.NewAllowKeysFilter(),
11521164
},
1153-
)),
1165+
),
1166+
),
1167+
metric.WithView(metric.NewView(
1168+
metric.Instrument{Name: "exponential_histogram"},
1169+
metric.Stream{
1170+
Aggregation: metric.AggregationBase2ExponentialHistogram{
1171+
MaxSize: 20,
1172+
},
1173+
AttributeFilter: attribute.NewAllowKeysFilter(),
1174+
},
1175+
),
1176+
),
11541177
)
11551178
meter := provider.Meter("meter", otelmetric.WithInstrumentationVersion("v0.1.0"))
11561179

@@ -1179,16 +1202,23 @@ func TestExemplars(t *testing.T) {
11791202
case dto.MetricType_COUNTER:
11801203
exemplar = metric.GetCounter().GetExemplar()
11811204
case dto.MetricType_HISTOGRAM:
1182-
for _, b := range metric.GetHistogram().GetBucket() {
1205+
h := metric.GetHistogram()
1206+
for _, b := range h.GetBucket() {
11831207
if b.GetExemplar() != nil {
11841208
exemplar = b.GetExemplar()
11851209
continue
11861210
}
11871211
}
1212+
if h.GetZeroThreshold() != 0 || h.GetZeroCount() != 0 ||
1213+
len(h.PositiveSpan) != 0 || len(h.NegativeSpan) != 0 {
1214+
require.NotNil(t, h.Exemplars)
1215+
exemplar = h.Exemplars[0]
1216+
}
11881217
}
11891218
require.NotNil(t, exemplar)
11901219
require.Equal(t, tc.expectedExemplarValue, exemplar.GetValue())
11911220
require.Len(t, exemplar.GetLabel(), len(tc.expectedLabels))
1221+
11921222
for _, label := range exemplar.GetLabel() {
11931223
val, ok := tc.expectedLabels[label.GetName()]
11941224
require.True(t, ok)

0 commit comments

Comments
 (0)