Skip to content

Commit 0a79aa8

Browse files
graphaellifchikwekweTylerHelmutha-thaleratoulme
authored
[processor/transform] Convert between sum and gauge in metric context (#29091)
**Description:** Allow running OTTL `convert_sum_to_gauge` and `convert_gauge_to_sum` in metric context instead of datapoint when `processor.transform.ConvertBetweenSumAndGaugeMetricContext` is enabled closes #20773 <!-- **Testing:** <Describe what testing was performed and which tests were added.> **Documentation:** <Describe the documentation added.> --> This is the result of an effort at contribfest at Kubecon NA '23. --------- Signed-off-by: Alex Boten <[email protected]> Co-authored-by: Faith Chikwekwe <[email protected]> Co-authored-by: Tyler Helmuth <[email protected]> Co-authored-by: Andreas Thaler <[email protected]> Co-authored-by: Antoine Toulme <[email protected]> Co-authored-by: Etienne Pelletier <[email protected]> Co-authored-by: bryan-aguilar <[email protected]> Co-authored-by: Rajkumar Rangaraj <[email protected]> Co-authored-by: Curtis Robert <[email protected]> Co-authored-by: Alex Boten <[email protected]> Co-authored-by: Jacob Marble <[email protected]> Co-authored-by: Jon <[email protected]> Co-authored-by: Daniel Jaglowski <[email protected]> Co-authored-by: Antoine Toulme <[email protected]>
1 parent 8586383 commit 0a79aa8

12 files changed

+422
-20
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: processor/transform
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Convert between sum and gauge in metric context when alpha feature gate `processor.transform.ConvertBetweenSumAndGaugeMetricContext` enabled
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [20773]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

processor/transformprocessor/go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ module github.com/open-telemetry/opentelemetry-collector-contrib/processor/trans
33
go 1.20
44

55
require (
6+
github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.89.0
67
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.89.0
78
github.com/stretchr/testify v1.8.4
89
go.opentelemetry.io/collector/component v0.89.0
910
go.opentelemetry.io/collector/confmap v0.89.0
1011
go.opentelemetry.io/collector/consumer v0.89.0
12+
go.opentelemetry.io/collector/featuregate v1.0.0-rcv0018
1113
go.opentelemetry.io/collector/pdata v1.0.0-rcv0018
1214
go.opentelemetry.io/collector/processor v0.89.0
1315
go.uber.org/multierr v1.11.0
@@ -37,7 +39,6 @@ require (
3739
go.opencensus.io v0.24.0 // indirect
3840
go.opentelemetry.io/collector v0.89.0 // indirect
3941
go.opentelemetry.io/collector/config/configtelemetry v0.89.0 // indirect
40-
go.opentelemetry.io/collector/featuregate v1.0.0-rcv0018 // indirect
4142
go.opentelemetry.io/otel v1.21.0 // indirect
4243
go.opentelemetry.io/otel/metric v1.21.0 // indirect
4344
go.opentelemetry.io/otel/trace v1.21.0 // indirect
@@ -66,3 +67,5 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil
6667
replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest
6768

6869
replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden => ../../pkg/golden
70+
71+
replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/common => ../../internal/common

processor/transformprocessor/internal/metrics/func_convert_gauge_to_sum.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ import (
1010
"go.opentelemetry.io/collector/pdata/pmetric"
1111

1212
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
13-
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlmetric"
1414
)
1515

1616
type convertGaugeToSumArguments struct {
1717
StringAggTemp string
1818
Monotonic bool
1919
}
2020

21-
func newConvertGaugeToSumFactory() ottl.Factory[ottldatapoint.TransformContext] {
21+
func newConvertGaugeToSumFactory() ottl.Factory[ottlmetric.TransformContext] {
2222
return ottl.NewFactory("convert_gauge_to_sum", &convertGaugeToSumArguments{}, createConvertGaugeToSumFunction)
2323
}
2424

25-
func createConvertGaugeToSumFunction(_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
25+
func createConvertGaugeToSumFunction(_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[ottlmetric.TransformContext], error) {
2626
args, ok := oArgs.(*convertGaugeToSumArguments)
2727

2828
if !ok {
@@ -32,7 +32,7 @@ func createConvertGaugeToSumFunction(_ ottl.FunctionContext, oArgs ottl.Argument
3232
return convertGaugeToSum(args.StringAggTemp, args.Monotonic)
3333
}
3434

35-
func convertGaugeToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
35+
func convertGaugeToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottlmetric.TransformContext], error) {
3636
var aggTemp pmetric.AggregationTemporality
3737
switch stringAggTemp {
3838
case "delta":
@@ -43,7 +43,7 @@ func convertGaugeToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottl
4343
return nil, fmt.Errorf("unknown aggregation temporality: %s", stringAggTemp)
4444
}
4545

46-
return func(_ context.Context, tCtx ottldatapoint.TransformContext) (any, error) {
46+
return func(_ context.Context, tCtx ottlmetric.TransformContext) (any, error) {
4747
metric := tCtx.GetMetric()
4848
if metric.Type() != pmetric.MetricTypeGauge {
4949
return nil, nil
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package metrics // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/metrics"
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"go.opentelemetry.io/collector/pdata/pmetric"
11+
12+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
14+
)
15+
16+
func newConvertDatapointGaugeToSumFactory() ottl.Factory[ottldatapoint.TransformContext] {
17+
return ottl.NewFactory("convert_gauge_to_sum", &convertGaugeToSumArguments{}, createConvertDatapointGaugeToSumFunction)
18+
}
19+
20+
func createConvertDatapointGaugeToSumFunction(_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
21+
// use the same args as in metric context
22+
args, ok := oArgs.(*convertGaugeToSumArguments)
23+
24+
if !ok {
25+
return nil, fmt.Errorf("ConvertGaugeToSumFactory args must be of type *ConvertGaugeToSumArguments")
26+
}
27+
28+
return convertDatapointGaugeToSum(args.StringAggTemp, args.Monotonic)
29+
}
30+
31+
func convertDatapointGaugeToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
32+
var aggTemp pmetric.AggregationTemporality
33+
switch stringAggTemp {
34+
case "delta":
35+
aggTemp = pmetric.AggregationTemporalityDelta
36+
case "cumulative":
37+
aggTemp = pmetric.AggregationTemporalityCumulative
38+
default:
39+
return nil, fmt.Errorf("unknown aggregation temporality: %s", stringAggTemp)
40+
}
41+
42+
return func(_ context.Context, tCtx ottldatapoint.TransformContext) (any, error) {
43+
metric := tCtx.GetMetric()
44+
if metric.Type() != pmetric.MetricTypeGauge {
45+
return nil, nil
46+
}
47+
48+
dps := metric.Gauge().DataPoints()
49+
50+
metric.SetEmptySum().SetAggregationTemporality(aggTemp)
51+
metric.Sum().SetIsMonotonic(monotonic)
52+
53+
// Setting the data type removed all the data points, so we must copy them back to the metric.
54+
dps.CopyTo(metric.Sum().DataPoints())
55+
56+
return nil, nil
57+
}, nil
58+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package metrics
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"go.opentelemetry.io/collector/pdata/pcommon"
11+
"go.opentelemetry.io/collector/pdata/pmetric"
12+
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
14+
)
15+
16+
func Test_convertDatapointGaugeToSum(t *testing.T) {
17+
gaugeInput := pmetric.NewMetric()
18+
19+
dp1 := gaugeInput.SetEmptyGauge().DataPoints().AppendEmpty()
20+
dp1.SetIntValue(10)
21+
22+
dp2 := gaugeInput.Gauge().DataPoints().AppendEmpty()
23+
dp2.SetDoubleValue(14.5)
24+
25+
sumInput := pmetric.NewMetric()
26+
sumInput.SetEmptySum()
27+
28+
histogramInput := pmetric.NewMetric()
29+
histogramInput.SetEmptyHistogram()
30+
31+
expoHistogramInput := pmetric.NewMetric()
32+
expoHistogramInput.SetEmptyHistogram()
33+
34+
summaryInput := pmetric.NewMetric()
35+
summaryInput.SetEmptySummary()
36+
37+
tests := []struct {
38+
name string
39+
stringAggTemp string
40+
monotonic bool
41+
input pmetric.Metric
42+
want func(pmetric.Metric)
43+
}{
44+
{
45+
name: "convert gauge to cumulative sum",
46+
stringAggTemp: "cumulative",
47+
monotonic: false,
48+
input: gaugeInput,
49+
want: func(metric pmetric.Metric) {
50+
gaugeInput.CopyTo(metric)
51+
52+
dps := gaugeInput.Gauge().DataPoints()
53+
54+
metric.SetEmptySum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
55+
metric.Sum().SetIsMonotonic(false)
56+
57+
dps.CopyTo(metric.Sum().DataPoints())
58+
},
59+
},
60+
{
61+
name: "convert gauge to delta sum",
62+
stringAggTemp: "delta",
63+
monotonic: true,
64+
input: gaugeInput,
65+
want: func(metric pmetric.Metric) {
66+
gaugeInput.CopyTo(metric)
67+
68+
dps := gaugeInput.Gauge().DataPoints()
69+
70+
metric.SetEmptySum().SetAggregationTemporality(pmetric.AggregationTemporalityDelta)
71+
metric.Sum().SetIsMonotonic(true)
72+
73+
dps.CopyTo(metric.Sum().DataPoints())
74+
},
75+
},
76+
{
77+
name: "noop for sum",
78+
stringAggTemp: "delta",
79+
monotonic: true,
80+
input: sumInput,
81+
want: func(metric pmetric.Metric) {
82+
sumInput.CopyTo(metric)
83+
},
84+
},
85+
{
86+
name: "noop for histogram",
87+
stringAggTemp: "delta",
88+
monotonic: true,
89+
input: histogramInput,
90+
want: func(metric pmetric.Metric) {
91+
histogramInput.CopyTo(metric)
92+
},
93+
},
94+
{
95+
name: "noop for exponential histogram",
96+
stringAggTemp: "delta",
97+
monotonic: true,
98+
input: expoHistogramInput,
99+
want: func(metric pmetric.Metric) {
100+
expoHistogramInput.CopyTo(metric)
101+
},
102+
},
103+
{
104+
name: "noop for summary",
105+
stringAggTemp: "delta",
106+
monotonic: true,
107+
input: summaryInput,
108+
want: func(metric pmetric.Metric) {
109+
summaryInput.CopyTo(metric)
110+
},
111+
},
112+
}
113+
for _, tt := range tests {
114+
t.Run(tt.name, func(t *testing.T) {
115+
metric := pmetric.NewMetric()
116+
tt.input.CopyTo(metric)
117+
118+
ctx := ottldatapoint.NewTransformContext(pmetric.NewNumberDataPoint(), metric, pmetric.NewMetricSlice(), pcommon.NewInstrumentationScope(), pcommon.NewResource())
119+
120+
exprFunc, _ := convertDatapointGaugeToSum(tt.stringAggTemp, tt.monotonic)
121+
122+
_, err := exprFunc(nil, ctx)
123+
assert.Nil(t, err)
124+
125+
expected := pmetric.NewMetric()
126+
tt.want(expected)
127+
128+
assert.Equal(t, expected, metric)
129+
})
130+
}
131+
}
132+
133+
func Test_convertDatapointGaugeToSum_validation(t *testing.T) {
134+
tests := []struct {
135+
name string
136+
stringAggTemp string
137+
}{
138+
{
139+
name: "invalid aggregation temporality",
140+
stringAggTemp: "not a real aggregation temporality",
141+
},
142+
}
143+
for _, tt := range tests {
144+
t.Run(tt.name, func(t *testing.T) {
145+
_, err := convertDatapointGaugeToSum(tt.stringAggTemp, true)
146+
assert.Error(t, err, "unknown aggregation temporality: not a real aggregation temporality")
147+
})
148+
}
149+
}

processor/transformprocessor/internal/metrics/func_convert_gauge_to_sum_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"go.opentelemetry.io/collector/pdata/pcommon"
1111
"go.opentelemetry.io/collector/pdata/pmetric"
1212

13-
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlmetric"
1414
)
1515

1616
func Test_convertGaugeToSum(t *testing.T) {
@@ -115,7 +115,7 @@ func Test_convertGaugeToSum(t *testing.T) {
115115
metric := pmetric.NewMetric()
116116
tt.input.CopyTo(metric)
117117

118-
ctx := ottldatapoint.NewTransformContext(pmetric.NewNumberDataPoint(), metric, pmetric.NewMetricSlice(), pcommon.NewInstrumentationScope(), pcommon.NewResource())
118+
ctx := ottlmetric.NewTransformContext(metric, pmetric.NewMetricSlice(), pcommon.NewInstrumentationScope(), pcommon.NewResource())
119119

120120
exprFunc, _ := convertGaugeToSum(tt.stringAggTemp, tt.monotonic)
121121

processor/transformprocessor/internal/metrics/func_convert_sum_to_gauge.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ import (
99
"go.opentelemetry.io/collector/pdata/pmetric"
1010

1111
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
12-
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
12+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlmetric"
1313
)
1414

15-
func newConvertSumToGaugeFactory() ottl.Factory[ottldatapoint.TransformContext] {
15+
func newConvertSumToGaugeFactory() ottl.Factory[ottlmetric.TransformContext] {
1616
return ottl.NewFactory("convert_sum_to_gauge", nil, createConvertSumToGaugeFunction)
1717
}
1818

19-
func createConvertSumToGaugeFunction(_ ottl.FunctionContext, _ ottl.Arguments) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
19+
func createConvertSumToGaugeFunction(_ ottl.FunctionContext, _ ottl.Arguments) (ottl.ExprFunc[ottlmetric.TransformContext], error) {
2020
return convertSumToGauge()
2121
}
2222

23-
func convertSumToGauge() (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
24-
return func(_ context.Context, tCtx ottldatapoint.TransformContext) (any, error) {
23+
func convertSumToGauge() (ottl.ExprFunc[ottlmetric.TransformContext], error) {
24+
return func(_ context.Context, tCtx ottlmetric.TransformContext) (any, error) {
2525
metric := tCtx.GetMetric()
2626
if metric.Type() != pmetric.MetricTypeSum {
2727
return nil, nil
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package metrics // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/metrics"
5+
6+
import (
7+
"context"
8+
9+
"go.opentelemetry.io/collector/pdata/pmetric"
10+
11+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
12+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
13+
)
14+
15+
func newConvertDatapointSumToGaugeFactory() ottl.Factory[ottldatapoint.TransformContext] {
16+
return ottl.NewFactory("convert_sum_to_gauge", nil, createDatapointConvertSumToGaugeFunction)
17+
}
18+
19+
func createDatapointConvertSumToGaugeFunction(_ ottl.FunctionContext, _ ottl.Arguments) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
20+
return convertDatapointSumToGauge()
21+
}
22+
23+
func convertDatapointSumToGauge() (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
24+
return func(_ context.Context, tCtx ottldatapoint.TransformContext) (any, error) {
25+
metric := tCtx.GetMetric()
26+
if metric.Type() != pmetric.MetricTypeSum {
27+
return nil, nil
28+
}
29+
30+
dps := metric.Sum().DataPoints()
31+
32+
// Setting the data type removed all the data points, so we must copy them back to the metric.
33+
dps.CopyTo(metric.SetEmptyGauge().DataPoints())
34+
35+
return nil, nil
36+
}, nil
37+
}

0 commit comments

Comments
 (0)