Skip to content

Commit

Permalink
[exporter/azuremonitor] Export metric attributes to Azure Monitor (#2…
Browse files Browse the repository at this point in the history
…0671)

As of now, no attributes (dimensions) from the metrics timeseries model are exported to Application Insights. This PR ensures that for all metric points, attributes are present as customDimensions in Application Insights.

---------

Co-authored-by: Antoine Toulme <[email protected]>
  • Loading branch information
bastbu and atoulme authored Apr 9, 2023
1 parent 6e62214 commit 5fbe4fa
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 17 deletions.
16 changes: 16 additions & 0 deletions .chloggen/export-metric-dimensions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: azuremonitorexporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Ensure that metric attributes are exported to Azure Monitor

# One or more tracking issues related to the change
issues: [19407]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
8 changes: 8 additions & 0 deletions exporter/azuremonitorexporter/contracts_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@ func applyInstrumentationScopeValueToDataProperties(dataProperties map[string]st
dataProperties[instrumentationLibraryVersion] = instrumentationScope.Version()
}
}

// Applies attributes as Application Insights properties
func setAttributesAsProperties(attributeMap pcommon.Map, properties map[string]string) {
attributeMap.Range(func(k string, v pcommon.Value) bool {
properties[k] = v.AsString()
return true
})
}
7 changes: 0 additions & 7 deletions exporter/azuremonitorexporter/log_to_envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,3 @@ func timestampFromLogRecord(lr plog.LogRecord) pcommon.Timestamp {

return pcommon.NewTimestampFromTime(timeNow())
}

func setAttributesAsProperties(attributeMap pcommon.Map, properties map[string]string) {
attributeMap.Range(func(k string, v pcommon.Value) bool {
properties[k] = v.AsString()
return true
})
}
27 changes: 17 additions & 10 deletions exporter/azuremonitorexporter/metric_to_envelopes.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ type metricPacker struct {
}

type timedMetricDataPoint struct {
dataPoint *contracts.DataPoint
timestamp pcommon.Timestamp
dataPoint *contracts.DataPoint
timestamp pcommon.Timestamp
attributes pcommon.Map
}

type metricTimedData interface {
Expand Down Expand Up @@ -67,6 +68,8 @@ func (packer *metricPacker) MetricToEnvelopes(metric pmetric.Metric, resource pc
applyInstrumentationScopeValueToDataProperties(metricData.Properties, instrumentationScope)
applyCloudTagsToEnvelope(envelope, resourceAttributes)

setAttributesAsProperties(timedDataPoint.attributes, metricData.Properties)

packer.sanitize(func() []string { return metricData.Sanitize() })
packer.sanitize(func() []string { return envelope.Sanitize() })
packer.sanitize(func() []string { return contracts.SanitizeTags(envelope.Tags) })
Expand Down Expand Up @@ -141,8 +144,9 @@ func (m scalarMetric) getTimedDataPoints() []*timedMetricDataPoint {
dataPoint.Count = 1
dataPoint.Kind = contracts.Measurement
timedDataPoints[i] = &timedMetricDataPoint{
dataPoint: dataPoint,
timestamp: numberDataPoint.Timestamp(),
dataPoint: dataPoint,
timestamp: numberDataPoint.Timestamp(),
attributes: numberDataPoint.Attributes(),
}
}
return timedDataPoints
Expand Down Expand Up @@ -173,8 +177,9 @@ func (m histogramMetric) getTimedDataPoints() []*timedMetricDataPoint {
dataPoint.Count = int(histogramDataPoint.Count())

timedDataPoints[i] = &timedMetricDataPoint{
dataPoint: dataPoint,
timestamp: histogramDataPoint.Timestamp(),
dataPoint: dataPoint,
timestamp: histogramDataPoint.Timestamp(),
attributes: histogramDataPoint.Attributes(),
}

}
Expand Down Expand Up @@ -206,8 +211,9 @@ func (m exponentialHistogramMetric) getTimedDataPoints() []*timedMetricDataPoint
dataPoint.Count = int(exponentialHistogramDataPoint.Count())

timedDataPoints[i] = &timedMetricDataPoint{
dataPoint: dataPoint,
timestamp: exponentialHistogramDataPoint.Timestamp(),
dataPoint: dataPoint,
timestamp: exponentialHistogramDataPoint.Timestamp(),
attributes: exponentialHistogramDataPoint.Attributes(),
}
}
return timedDataPoints
Expand Down Expand Up @@ -236,8 +242,9 @@ func (m summaryMetric) getTimedDataPoints() []*timedMetricDataPoint {
dataPoint.Count = int(summaryDataPoint.Count())

timedDataPoints[i] = &timedMetricDataPoint{
dataPoint: dataPoint,
timestamp: summaryDataPoint.Timestamp(),
dataPoint: dataPoint,
timestamp: summaryDataPoint.Timestamp(),
attributes: summaryDataPoint.Attributes(),
}

}
Expand Down
19 changes: 19 additions & 0 deletions exporter/azuremonitorexporter/metricexporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/microsoft/ApplicationInsights-Go/appinsights/contracts"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.uber.org/zap"
)
Expand Down Expand Up @@ -137,6 +138,12 @@ func getDataPoint(t testing.TB, metric pmetric.Metric) *contracts.DataPoint {
dataPoint := metricData.Metrics[0]
require.NotNil(t, dataPoint)

actualProperties := metricData.Properties
require.Equal(t, "10", actualProperties["int_attribute"])
require.Equal(t, "str_value", actualProperties["str_attribute"])
require.Equal(t, "true", actualProperties["bool_attribute"])
require.Equal(t, "1.2", actualProperties["double_attribute"])

return dataPoint
}

Expand Down Expand Up @@ -202,6 +209,7 @@ func getTestGaugeMetric(modify func(pmetric.NumberDataPoint)) pmetric.Metric {
metric.SetEmptyGauge()
datapoints := metric.Gauge().DataPoints()
datapoint := datapoints.AppendEmpty()
setDefaultTestAttributes(datapoint.Attributes())
modify(datapoint)
return metric
}
Expand All @@ -224,6 +232,7 @@ func getTestSumMetric(modify func(pmetric.NumberDataPoint)) pmetric.Metric {
metric.SetEmptySum()
datapoints := metric.Sum().DataPoints()
datapoint := datapoints.AppendEmpty()
setDefaultTestAttributes(datapoint.Attributes())
modify(datapoint)
return metric
}
Expand All @@ -238,6 +247,7 @@ func getTestHistogramMetric() pmetric.Metric {
datapoint.SetCount(3)
datapoint.SetMin(0)
datapoint.SetMax(2)
setDefaultTestAttributes(datapoint.Attributes())
return metric
}

Expand All @@ -251,6 +261,7 @@ func getTestExponentialHistogramMetric() pmetric.Metric {
datapoint.SetCount(4)
datapoint.SetMin(1)
datapoint.SetMax(3)
setDefaultTestAttributes(datapoint.Attributes())
return metric
}

Expand All @@ -262,5 +273,13 @@ func getTestSummaryMetric() pmetric.Metric {
datapoint := datapoints.AppendEmpty()
datapoint.SetSum(5)
datapoint.SetCount(5)
setDefaultTestAttributes(datapoint.Attributes())
return metric
}

func setDefaultTestAttributes(attributeMap pcommon.Map) {
attributeMap.PutInt("int_attribute", 10)
attributeMap.PutStr("str_attribute", "str_value")
attributeMap.PutBool("bool_attribute", true)
attributeMap.PutDouble("double_attribute", 1.2)
}

0 comments on commit 5fbe4fa

Please sign in to comment.