1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-01-28 03:57:09 +02:00

add summary support to the OTLP exporter (#5100)

Co-authored-by: Chester Cheung <cheung.zhy.csu@gmail.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
David Ashpole 2024-03-25 11:15:02 -04:00 committed by GitHub
parent 32e3a3d994
commit 540663b064
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 475 additions and 0 deletions

View File

@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add `go.opentelemetry.io/otel/log/global` to manage the global `LoggerProvider`.
This package is provided with the anticipation that all functionality will be migrate to `go.opentelemetry.io/otel` when `go.opentelemetry.io/otel/log` stabilizes.
At which point, users will be required to migrage their code, and this package will be deprecated then removed. (#5085)
- Add support for `Summary` metrics in the `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` exporters. (#5100)
### Changed

View File

@ -98,6 +98,8 @@ func metric(m metricdata.Metrics) (*mpb.Metric, error) {
out.Data, err = ExponentialHistogram(a)
case metricdata.ExponentialHistogram[float64]:
out.Data, err = ExponentialHistogram(a)
case metricdata.Summary:
out.Data = Summary(a)
default:
return out, fmt.Errorf("%w: %T", errUnknownAggregation, a)
}
@ -307,3 +309,44 @@ func Exemplars[N int64 | float64](exemplars []metricdata.Exemplar[N]) []*mpb.Exe
}
return out
}
// Summary returns an OTLP Metric_Summary generated from s.
func Summary(s metricdata.Summary) *mpb.Metric_Summary {
return &mpb.Metric_Summary{
Summary: &mpb.Summary{
DataPoints: SummaryDataPoints(s.DataPoints),
},
}
}
// SummaryDataPoints returns a slice of OTLP SummaryDataPoint generated from
// dPts.
func SummaryDataPoints(dPts []metricdata.SummaryDataPoint) []*mpb.SummaryDataPoint {
out := make([]*mpb.SummaryDataPoint, 0, len(dPts))
for _, dPt := range dPts {
sdp := &mpb.SummaryDataPoint{
Attributes: AttrIter(dPt.Attributes.Iter()),
StartTimeUnixNano: timeUnixNano(dPt.StartTime),
TimeUnixNano: timeUnixNano(dPt.Time),
Count: dPt.Count,
Sum: dPt.Sum,
QuantileValues: QuantileValues(dPt.QuantileValues),
}
out = append(out, sdp)
}
return out
}
// QuantileValues returns a slice of OTLP SummaryDataPoint_ValueAtQuantile
// generated from quantiles.
func QuantileValues(quantiles []metricdata.QuantileValue) []*mpb.SummaryDataPoint_ValueAtQuantile {
out := make([]*mpb.SummaryDataPoint_ValueAtQuantile, 0, len(quantiles))
for _, q := range quantiles {
quantile := &mpb.SummaryDataPoint_ValueAtQuantile{
Quantile: q.Quantile,
Value: q.Value,
}
out = append(out, quantile)
}
return out
}

View File

@ -432,6 +432,83 @@ var (
DataPoints: pbEHDPFloat64,
}
quantileValuesA = []metricdata.QuantileValue{
{
Quantile: 0.0,
Value: 0.1,
},
{
Quantile: 0.5,
Value: 1.0,
},
{
Quantile: 1.0,
Value: 10.4,
},
}
quantileValuesB = []metricdata.QuantileValue{
{
Quantile: 0.0,
Value: 0.5,
},
{
Quantile: 0.5,
Value: 3.1,
},
{
Quantile: 1.0,
Value: 8.3,
},
}
pbQuantileValuesA = []*mpb.SummaryDataPoint_ValueAtQuantile{
{
Quantile: 0.0,
Value: 0.1,
},
{
Quantile: 0.5,
Value: 1.0,
},
{
Quantile: 1.0,
Value: 10.4,
},
}
pbQuantileValuesB = []*mpb.SummaryDataPoint_ValueAtQuantile{
{
Quantile: 0.0,
Value: 0.5,
},
{
Quantile: 0.5,
Value: 3.1,
},
{
Quantile: 1.0,
Value: 8.3,
},
}
otelSummaryDPts = []metricdata.SummaryDataPoint{
{
Attributes: alice,
StartTime: start,
Time: end,
Count: 20,
Sum: sumA,
QuantileValues: quantileValuesA,
},
{
Attributes: bob,
StartTime: start,
Time: end,
Count: 26,
Sum: sumB,
QuantileValues: quantileValuesB,
},
}
otelDPtsInt64 = []metricdata.DataPoint[int64]{
{
Attributes: alice,
@ -498,6 +575,25 @@ var (
},
}
pbDPtsSummary = []*mpb.SummaryDataPoint{
{
Attributes: []*cpb.KeyValue{pbAlice},
StartTimeUnixNano: uint64(start.UnixNano()),
TimeUnixNano: uint64(end.UnixNano()),
Count: 20,
Sum: sumA,
QuantileValues: pbQuantileValuesA,
},
{
Attributes: []*cpb.KeyValue{pbBob},
StartTimeUnixNano: uint64(start.UnixNano()),
TimeUnixNano: uint64(end.UnixNano()),
Count: 26,
Sum: sumB,
QuantileValues: pbQuantileValuesB,
},
}
otelSumInt64 = metricdata.Sum[int64]{
Temporality: metricdata.CumulativeTemporality,
IsMonotonic: true,
@ -551,6 +647,10 @@ var (
},
}}
pbSummary = &mpb.Summary{DataPoints: pbDPtsSummary}
otelSummary = metricdata.Summary{DataPoints: otelSummaryDPts}
unknownAgg unknownAggT
otelMetrics = []metricdata.Metrics{
{
@ -631,6 +731,12 @@ var (
Unit: "1",
Data: otelGaugeZeroStartTime,
},
{
Name: "summary",
Description: "Summary metric",
Unit: "1",
Data: otelSummary,
},
}
pbMetrics = []*mpb.Metric{
@ -688,6 +794,12 @@ var (
Unit: "1",
Data: &mpb.Metric_Gauge{Gauge: pbGaugeZeroStartTime},
},
{
Name: "summary",
Description: "Summary metric",
Unit: "1",
Data: &mpb.Metric_Summary{Summary: pbSummary},
},
}
otelScopeMetrics = []metricdata.ScopeMetrics{
@ -761,6 +873,7 @@ func TestTransformations(t *testing.T) {
assert.Equal(t, pbEHDPInt64, ExponentialHistogramDataPoints(otelEHDPInt64))
assert.Equal(t, pbEHDPFloat64, ExponentialHistogramDataPoints(otelEHDPFloat64))
assert.Equal(t, pbEHDPBA, ExponentialHistogramDataPointBuckets(otelEBucketA))
assert.Equal(t, pbDPtsSummary, SummaryDataPoints(otelSummaryDPts))
// Aggregations.
h, err := Histogram(otelHistInt64)
@ -796,6 +909,8 @@ func TestTransformations(t *testing.T) {
assert.ErrorIs(t, err, errUnknownTemporality)
assert.Nil(t, e)
require.Equal(t, &mpb.Metric_Summary{Summary: pbSummary}, Summary(otelSummary))
// Metrics.
m, err := Metrics(otelMetrics)
assert.ErrorIs(t, err, errUnknownTemporality)

View File

@ -98,6 +98,8 @@ func metric(m metricdata.Metrics) (*mpb.Metric, error) {
out.Data, err = ExponentialHistogram(a)
case metricdata.ExponentialHistogram[float64]:
out.Data, err = ExponentialHistogram(a)
case metricdata.Summary:
out.Data = Summary(a)
default:
return out, fmt.Errorf("%w: %T", errUnknownAggregation, a)
}
@ -307,3 +309,44 @@ func Exemplars[N int64 | float64](exemplars []metricdata.Exemplar[N]) []*mpb.Exe
}
return out
}
// Summary returns an OTLP Metric_Summary generated from s.
func Summary(s metricdata.Summary) *mpb.Metric_Summary {
return &mpb.Metric_Summary{
Summary: &mpb.Summary{
DataPoints: SummaryDataPoints(s.DataPoints),
},
}
}
// SummaryDataPoints returns a slice of OTLP SummaryDataPoint generated from
// dPts.
func SummaryDataPoints(dPts []metricdata.SummaryDataPoint) []*mpb.SummaryDataPoint {
out := make([]*mpb.SummaryDataPoint, 0, len(dPts))
for _, dPt := range dPts {
sdp := &mpb.SummaryDataPoint{
Attributes: AttrIter(dPt.Attributes.Iter()),
StartTimeUnixNano: timeUnixNano(dPt.StartTime),
TimeUnixNano: timeUnixNano(dPt.Time),
Count: dPt.Count,
Sum: dPt.Sum,
QuantileValues: QuantileValues(dPt.QuantileValues),
}
out = append(out, sdp)
}
return out
}
// QuantileValues returns a slice of OTLP SummaryDataPoint_ValueAtQuantile
// generated from quantiles.
func QuantileValues(quantiles []metricdata.QuantileValue) []*mpb.SummaryDataPoint_ValueAtQuantile {
out := make([]*mpb.SummaryDataPoint_ValueAtQuantile, 0, len(quantiles))
for _, q := range quantiles {
quantile := &mpb.SummaryDataPoint_ValueAtQuantile{
Quantile: q.Quantile,
Value: q.Value,
}
out = append(out, quantile)
}
return out
}

View File

@ -432,6 +432,83 @@ var (
DataPoints: pbEHDPFloat64,
}
quantileValuesA = []metricdata.QuantileValue{
{
Quantile: 0.0,
Value: 0.1,
},
{
Quantile: 0.5,
Value: 1.0,
},
{
Quantile: 1.0,
Value: 10.4,
},
}
quantileValuesB = []metricdata.QuantileValue{
{
Quantile: 0.0,
Value: 0.5,
},
{
Quantile: 0.5,
Value: 3.1,
},
{
Quantile: 1.0,
Value: 8.3,
},
}
pbQuantileValuesA = []*mpb.SummaryDataPoint_ValueAtQuantile{
{
Quantile: 0.0,
Value: 0.1,
},
{
Quantile: 0.5,
Value: 1.0,
},
{
Quantile: 1.0,
Value: 10.4,
},
}
pbQuantileValuesB = []*mpb.SummaryDataPoint_ValueAtQuantile{
{
Quantile: 0.0,
Value: 0.5,
},
{
Quantile: 0.5,
Value: 3.1,
},
{
Quantile: 1.0,
Value: 8.3,
},
}
otelSummaryDPts = []metricdata.SummaryDataPoint{
{
Attributes: alice,
StartTime: start,
Time: end,
Count: 20,
Sum: sumA,
QuantileValues: quantileValuesA,
},
{
Attributes: bob,
StartTime: start,
Time: end,
Count: 26,
Sum: sumB,
QuantileValues: quantileValuesB,
},
}
otelDPtsInt64 = []metricdata.DataPoint[int64]{
{
Attributes: alice,
@ -498,6 +575,25 @@ var (
},
}
pbDPtsSummary = []*mpb.SummaryDataPoint{
{
Attributes: []*cpb.KeyValue{pbAlice},
StartTimeUnixNano: uint64(start.UnixNano()),
TimeUnixNano: uint64(end.UnixNano()),
Count: 20,
Sum: sumA,
QuantileValues: pbQuantileValuesA,
},
{
Attributes: []*cpb.KeyValue{pbBob},
StartTimeUnixNano: uint64(start.UnixNano()),
TimeUnixNano: uint64(end.UnixNano()),
Count: 26,
Sum: sumB,
QuantileValues: pbQuantileValuesB,
},
}
otelSumInt64 = metricdata.Sum[int64]{
Temporality: metricdata.CumulativeTemporality,
IsMonotonic: true,
@ -551,6 +647,10 @@ var (
},
}}
pbSummary = &mpb.Summary{DataPoints: pbDPtsSummary}
otelSummary = metricdata.Summary{DataPoints: otelSummaryDPts}
unknownAgg unknownAggT
otelMetrics = []metricdata.Metrics{
{
@ -631,6 +731,12 @@ var (
Unit: "1",
Data: otelGaugeZeroStartTime,
},
{
Name: "summary",
Description: "Summary metric",
Unit: "1",
Data: otelSummary,
},
}
pbMetrics = []*mpb.Metric{
@ -688,6 +794,12 @@ var (
Unit: "1",
Data: &mpb.Metric_Gauge{Gauge: pbGaugeZeroStartTime},
},
{
Name: "summary",
Description: "Summary metric",
Unit: "1",
Data: &mpb.Metric_Summary{Summary: pbSummary},
},
}
otelScopeMetrics = []metricdata.ScopeMetrics{
@ -761,6 +873,7 @@ func TestTransformations(t *testing.T) {
assert.Equal(t, pbEHDPInt64, ExponentialHistogramDataPoints(otelEHDPInt64))
assert.Equal(t, pbEHDPFloat64, ExponentialHistogramDataPoints(otelEHDPFloat64))
assert.Equal(t, pbEHDPBA, ExponentialHistogramDataPointBuckets(otelEBucketA))
assert.Equal(t, pbDPtsSummary, SummaryDataPoints(otelSummaryDPts))
// Aggregations.
h, err := Histogram(otelHistInt64)
@ -796,6 +909,8 @@ func TestTransformations(t *testing.T) {
assert.ErrorIs(t, err, errUnknownTemporality)
assert.Nil(t, e)
require.Equal(t, &mpb.Metric_Summary{Summary: pbSummary}, Summary(otelSummary))
// Metrics.
m, err := Metrics(otelMetrics)
assert.ErrorIs(t, err, errUnknownTemporality)

View File

@ -98,6 +98,8 @@ func metric(m metricdata.Metrics) (*mpb.Metric, error) {
out.Data, err = ExponentialHistogram(a)
case metricdata.ExponentialHistogram[float64]:
out.Data, err = ExponentialHistogram(a)
case metricdata.Summary:
out.Data = Summary(a)
default:
return out, fmt.Errorf("%w: %T", errUnknownAggregation, a)
}
@ -307,3 +309,44 @@ func Exemplars[N int64 | float64](exemplars []metricdata.Exemplar[N]) []*mpb.Exe
}
return out
}
// Summary returns an OTLP Metric_Summary generated from s.
func Summary(s metricdata.Summary) *mpb.Metric_Summary {
return &mpb.Metric_Summary{
Summary: &mpb.Summary{
DataPoints: SummaryDataPoints(s.DataPoints),
},
}
}
// SummaryDataPoints returns a slice of OTLP SummaryDataPoint generated from
// dPts.
func SummaryDataPoints(dPts []metricdata.SummaryDataPoint) []*mpb.SummaryDataPoint {
out := make([]*mpb.SummaryDataPoint, 0, len(dPts))
for _, dPt := range dPts {
sdp := &mpb.SummaryDataPoint{
Attributes: AttrIter(dPt.Attributes.Iter()),
StartTimeUnixNano: timeUnixNano(dPt.StartTime),
TimeUnixNano: timeUnixNano(dPt.Time),
Count: dPt.Count,
Sum: dPt.Sum,
QuantileValues: QuantileValues(dPt.QuantileValues),
}
out = append(out, sdp)
}
return out
}
// QuantileValues returns a slice of OTLP SummaryDataPoint_ValueAtQuantile
// generated from quantiles.
func QuantileValues(quantiles []metricdata.QuantileValue) []*mpb.SummaryDataPoint_ValueAtQuantile {
out := make([]*mpb.SummaryDataPoint_ValueAtQuantile, 0, len(quantiles))
for _, q := range quantiles {
quantile := &mpb.SummaryDataPoint_ValueAtQuantile{
Quantile: q.Quantile,
Value: q.Value,
}
out = append(out, quantile)
}
return out
}

View File

@ -432,6 +432,83 @@ var (
DataPoints: pbEHDPFloat64,
}
quantileValuesA = []metricdata.QuantileValue{
{
Quantile: 0.0,
Value: 0.1,
},
{
Quantile: 0.5,
Value: 1.0,
},
{
Quantile: 1.0,
Value: 10.4,
},
}
quantileValuesB = []metricdata.QuantileValue{
{
Quantile: 0.0,
Value: 0.5,
},
{
Quantile: 0.5,
Value: 3.1,
},
{
Quantile: 1.0,
Value: 8.3,
},
}
pbQuantileValuesA = []*mpb.SummaryDataPoint_ValueAtQuantile{
{
Quantile: 0.0,
Value: 0.1,
},
{
Quantile: 0.5,
Value: 1.0,
},
{
Quantile: 1.0,
Value: 10.4,
},
}
pbQuantileValuesB = []*mpb.SummaryDataPoint_ValueAtQuantile{
{
Quantile: 0.0,
Value: 0.5,
},
{
Quantile: 0.5,
Value: 3.1,
},
{
Quantile: 1.0,
Value: 8.3,
},
}
otelSummaryDPts = []metricdata.SummaryDataPoint{
{
Attributes: alice,
StartTime: start,
Time: end,
Count: 20,
Sum: sumA,
QuantileValues: quantileValuesA,
},
{
Attributes: bob,
StartTime: start,
Time: end,
Count: 26,
Sum: sumB,
QuantileValues: quantileValuesB,
},
}
otelDPtsInt64 = []metricdata.DataPoint[int64]{
{
Attributes: alice,
@ -498,6 +575,25 @@ var (
},
}
pbDPtsSummary = []*mpb.SummaryDataPoint{
{
Attributes: []*cpb.KeyValue{pbAlice},
StartTimeUnixNano: uint64(start.UnixNano()),
TimeUnixNano: uint64(end.UnixNano()),
Count: 20,
Sum: sumA,
QuantileValues: pbQuantileValuesA,
},
{
Attributes: []*cpb.KeyValue{pbBob},
StartTimeUnixNano: uint64(start.UnixNano()),
TimeUnixNano: uint64(end.UnixNano()),
Count: 26,
Sum: sumB,
QuantileValues: pbQuantileValuesB,
},
}
otelSumInt64 = metricdata.Sum[int64]{
Temporality: metricdata.CumulativeTemporality,
IsMonotonic: true,
@ -551,6 +647,10 @@ var (
},
}}
pbSummary = &mpb.Summary{DataPoints: pbDPtsSummary}
otelSummary = metricdata.Summary{DataPoints: otelSummaryDPts}
unknownAgg unknownAggT
otelMetrics = []metricdata.Metrics{
{
@ -631,6 +731,12 @@ var (
Unit: "1",
Data: otelGaugeZeroStartTime,
},
{
Name: "summary",
Description: "Summary metric",
Unit: "1",
Data: otelSummary,
},
}
pbMetrics = []*mpb.Metric{
@ -688,6 +794,12 @@ var (
Unit: "1",
Data: &mpb.Metric_Gauge{Gauge: pbGaugeZeroStartTime},
},
{
Name: "summary",
Description: "Summary metric",
Unit: "1",
Data: &mpb.Metric_Summary{Summary: pbSummary},
},
}
otelScopeMetrics = []metricdata.ScopeMetrics{
@ -761,6 +873,7 @@ func TestTransformations(t *testing.T) {
assert.Equal(t, pbEHDPInt64, ExponentialHistogramDataPoints(otelEHDPInt64))
assert.Equal(t, pbEHDPFloat64, ExponentialHistogramDataPoints(otelEHDPFloat64))
assert.Equal(t, pbEHDPBA, ExponentialHistogramDataPointBuckets(otelEBucketA))
assert.Equal(t, pbDPtsSummary, SummaryDataPoints(otelSummaryDPts))
// Aggregations.
h, err := Histogram(otelHistInt64)
@ -796,6 +909,8 @@ func TestTransformations(t *testing.T) {
assert.ErrorIs(t, err, errUnknownTemporality)
assert.Nil(t, e)
require.Equal(t, &mpb.Metric_Summary{Summary: pbSummary}, Summary(otelSummary))
// Metrics.
m, err := Metrics(otelMetrics)
assert.ErrorIs(t, err, errUnknownTemporality)