Skip to content

Commit

Permalink
[exporter/awsemfexporter] Fix regression in dimension roll up (#14532)
Browse files Browse the repository at this point in the history
* [exporter/awsemfexporter]Fix regression in dimension roll up

* Add changelog

* Fix linting errors

* Improve readability

* Improve unit tests
  • Loading branch information
rapphil committed Sep 28, 2022
1 parent ca42b2c commit 575c72b
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 16 deletions.
57 changes: 43 additions & 14 deletions exporter/awsemfexporter/metric_translator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ package awsemfexporter

import (
"os"
"reflect"
"sort"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -296,17 +296,46 @@ func stringSlicesEqual(expected, actual []string) bool {
return true
}

// hashDimensions hashes dimensions for equality checking.
func hashDimensions(dims [][]string) []string {
func min(i, j int) int {
if i < j {
return i
}
return j
}

type dimensionality [][]string

func (d dimensionality) Len() int {
return len(d)
}

func (d dimensionality) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}

func (d dimensionality) Less(i, j int) bool {
dim1 := d[i]
dim2 := d[j]

for k := 0; k < min(len(dim1), len(dim2)); k++ {
if dim1[k] != dim2[k] {
return dim1[k] < dim2[k]
}
}

return len(dim1) < len(dim2)
}

// normalizes a dimensionality lexicographically so that it can be compared
func normalizeDimensionality(dims [][]string) [][]string {
// Convert to string for easier sorting
stringified := make([]string, len(dims))
sortedDimensions := make([][]string, len(dims))
for i, v := range dims {
sort.Strings(v)
stringified[i] = strings.Join(v, ",")
sortedDimensions[i] = v
}
// Sort across dimension sets for equality checking
sort.Strings(stringified)
return stringified
sort.Sort(dimensionality(sortedDimensions))
return sortedDimensions
}

// hashMetricSlice hashes a metrics slice for equality checking.
Expand All @@ -325,9 +354,9 @@ func hashMetricSlice(metricSlice []map[string]string) []string {
// (i.e. has same sets of dimensions), regardless of order.
func assertDimsEqual(t *testing.T, expected, actual [][]string) {
assert.Equal(t, len(expected), len(actual))
expectedHashedDimensions := hashDimensions(expected)
actualHashedDimensions := hashDimensions(actual)
assert.Equal(t, expectedHashedDimensions, actualHashedDimensions)
expectedDimensions := normalizeDimensionality(expected)
actualDimensions := normalizeDimensionality(actual)
assert.True(t, reflect.DeepEqual(expectedDimensions, actualDimensions))
}

// cWMeasurementEqual returns true if CW Measurements are equal.
Expand All @@ -351,9 +380,9 @@ func cWMeasurementEqual(expected, actual cWMeasurement) bool {
if len(expected.Dimensions) != len(actual.Dimensions) {
return false
}
expectedHashedDimensions := hashDimensions(expected.Dimensions)
actualHashedDimensions := hashDimensions(actual.Dimensions)
return stringSlicesEqual(expectedHashedDimensions, actualHashedDimensions)
expectedDimensions := normalizeDimensionality(expected.Dimensions)
actualDimensions := normalizeDimensionality(actual.Dimensions)
return reflect.DeepEqual(expectedDimensions, actualDimensions)
}

// assertCWMeasurementEqual asserts whether CW Measurements are equal.
Expand Down
6 changes: 4 additions & 2 deletions exporter/awsemfexporter/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,15 @@ func dedupDimensions(dimensions [][]string) (deduped [][]string) {
// The returned dimensions are sorted in alphabetical order within each dimension set
func dimensionRollup(dimensionRollupOption string, labels map[string]string) [][]string {
var rollupDimensionArray [][]string
var dimensionZero []string

// Empty dimension must be always present in a roll up.
dimensionZero := []string{}

instrLibName, hasOTelKey := labels[oTellibDimensionKey]
if hasOTelKey {
// If OTel key exists in labels, add it as a zero dimension but remove it
// temporarily from labels as it is not an original label
dimensionZero = []string{oTellibDimensionKey}
dimensionZero = append(dimensionZero, oTellibDimensionKey)
delete(labels, oTellibDimensionKey)
}

Expand Down
11 changes: 11 additions & 0 deletions unreleased/awsemfexporter-fix-regression-null-dimension.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 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: awsemfexporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Fix regression that causes null dimensions to be appended during dimension roll up.

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

0 comments on commit 575c72b

Please sign in to comment.