123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- package golden // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden"
- import (
- "fmt"
- "sort"
- "strings"
- "go.opentelemetry.io/collector/pdata/pcommon"
- "go.opentelemetry.io/collector/pdata/pmetric"
- )
- // sorts all Resource Metrics attributes and Datapoint Slice metric attributes and all Resource, Scope, and Datapoint Slices
- func sortMetrics(ms pmetric.Metrics) {
- rms := ms.ResourceMetrics()
- for i := 0; i < rms.Len(); i++ {
- sortAttributeMap(rms.At(i).Resource().Attributes())
- ilms := rms.At(i).ScopeMetrics()
- for j := 0; j < ilms.Len(); j++ {
- sortAttributeMap(ilms.At(j).Scope().Attributes())
- metricsList := ilms.At(j).Metrics()
- for k := 0; k < metricsList.Len(); k++ {
- metric := metricsList.At(k)
- //exhaustive:enforce
- switch metricsList.At(k).Type() {
- case pmetric.MetricTypeGauge:
- ds := metric.Gauge().DataPoints()
- for l := 0; l < ds.Len(); l++ {
- sortAttributeMap(ds.At(l).Attributes())
- }
- case pmetric.MetricTypeSum:
- ds := metric.Sum().DataPoints()
- for l := 0; l < ds.Len(); l++ {
- sortAttributeMap(ds.At(l).Attributes())
- }
- case pmetric.MetricTypeHistogram:
- ds := metric.Histogram().DataPoints()
- for l := 0; l < ds.Len(); l++ {
- sortAttributeMap(ds.At(l).Attributes())
- }
- case pmetric.MetricTypeExponentialHistogram:
- ds := metric.ExponentialHistogram().DataPoints()
- for l := 0; l < ds.Len(); l++ {
- sortAttributeMap(ds.At(l).Attributes())
- }
- case pmetric.MetricTypeSummary:
- ds := metric.Summary().DataPoints()
- for l := 0; l < ds.Len(); l++ {
- sortAttributeMap(ds.At(l).Attributes())
- }
- }
- }
- }
- }
- sortResources(ms)
- sortScopes(ms)
- sortMetricDataPointSlices(ms)
- }
- // sortAttributeMap sorts the attributes of a pcommon.Map according to the alphanumeric ordering of the keys
- func sortAttributeMap(mp pcommon.Map) {
- tempMap := pcommon.NewMap()
- keys := []string{}
- mp.Range(func(key string, _ pcommon.Value) bool {
- keys = append(keys, key)
- return true
- })
- sort.Strings(keys)
- for _, k := range keys {
- value, exists := mp.Get(k)
- if exists {
- switch value.Type() {
- case pcommon.ValueTypeStr:
- tempMap.PutStr(k, value.Str())
- case pcommon.ValueTypeBool:
- tempMap.PutBool(k, value.Bool())
- case pcommon.ValueTypeInt:
- tempMap.PutInt(k, value.Int())
- case pcommon.ValueTypeDouble:
- tempMap.PutDouble(k, value.Double())
- case pcommon.ValueTypeMap:
- value.Map().CopyTo(tempMap.PutEmptyMap(k))
- case pcommon.ValueTypeSlice:
- value.Slice().CopyTo(tempMap.PutEmptySlice(k))
- case pcommon.ValueTypeBytes:
- value.Bytes().CopyTo(tempMap.PutEmptyBytes(k))
- }
- }
- }
- tempMap.CopyTo(mp)
- }
- // sortMetricDataPointSlices sorts the datapoint slice of a pmetric.Metrics according to the alphanumeric ordering of map key
- func sortMetricDataPointSlices(ms pmetric.Metrics) {
- for i := 0; i < ms.ResourceMetrics().Len(); i++ {
- for j := 0; j < ms.ResourceMetrics().At(i).ScopeMetrics().Len(); j++ {
- for k := 0; k < ms.ResourceMetrics().At(i).ScopeMetrics().At(j).Metrics().Len(); k++ {
- m := ms.ResourceMetrics().At(i).ScopeMetrics().At(j).Metrics().At(k)
- //exhaustive:enforce
- switch m.Type() {
- case pmetric.MetricTypeGauge:
- sortNumberDataPointSlice(m.Gauge().DataPoints())
- case pmetric.MetricTypeSum:
- sortNumberDataPointSlice(m.Sum().DataPoints())
- case pmetric.MetricTypeHistogram:
- sortHistogramDataPointSlice(m.Histogram().DataPoints())
- case pmetric.MetricTypeExponentialHistogram:
- sortExponentialHistogramDataPointSlice(m.ExponentialHistogram().DataPoints())
- case pmetric.MetricTypeSummary:
- sortSummaryDataPointSlice(m.Summary().DataPoints())
- }
- }
- }
- }
- }
- func sortResources(ms pmetric.Metrics) {
- ms.ResourceMetrics().Sort(func(a, b pmetric.ResourceMetrics) bool {
- return compareMaps(a.Resource().Attributes(), b.Resource().Attributes()) < 0
- })
- }
- func sortScopes(ms pmetric.Metrics) {
- for i := 0; i < ms.ResourceMetrics().Len(); i++ {
- rm := ms.ResourceMetrics().At(i)
- rm.ScopeMetrics().Sort(func(a, b pmetric.ScopeMetrics) bool {
- return compareMaps(a.Scope().Attributes(), b.Scope().Attributes()) < 0
- })
- }
- }
- func sortNumberDataPointSlice(ndps pmetric.NumberDataPointSlice) {
- ndps.Sort(func(a, b pmetric.NumberDataPoint) bool {
- return compareMaps(a.Attributes(), b.Attributes()) < 0
- })
- }
- func sortSummaryDataPointSlice(sdps pmetric.SummaryDataPointSlice) {
- sdps.Sort(func(a, b pmetric.SummaryDataPoint) bool {
- return compareMaps(a.Attributes(), b.Attributes()) < 0
- })
- }
- func sortHistogramDataPointSlice(hdps pmetric.HistogramDataPointSlice) {
- hdps.Sort(func(a, b pmetric.HistogramDataPoint) bool {
- return compareMaps(a.Attributes(), b.Attributes()) < 0
- })
- }
- func sortExponentialHistogramDataPointSlice(ehdps pmetric.ExponentialHistogramDataPointSlice) {
- ehdps.Sort(func(a, b pmetric.ExponentialHistogramDataPoint) bool {
- return compareMaps(a.Attributes(), b.Attributes()) < 0
- })
- }
- func compareMaps(a, b pcommon.Map) int {
- sortAttributeMap(a)
- sortAttributeMap(b)
- if a.Len() != b.Len() {
- return a.Len() - b.Len()
- }
- var aKeys, bKeys []string
- a.Range(func(k string, v pcommon.Value) bool {
- aKeys = append(aKeys, fmt.Sprintf("%s: %v", k, v.AsString()))
- return true
- })
- b.Range(func(k string, v pcommon.Value) bool {
- bKeys = append(bKeys, fmt.Sprintf("%s: %v", k, v.AsString()))
- return true
- })
- for i := 0; i < len(aKeys); i++ {
- if aKeys[i] != bKeys[i] {
- return strings.Compare(aKeys[i], bKeys[i])
- }
- }
- return 0
- }
|