Skip to content

Commit 9a2ea1c

Browse files
odubajDTevan-bradleyedmocosta
authored
[processor/transform] Introduce optional metric name suffix setup for convert summary and extract histogram functions (#37238)
Co-authored-by: Evan Bradley <[email protected]> Co-authored-by: edmocosta <[email protected]>
1 parent 66bce50 commit 9a2ea1c

10 files changed

+185
-36
lines changed

.chloggen/transform-name-suffix.yaml

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: "Introduce optional metric name suffix setup for metric conversion functions"
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: [33850]
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: "The affected functions are: convert_summary_count_val_to_sum(), convert_summary_sum_val_to_sum(), extract_count_metric(), extract_sum_metric()"
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: []

processor/transformprocessor/README.md

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ In addition to the common OTTL functions, the processor defines its own function
254254
**Metrics only functions**
255255
- [convert_sum_to_gauge](#convert_sum_to_gauge)
256256
- [convert_gauge_to_sum](#convert_gauge_to_sum)
257+
- [extract_count_metric](#extract_count_metric)
258+
- [extract_sum_metric](#extract_sum_metric)
257259
- [convert_summary_count_val_to_sum](#convert_summary_count_val_to_sum)
258260
- [convert_summary_sum_val_to_sum](#convert_summary_sum_val_to_sum)
259261
- [copy_metric](#copy_metric)
@@ -296,13 +298,15 @@ Examples:
296298
> [!NOTE]
297299
> This function supports Histograms, ExponentialHistograms and Summaries.
298300

299-
`extract_count_metric(is_monotonic)`
301+
`extract_count_metric(is_monotonic, Optional[suffix])`
300302

301303
The `extract_count_metric` function creates a new Sum metric from a Histogram, ExponentialHistogram or Summary's count value. A metric will only be created if there is at least one data point.
302304

303305
`is_monotonic` is a boolean representing the monotonicity of the new metric.
306+
`suffix` is an optional string that defines the suffix for the metric name. By default, it is set to `_count`.
307+
For backward compatibility, this default does not follow the [semantic naming conventions](https://opentelemetry.io/docs/specs/semconv/general/naming/#general-naming-considerations) and should ideally be `.count` instead. This default is expected to change in a future release.
304308

305-
The name for the new metric will be `<original metric name>_count`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, `description`, and `aggregation_temporality`. As metrics of type Summary don't have an `aggregation_temporality` field, this field will be set to `AGGREGATION_TEMPORALITY_CUMULATIVE` for those metrics.
309+
The name for the new metric will be `<original metric name><suffix>`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, `description`, and `aggregation_temporality`. As metrics of type Summary don't have an `aggregation_temporality` field, this field will be set to `AGGREGATION_TEMPORALITY_CUMULATIVE` for those metrics.
306310

307311
The new metric that is created will be passed to all subsequent statements in the metrics statements list.
308312

@@ -311,22 +315,24 @@ The new metric that is created will be passed to all subsequent statements in th
311315

312316
Examples:
313317

314-
- `extract_count_metric(true)`
318+
- `extract_count_metric(true, ".count")`
315319

316-
- `extract_count_metric(false)`
320+
- `extract_count_metric(false, ".count")`
317321

318322
### extract_sum_metric
319323

320324
> [!NOTE]
321325
> This function supports Histograms, ExponentialHistograms and Summaries.
322326

323-
`extract_sum_metric(is_monotonic)`
327+
`extract_sum_metric(is_monotonic, Optional[suffix])`
324328

325329
The `extract_sum_metric` function creates a new Sum metric from a Histogram, ExponentialHistogram or Summary's sum value. If the sum value of a Histogram or ExponentialHistogram data point is missing, no data point is added to the output metric. A metric will only be created if there is at least one data point.
326330

327331
`is_monotonic` is a boolean representing the monotonicity of the new metric.
332+
`suffix` is an optional string that defines the suffix for the metric name. By default, it is set to `_sum`.
333+
For backward compatibility, this default does not follow the [semantic naming conventions](https://opentelemetry.io/docs/specs/semconv/general/naming/#general-naming-considerations) and should ideally be `.sum` instead. This default is expected to change in a future release.
328334

329-
The name for the new metric will be `<original metric name>_sum`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, `description`, and `aggregation_temporality`. As metrics of type Summary don't have an `aggregation_temporality` field, this field will be set to `AGGREGATION_TEMPORALITY_CUMULATIVE` for those metrics.
335+
The name for the new metric will be `<original metric name><suffix>`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, `description`, and `aggregation_temporality`. As metrics of type Summary don't have an `aggregation_temporality` field, this field will be set to `AGGREGATION_TEMPORALITY_CUMULATIVE` for those metrics.
330336

331337
The new metric that is created will be passed to all subsequent statements in the metrics statements list.
332338

@@ -335,47 +341,50 @@ The new metric that is created will be passed to all subsequent statements in th
335341

336342
Examples:
337343

338-
- `extract_sum_metric(true)`
344+
- `extract_sum_metric(true, ".sum")`
339345

340-
- `extract_sum_metric(false)`
346+
- `extract_sum_metric(false, ".sum")`
341347

342348
### convert_summary_count_val_to_sum
343349

344-
`convert_summary_count_val_to_sum(aggregation_temporality, is_monotonic)`
350+
`convert_summary_count_val_to_sum(aggregation_temporality, is_monotonic, Optional[suffix])`
345351

346352
The `convert_summary_count_val_to_sum` function creates a new Sum metric from a Summary's count value.
347353

348354
`aggregation_temporality` is a string (`"cumulative"` or `"delta"`) representing the desired aggregation temporality of the new metric. `is_monotonic` is a boolean representing the monotonicity of the new metric.
349355

350-
The name for the new metric will be `<summary metric name>_count`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, and `description`. The new metric that is created will be passed to all functions in the metrics statements list. Function conditions will apply.
356+
`suffix` is an optional string that defines the suffix for the metric name. By default, it is set to `_count`.
357+
For backward compatibility, this default does not follow the [semantic naming conventions](https://opentelemetry.io/docs/specs/semconv/general/naming/#general-naming-considerations) and should ideally be `.count` instead. This default is expected to change in a future release.
358+
359+
The name for the new metric will be `<summary metric name><suffix>`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, and `description`. The new metric that is created will be passed to all functions in the metrics statements list. Function conditions will apply.
351360

352361
**NOTE:** This function may cause a metric to break semantics for [Sum metrics](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#sums). Use at your own risk.
353362

354363
Examples:
355364

356-
- `convert_summary_count_val_to_sum("delta", true)`
357-
365+
- `convert_summary_count_val_to_sum("delta", true, ".count")`
358366

359-
- `convert_summary_count_val_to_sum("cumulative", false)`
367+
- `convert_summary_count_val_to_sum("cumulative", false, ".count")`
360368

361369
### convert_summary_sum_val_to_sum
362370

363-
`convert_summary_sum_val_to_sum(aggregation_temporality, is_monotonic)`
371+
`convert_summary_sum_val_to_sum(aggregation_temporality, is_monotonic, Optional[suffix])`
364372

365373
The `convert_summary_sum_val_to_sum` function creates a new Sum metric from a Summary's sum value.
366374

367375
`aggregation_temporality` is a string (`"cumulative"` or `"delta"`) representing the desired aggregation temporality of the new metric. `is_monotonic` is a boolean representing the monotonicity of the new metric.
376+
`suffix` is an optional string that defines the suffix for the metric name. By default, it is set to `_sum`.
377+
For backward compatibility, this default does not follow the [semantic naming conventions](https://opentelemetry.io/docs/specs/semconv/general/naming/#general-naming-considerations) and should ideally be `.sum` instead. This default is expected to change in a future release.
368378

369-
The name for the new metric will be `<summary metric name>_sum`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, and `description`. The new metric that is created will be passed to all functions in the metrics statements list. Function conditions will apply.
379+
The name for the new metric will be `<summary metric name><suffix>`. The fields that are copied are: `timestamp`, `starttimestamp`, `attributes`, and `description`. The new metric that is created will be passed to all functions in the metrics statements list. Function conditions will apply.
370380

371381
**NOTE:** This function may cause a metric to break semantics for [Sum metrics](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#sums). Use at your own risk.
372382

373383
Examples:
374384

375-
- `convert_summary_sum_val_to_sum("delta", true)`
376-
385+
- `convert_summary_sum_val_to_sum("delta", true, ".sum")`
377386

378-
- `convert_summary_sum_val_to_sum("cumulative", false)`
387+
- `convert_summary_sum_val_to_sum("cumulative", false, ".sum")`
379388

380389
### copy_metric
381390

processor/transformprocessor/internal/metrics/func_convert_summary_count_val_to_sum.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
type convertSummaryCountValToSumArguments struct {
1818
StringAggTemp string
1919
Monotonic bool
20+
Suffix ottl.Optional[string]
2021
}
2122

2223
func newConvertSummaryCountValToSumFactory() ottl.Factory[ottldatapoint.TransformContext] {
@@ -30,10 +31,14 @@ func createConvertSummaryCountValToSumFunction(_ ottl.FunctionContext, oArgs ott
3031
return nil, errors.New("convertSummaryCountValToSumFactory args must be of type *convertSummaryCountValToSumArguments")
3132
}
3233

33-
return convertSummaryCountValToSum(args.StringAggTemp, args.Monotonic)
34+
return convertSummaryCountValToSum(args.StringAggTemp, args.Monotonic, args.Suffix)
3435
}
3536

36-
func convertSummaryCountValToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
37+
func convertSummaryCountValToSum(stringAggTemp string, monotonic bool, suffix ottl.Optional[string]) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
38+
metricNameSuffix := "_count"
39+
if !suffix.IsEmpty() {
40+
metricNameSuffix = suffix.Get()
41+
}
3742
var aggTemp pmetric.AggregationTemporality
3843
switch stringAggTemp {
3944
case "delta":
@@ -51,7 +56,7 @@ func convertSummaryCountValToSum(stringAggTemp string, monotonic bool) (ottl.Exp
5156

5257
sumMetric := tCtx.GetMetrics().AppendEmpty()
5358
sumMetric.SetDescription(metric.Description())
54-
sumMetric.SetName(metric.Name() + "_count")
59+
sumMetric.SetName(metric.Name() + metricNameSuffix)
5560
sumMetric.SetUnit(metric.Unit())
5661
sumMetric.SetEmptySum().SetAggregationTemporality(aggTemp)
5762
sumMetric.Sum().SetIsMonotonic(monotonic)

processor/transformprocessor/internal/metrics/func_convert_summary_count_val_to_sum_test.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +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"
1314
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
1415
)
1516

@@ -78,6 +79,28 @@ func Test_ConvertSummaryCountValToSum(t *testing.T) {
7879
attrs.CopyTo(dp.Attributes())
7980
},
8081
},
82+
{
83+
name: "convert_summary_count_val_to_sum custom suffix",
84+
input: getTestSummaryMetric(),
85+
temporality: "cumulative",
86+
monotonicity: false,
87+
suffix: ottl.NewTestingOptional("_custom_suf"),
88+
want: func(metrics pmetric.MetricSlice) {
89+
summaryMetric := getTestSummaryMetric()
90+
summaryMetric.CopyTo(metrics.AppendEmpty())
91+
sumMetric := metrics.AppendEmpty()
92+
sumMetric.SetEmptySum()
93+
sumMetric.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
94+
sumMetric.Sum().SetIsMonotonic(false)
95+
96+
sumMetric.SetName("summary_metric_custom_suf")
97+
dp := sumMetric.Sum().DataPoints().AppendEmpty()
98+
dp.SetIntValue(100)
99+
100+
attrs := getTestAttributes()
101+
attrs.CopyTo(dp.Attributes())
102+
},
103+
},
81104
{
82105
name: "convert_summary_count_val_to_sum (no op)",
83106
input: getTestGaugeMetric(),
@@ -94,7 +117,7 @@ func Test_ConvertSummaryCountValToSum(t *testing.T) {
94117
actualMetrics := pmetric.NewMetricSlice()
95118
tt.input.CopyTo(actualMetrics.AppendEmpty())
96119

97-
evaluate, err := convertSummaryCountValToSum(tt.temporality, tt.monotonicity)
120+
evaluate, err := convertSummaryCountValToSum(tt.temporality, tt.monotonicity, tt.suffix)
98121
assert.NoError(t, err)
99122

100123
_, err = evaluate(nil, ottldatapoint.NewTransformContext(pmetric.NewNumberDataPoint(), tt.input, actualMetrics, pcommon.NewInstrumentationScope(), pcommon.NewResource(), pmetric.NewScopeMetrics(), pmetric.NewResourceMetrics()))
@@ -119,7 +142,7 @@ func Test_ConvertSummaryCountValToSum_validation(t *testing.T) {
119142
}
120143
for _, tt := range tests {
121144
t.Run(tt.name, func(t *testing.T) {
122-
_, err := convertSummaryCountValToSum(tt.stringAggTemp, true)
145+
_, err := convertSummaryCountValToSum(tt.stringAggTemp, true, ottl.Optional[string]{})
123146
assert.Error(t, err, "unknown aggregation temporality: not a real aggregation temporality")
124147
})
125148
}

processor/transformprocessor/internal/metrics/func_convert_summary_sum_val_to_sum.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
type convertSummarySumValToSumArguments struct {
1818
StringAggTemp string
1919
Monotonic bool
20+
Suffix ottl.Optional[string]
2021
}
2122

2223
func newConvertSummarySumValToSumFactory() ottl.Factory[ottldatapoint.TransformContext] {
@@ -30,10 +31,14 @@ func createConvertSummarySumValToSumFunction(_ ottl.FunctionContext, oArgs ottl.
3031
return nil, errors.New("convertSummarySumValToSumFactory args must be of type *convertSummarySumValToSumArguments")
3132
}
3233

33-
return convertSummarySumValToSum(args.StringAggTemp, args.Monotonic)
34+
return convertSummarySumValToSum(args.StringAggTemp, args.Monotonic, args.Suffix)
3435
}
3536

36-
func convertSummarySumValToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
37+
func convertSummarySumValToSum(stringAggTemp string, monotonic bool, suffix ottl.Optional[string]) (ottl.ExprFunc[ottldatapoint.TransformContext], error) {
38+
metricNameSuffix := "_sum"
39+
if !suffix.IsEmpty() {
40+
metricNameSuffix = suffix.Get()
41+
}
3742
var aggTemp pmetric.AggregationTemporality
3843
switch stringAggTemp {
3944
case "delta":
@@ -51,7 +56,7 @@ func convertSummarySumValToSum(stringAggTemp string, monotonic bool) (ottl.ExprF
5156

5257
sumMetric := tCtx.GetMetrics().AppendEmpty()
5358
sumMetric.SetDescription(metric.Description())
54-
sumMetric.SetName(metric.Name() + "_sum")
59+
sumMetric.SetName(metric.Name() + metricNameSuffix)
5560
sumMetric.SetUnit(metric.Unit())
5661
sumMetric.SetEmptySum().SetAggregationTemporality(aggTemp)
5762
sumMetric.Sum().SetIsMonotonic(monotonic)

processor/transformprocessor/internal/metrics/func_convert_summary_sum_val_to_sum_test.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +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"
1314
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoint"
1415
)
1516

@@ -18,6 +19,7 @@ type summaryTestCase struct {
1819
input pmetric.Metric
1920
temporality string
2021
monotonicity bool
22+
suffix ottl.Optional[string]
2123
want func(pmetric.MetricSlice)
2224
}
2325

@@ -86,6 +88,28 @@ func Test_ConvertSummarySumValToSum(t *testing.T) {
8688
attrs.CopyTo(dp.Attributes())
8789
},
8890
},
91+
{
92+
name: "convert_summary_sum_val_to_sum custom suffix",
93+
input: getTestSummaryMetric(),
94+
temporality: "delta",
95+
monotonicity: false,
96+
suffix: ottl.NewTestingOptional("_custom_suf"),
97+
want: func(metrics pmetric.MetricSlice) {
98+
summaryMetric := getTestSummaryMetric()
99+
summaryMetric.CopyTo(metrics.AppendEmpty())
100+
sumMetric := metrics.AppendEmpty()
101+
sumMetric.SetEmptySum()
102+
sumMetric.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityDelta)
103+
sumMetric.Sum().SetIsMonotonic(false)
104+
105+
sumMetric.SetName("summary_metric_custom_suf")
106+
dp := sumMetric.Sum().DataPoints().AppendEmpty()
107+
dp.SetDoubleValue(12.34)
108+
109+
attrs := getTestAttributes()
110+
attrs.CopyTo(dp.Attributes())
111+
},
112+
},
89113
{
90114
name: "convert_summary_sum_val_to_sum (no op)",
91115
input: getTestGaugeMetric(),
@@ -102,7 +126,7 @@ func Test_ConvertSummarySumValToSum(t *testing.T) {
102126
actualMetrics := pmetric.NewMetricSlice()
103127
tt.input.CopyTo(actualMetrics.AppendEmpty())
104128

105-
evaluate, err := convertSummarySumValToSum(tt.temporality, tt.monotonicity)
129+
evaluate, err := convertSummarySumValToSum(tt.temporality, tt.monotonicity, tt.suffix)
106130
assert.NoError(t, err)
107131

108132
_, err = evaluate(nil, ottldatapoint.NewTransformContext(pmetric.NewNumberDataPoint(), tt.input, actualMetrics, pcommon.NewInstrumentationScope(), pcommon.NewResource(), pmetric.NewScopeMetrics(), pmetric.NewResourceMetrics()))
@@ -127,7 +151,7 @@ func Test_ConvertSummarySumValToSum_validation(t *testing.T) {
127151
}
128152
for _, tt := range tests {
129153
t.Run(tt.name, func(t *testing.T) {
130-
_, err := convertSummarySumValToSum(tt.stringAggTemp, true)
154+
_, err := convertSummarySumValToSum(tt.stringAggTemp, true, ottl.Optional[string]{})
131155
assert.Error(t, err, "unknown aggregation temporality: not a real aggregation temporality")
132156
})
133157
}

processor/transformprocessor/internal/metrics/func_extract_count_metric.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const sumCountName = "extract_count_metric"
1717

1818
type extractCountMetricArguments struct {
1919
Monotonic bool
20+
Suffix ottl.Optional[string]
2021
}
2122

2223
func newExtractCountMetricFactory() ottl.Factory[ottlmetric.TransformContext] {
@@ -30,10 +31,14 @@ func createExtractCountMetricFunction(_ ottl.FunctionContext, oArgs ottl.Argumen
3031
return nil, errors.New("extractCountMetricFactory args must be of type *extractCountMetricArguments")
3132
}
3233

33-
return extractCountMetric(args.Monotonic)
34+
return extractCountMetric(args.Monotonic, args.Suffix)
3435
}
3536

36-
func extractCountMetric(monotonic bool) (ottl.ExprFunc[ottlmetric.TransformContext], error) {
37+
func extractCountMetric(monotonic bool, suffix ottl.Optional[string]) (ottl.ExprFunc[ottlmetric.TransformContext], error) {
38+
metricNameSuffix := "_count"
39+
if !suffix.IsEmpty() {
40+
metricNameSuffix = suffix.Get()
41+
}
3742
return func(_ context.Context, tCtx ottlmetric.TransformContext) (any, error) {
3843
metric := tCtx.GetMetric()
3944

@@ -44,7 +49,7 @@ func extractCountMetric(monotonic bool) (ottl.ExprFunc[ottlmetric.TransformConte
4449

4550
countMetric := pmetric.NewMetric()
4651
countMetric.SetDescription(metric.Description())
47-
countMetric.SetName(metric.Name() + "_count")
52+
countMetric.SetName(metric.Name() + metricNameSuffix)
4853
// Use the default unit as the original metric unit does not apply to the 'count' field
4954
countMetric.SetUnit("1")
5055
countMetric.SetEmptySum().SetAggregationTemporality(aggTemp)

0 commit comments

Comments
 (0)