Skip to content

Commit 73e67ba

Browse files
author
Felipe Lopes
authored
[processor/metricstransformprocessor] Support count aggregation type (#32935)
**Description:** Implements #24978.
1 parent 3ee48c4 commit 73e67ba

File tree

5 files changed

+94
-3
lines changed

5 files changed

+94
-3
lines changed

.chloggen/count-aggregation-type.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: metricstransformprocessor
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: "Adds the 'count' aggregation type to the Metrics Transform Processor."
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: [24978]
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/metricstransformprocessor/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ processors:
8686
# new_name specifies the updated name of the metric; if action is insert or combine, new_name is required
8787
new_name: <new_metric_name_inserted>
8888
# aggregation_type defines how combined data points will be aggregated; if action is combine, aggregation_type is required
89-
aggregation_type: {sum, mean, min, max}
89+
aggregation_type: {sum, mean, min, max, count}
9090
# submatch_case specifies the case that should be used when adding label values based on regexp submatches when performing a combine action; leave blank to use the submatch value as is
9191
submatch_case: {lower, upper}
9292
# operations contain a list of operations that will be performed on the resulting metric(s)
@@ -106,7 +106,7 @@ processors:
106106
# label_set contains a list of labels that will remain after aggregation; if action is aggregate_labels, label_set is required
107107
label_set: [labels...]
108108
# aggregation_type defines how data points will be aggregated; if action is aggregate_labels or aggregate_label_values, aggregation_type is required
109-
aggregation_type: {sum, mean, min, max}
109+
aggregation_type: {sum, mean, min, max, count}
110110
# experimental_scale specifies the scalar to apply to values
111111
experimental_scale: <scalar>
112112
# value_actions contain a list of operations that will be performed on the selected label

processor/metricstransformprocessor/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,12 @@ const (
231231

232232
// max indicates taking the max of the aggregated data.
233233
max aggregationType = "max"
234+
235+
// count indicates taking the count of the aggregated data.
236+
count aggregationType = "count"
234237
)
235238

236-
var aggregationTypes = []aggregationType{sum, mean, min, max}
239+
var aggregationTypes = []aggregationType{sum, mean, min, max, count}
237240

238241
func (at aggregationType) isValid() bool {
239242
for _, aggregationType := range aggregationTypes {

processor/metricstransformprocessor/metrics_transform_processor_testcases_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,35 @@ var (
298298
addIntDatapoint(1, 2, 3, "label1-value1").build(),
299299
},
300300
},
301+
{
302+
name: "metric_label_aggregation_count_int_update",
303+
transforms: []internalTransform{
304+
{
305+
MetricIncludeFilter: internalFilterStrict{include: "metric1"},
306+
Action: Update,
307+
Operations: []internalOperation{
308+
{
309+
configOperation: Operation{
310+
Action: aggregateLabels,
311+
AggregationType: count,
312+
LabelSet: []string{"label1"},
313+
},
314+
labelSetMap: map[string]bool{"label1": true},
315+
},
316+
},
317+
},
318+
},
319+
in: []pmetric.Metric{
320+
metricBuilder(pmetric.MetricTypeGauge, "metric1", "label1", "label2").
321+
addIntDatapoint(1, 2, 1, "label1-value1", "label2-value1").
322+
addIntDatapoint(1, 2, 4, "label1-value1", "label2-value2").
323+
addIntDatapoint(1, 2, 2, "label1-value1", "label2-value2").build(),
324+
},
325+
out: []pmetric.Metric{
326+
metricBuilder(pmetric.MetricTypeGauge, "metric1", "label1").
327+
addIntDatapoint(1, 2, 3, "label1-value1").build(),
328+
},
329+
},
301330
{
302331
name: "metric_label_aggregation_min_int_update",
303332
transforms: []internalTransform{
@@ -411,6 +440,34 @@ var (
411440
addDoubleDatapoint(1, 2, 3, "label1-value1").build(),
412441
},
413442
},
443+
{
444+
name: "metric_label_aggregation_count_double_update",
445+
transforms: []internalTransform{
446+
{
447+
MetricIncludeFilter: internalFilterStrict{include: "metric1"},
448+
Action: Update,
449+
Operations: []internalOperation{
450+
{
451+
configOperation: Operation{
452+
Action: aggregateLabels,
453+
AggregationType: count,
454+
LabelSet: []string{"label1"},
455+
},
456+
labelSetMap: map[string]bool{"label1": true},
457+
},
458+
},
459+
},
460+
},
461+
in: []pmetric.Metric{
462+
metricBuilder(pmetric.MetricTypeGauge, "metric1", "label1", "label2").
463+
addDoubleDatapoint(1, 2, 3, "label1-value1", "label2-value1").
464+
addDoubleDatapoint(1, 2, 1, "label1-value1", "label2-value2").build(),
465+
},
466+
out: []pmetric.Metric{
467+
metricBuilder(pmetric.MetricTypeGauge, "metric1", "label1").
468+
addDoubleDatapoint(1, 2, 2, "label1-value1").build(),
469+
},
470+
},
414471
{
415472
name: "metric_label_aggregation_min_double_update",
416473
transforms: []internalTransform{

processor/metricstransformprocessor/operation_aggregate_labels.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ func mergeNumberDataPoints(dpsMap map[string]pmetric.NumberDataPointSlice, agg a
167167
dp.SetDoubleValue(math.Max(dp.DoubleValue(), doubleVal(dps.At(i))))
168168
case min:
169169
dp.SetDoubleValue(math.Min(dp.DoubleValue(), doubleVal(dps.At(i))))
170+
case count:
171+
dp.SetDoubleValue(float64(dps.Len()))
170172
}
171173
if dps.At(i).StartTimestamp() < dp.StartTimestamp() {
172174
dp.SetStartTimestamp(dps.At(i).StartTimestamp())
@@ -188,6 +190,8 @@ func mergeNumberDataPoints(dpsMap map[string]pmetric.NumberDataPointSlice, agg a
188190
if dp.IntValue() > intVal(dps.At(i)) {
189191
dp.SetIntValue(intVal(dps.At(i)))
190192
}
193+
case count:
194+
dp.SetIntValue(int64(dps.Len()))
191195
}
192196
if dps.At(i).StartTimestamp() < dp.StartTimestamp() {
193197
dp.SetStartTimestamp(dps.At(i).StartTimestamp())

0 commit comments

Comments
 (0)