Skip to content

Commit ac33209

Browse files
mdonkersdashpole
andauthored
[fix] Correctly add Metric Labels as Metric Attributes in OTel, not as Resource Attributes (#42473)
#### Description Fixes issue #42232 By no longer adding Metric Labels from the source metric, to the target Resource Attributes. Instead for every metric, add the Labels as Metric Attributes (which was happening for 'histograms' already) #### Link to tracking issue Fixes #42232 #### Testing As there was only a test for gauges, I extended it to validate attributes are correctly converted. --------- Co-authored-by: David Ashpole <[email protected]>
1 parent 02a4c4f commit ac33209

File tree

5 files changed

+45
-9
lines changed

5 files changed

+45
-9
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: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: receiver/googlecloudmonitoring
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add metric labels from Google Cloud metrics to all OTel metric attributes
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: [42232]
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]

receiver/googlecloudmonitoringreceiver/internal/metrics_conversion.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func (mb *MetricsBuilder) ConvertGaugeToMetrics(ts *monitoringpb.TimeSeries, m p
4141
m.SetUnit(ts.GetUnit())
4242
gauge := m.SetEmptyGauge()
4343

44+
metricAttributes := convertLabelsToMetricAttributes(ts.GetMetric().GetLabels())
4445
for _, point := range ts.GetPoints() {
4546
dp := gauge.DataPoints().AppendEmpty()
4647

@@ -56,6 +57,8 @@ func (mb *MetricsBuilder) ConvertGaugeToMetrics(ts *monitoringpb.TimeSeries, m p
5657
mb.logger.Warn("EndTime is invalid for metric:", zap.String("Metric", ts.GetMetric().GetType()))
5758
}
5859

60+
metricAttributes.CopyTo(dp.Attributes())
61+
5962
switch v := point.Value.Value.(type) {
6063
case *monitoringpb.TypedValue_DoubleValue:
6164
dp.SetDoubleValue(v.DoubleValue)
@@ -75,6 +78,7 @@ func (mb *MetricsBuilder) ConvertSumToMetrics(ts *monitoringpb.TimeSeries, m pme
7578
sum := m.SetEmptySum()
7679
sum.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
7780

81+
metricAttributes := convertLabelsToMetricAttributes(ts.GetMetric().GetLabels())
7882
for _, point := range ts.GetPoints() {
7983
dp := sum.DataPoints().AppendEmpty()
8084

@@ -90,6 +94,8 @@ func (mb *MetricsBuilder) ConvertSumToMetrics(ts *monitoringpb.TimeSeries, m pme
9094
mb.logger.Warn("EndTime is invalid for metric:", zap.String("Metric", ts.GetMetric().GetType()))
9195
}
9296

97+
metricAttributes.CopyTo(dp.Attributes())
98+
9399
switch v := point.Value.Value.(type) {
94100
case *monitoringpb.TypedValue_DoubleValue:
95101
dp.SetDoubleValue(v.DoubleValue)
@@ -109,6 +115,7 @@ func (mb *MetricsBuilder) ConvertDeltaToMetrics(ts *monitoringpb.TimeSeries, m p
109115
sum := m.SetEmptySum()
110116
sum.SetAggregationTemporality(pmetric.AggregationTemporalityDelta)
111117

118+
metricAttributes := convertLabelsToMetricAttributes(ts.GetMetric().GetLabels())
112119
for _, point := range ts.GetPoints() {
113120
dp := sum.DataPoints().AppendEmpty()
114121

@@ -124,6 +131,8 @@ func (mb *MetricsBuilder) ConvertDeltaToMetrics(ts *monitoringpb.TimeSeries, m p
124131
mb.logger.Warn("EndTime is invalid for metric:", zap.String("Metric", ts.GetMetric().GetType()))
125132
}
126133

134+
metricAttributes.CopyTo(dp.Attributes())
135+
127136
switch v := point.Value.Value.(type) {
128137
case *monitoringpb.TypedValue_DoubleValue:
129138
dp.SetDoubleValue(v.DoubleValue)
@@ -152,7 +161,7 @@ func (mb *MetricsBuilder) ConvertDistributionToMetrics(ts *monitoringpb.TimeSeri
152161
// > Importers and exporters working with OpenTelemetry Metrics data are meant to disregard this specification when
153162
// > translating to and from histogram formats that use inclusive lower bounds and exclusive upper bounds.
154163

155-
metricAttributes := convertDistributionLabels(ts.GetMetric().GetLabels())
164+
metricAttributes := convertLabelsToMetricAttributes(ts.GetMetric().GetLabels())
156165
for _, sourceDataPoint := range ts.GetPoints() {
157166
sourceValue := sourceDataPoint.GetValue()
158167
if sourceValue == nil {
@@ -271,7 +280,7 @@ func (mb *MetricsBuilder) ConvertDistributionToMetrics(ts *monitoringpb.TimeSeri
271280
return m
272281
}
273282

274-
func convertDistributionLabels(sourceLabels map[string]string) pcommon.Map {
283+
func convertLabelsToMetricAttributes(sourceLabels map[string]string) pcommon.Map {
275284
metricAttributes := pcommon.NewMap()
276285
metricAttributes.EnsureCapacity(len(sourceLabels))
277286
for k, v := range sourceLabels {

receiver/googlecloudmonitoringreceiver/internal/metrics_conversion_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ func TestConvertGaugeToMetrics(t *testing.T) {
4343
},
4444
},
4545
},
46+
Metric: &metric.Metric{
47+
Labels: map[string]string{"labelKey": "labelValue"},
48+
},
4649
},
4750
fileNameExpected: "TestConvertGaugeToMetrics_ValidGaugePoints.yaml",
4851
},

receiver/googlecloudmonitoringreceiver/internal/testdata/TestConvertGaugeToMetrics_ValidGaugePoints.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ resourceMetrics:
77
- asDouble: 42
88
startTimeUnixNano: "10000000000"
99
timeUnixNano: "20000000000"
10+
attributes:
11+
- key: labelKey
12+
value:
13+
stringValue: labelValue
1014
scope: {}

receiver/googlecloudmonitoringreceiver/receiver.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,6 @@ func (mr *monitoringReceiver) convertGCPTimeSeriesToMetrics(metrics pmetric.Metr
279279
}
280280
}
281281

282-
// Add metric-specific labels if they are present
283-
if len(timeSeries.GetMetric().Labels) > 0 {
284-
for k, v := range timeSeries.GetMetric().GetLabels() {
285-
resource.Attributes().PutStr(k, v)
286-
}
287-
}
288-
289282
// Store the newly created ResourceMetrics in the map
290283
resourceMetricsMap[resourceKey] = rm
291284
}

0 commit comments

Comments
 (0)