Skip to content

Commit

Permalink
Unify the OTLP attribute transform (#2170)
Browse files Browse the repository at this point in the history
* Unify the otlpmetric attribute transform

* Unify attr conversion in otlptrace
  • Loading branch information
MrAlias authored Aug 11, 2021
1 parent a882ee3 commit 1cb5cdc
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 187 deletions.
66 changes: 37 additions & 29 deletions exporters/otlp/otlpmetric/internal/metrictransform/attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,71 +23,79 @@ import (
"go.opentelemetry.io/otel/sdk/resource"
)

// Attributes transforms a slice of KeyValues into a slice of OTLP attribute key-values.
func Attributes(attrs []attribute.KeyValue) []*commonpb.KeyValue {
// KeyValues transforms a slice of attribute KeyValues into OTLP key-values.
func KeyValues(attrs []attribute.KeyValue) []*commonpb.KeyValue {
if len(attrs) == 0 {
return nil
}

out := make([]*commonpb.KeyValue, 0, len(attrs))
for _, kv := range attrs {
out = append(out, toAttribute(kv))
out = append(out, KeyValue(kv))
}
return out
}

// ResourceAttributes transforms a Resource into a slice of OTLP attribute key-values.
func ResourceAttributes(resource *resource.Resource) []*commonpb.KeyValue {
if resource.Len() == 0 {
// Iterator transforms an attribute iterator into OTLP key-values.
func Iterator(iter attribute.Iterator) []*commonpb.KeyValue {
l := iter.Len()
if l == 0 {
return nil
}

out := make([]*commonpb.KeyValue, 0, resource.Len())
for iter := resource.Iter(); iter.Next(); {
out = append(out, toAttribute(iter.Attribute()))
out := make([]*commonpb.KeyValue, 0, l)
for iter.Next() {
out = append(out, KeyValue(iter.Attribute()))
}

return out
}

func toAttribute(v attribute.KeyValue) *commonpb.KeyValue {
result := &commonpb.KeyValue{
Key: string(v.Key),
Value: new(commonpb.AnyValue),
}
switch v.Value.Type() {
// ResourceAttributes transforms a Resource OTLP key-values.
func ResourceAttributes(resource *resource.Resource) []*commonpb.KeyValue {
return Iterator(resource.Iter())
}

// KeyValue transforms an attribute KeyValue into an OTLP key-value.
func KeyValue(kv attribute.KeyValue) *commonpb.KeyValue {
return &commonpb.KeyValue{Key: string(kv.Key), Value: Value(kv.Value)}
}

// Value transforms an attribute Value into an OTLP AnyValue.
func Value(v attribute.Value) *commonpb.AnyValue {
av := new(commonpb.AnyValue)
switch v.Type() {
case attribute.BOOL:
result.Value.Value = &commonpb.AnyValue_BoolValue{
BoolValue: v.Value.AsBool(),
av.Value = &commonpb.AnyValue_BoolValue{
BoolValue: v.AsBool(),
}
case attribute.INT64:
result.Value.Value = &commonpb.AnyValue_IntValue{
IntValue: v.Value.AsInt64(),
av.Value = &commonpb.AnyValue_IntValue{
IntValue: v.AsInt64(),
}
case attribute.FLOAT64:
result.Value.Value = &commonpb.AnyValue_DoubleValue{
DoubleValue: v.Value.AsFloat64(),
av.Value = &commonpb.AnyValue_DoubleValue{
DoubleValue: v.AsFloat64(),
}
case attribute.STRING:
result.Value.Value = &commonpb.AnyValue_StringValue{
StringValue: v.Value.AsString(),
av.Value = &commonpb.AnyValue_StringValue{
StringValue: v.AsString(),
}
case attribute.ARRAY:
result.Value.Value = &commonpb.AnyValue_ArrayValue{
av.Value = &commonpb.AnyValue_ArrayValue{
ArrayValue: &commonpb.ArrayValue{
Values: arrayValues(v),
},
}
default:
result.Value.Value = &commonpb.AnyValue_StringValue{
av.Value = &commonpb.AnyValue_StringValue{
StringValue: "INVALID",
}
}
return result
return av
}

func arrayValues(kv attribute.KeyValue) []*commonpb.AnyValue {
a := kv.Value.AsArray()
func arrayValues(v attribute.Value) []*commonpb.AnyValue {
a := v.AsArray()
aType := reflect.TypeOf(a)
var valueFunc func(reflect.Value) *commonpb.AnyValue
switch aType.Elem().Kind() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func TestAttributes(t *testing.T) {
},
},
} {
got := Attributes(test.attrs)
got := KeyValues(test.attrs)
if !assert.Len(t, got, len(test.expected)) {
continue
}
Expand Down Expand Up @@ -142,7 +142,7 @@ func TestArrayAttributes(t *testing.T) {
},
},
} {
actualArrayAttributes := Attributes(test.attrs)
actualArrayAttributes := KeyValues(test.attrs)
expectedArrayAttributes := test.expected
if !assert.Len(t, actualArrayAttributes, len(expectedArrayAttributes)) {
continue
Expand Down
123 changes: 7 additions & 116 deletions exporters/otlp/otlpmetric/internal/metrictransform/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func gaugeArray(record export.Record, points []aggregation.Point) (*metricpb.Met
Unit: string(desc.Unit()),
}

pbAttrs := keyValues(labels.Iter())
pbAttrs := Iterator(labels.Iter())

ndp := make([]*metricpb.NumberDataPoint, 0, len(points))
switch nk := desc.NumberKind(); nk {
Expand Down Expand Up @@ -375,7 +375,7 @@ func gaugePoint(record export.Record, num number.Number, start, end time.Time) (
Value: &metricpb.NumberDataPoint_AsInt{
AsInt: num.CoerceToInt64(n),
},
Attributes: keyValues(labels.Iter()),
Attributes: Iterator(labels.Iter()),
StartTimeUnixNano: toNanos(start),
TimeUnixNano: toNanos(end),
},
Expand All @@ -390,7 +390,7 @@ func gaugePoint(record export.Record, num number.Number, start, end time.Time) (
Value: &metricpb.NumberDataPoint_AsDouble{
AsDouble: num.CoerceToFloat64(n),
},
Attributes: keyValues(labels.Iter()),
Attributes: Iterator(labels.Iter()),
StartTimeUnixNano: toNanos(start),
TimeUnixNano: toNanos(end),
},
Expand Down Expand Up @@ -435,7 +435,7 @@ func sumPoint(record export.Record, num number.Number, start, end time.Time, ek
Value: &metricpb.NumberDataPoint_AsInt{
AsInt: num.CoerceToInt64(n),
},
Attributes: keyValues(labels.Iter()),
Attributes: Iterator(labels.Iter()),
StartTimeUnixNano: toNanos(start),
TimeUnixNano: toNanos(end),
},
Expand All @@ -452,7 +452,7 @@ func sumPoint(record export.Record, num number.Number, start, end time.Time, ek
Value: &metricpb.NumberDataPoint_AsDouble{
AsDouble: num.CoerceToFloat64(n),
},
Attributes: keyValues(labels.Iter()),
Attributes: Iterator(labels.Iter()),
StartTimeUnixNano: toNanos(start),
TimeUnixNano: toNanos(end),
},
Expand Down Expand Up @@ -502,7 +502,7 @@ func minMaxSumCount(record export.Record, a aggregation.MinMaxSumCount) (*metric
DataPoints: []*metricpb.SummaryDataPoint{
{
Sum: sum.CoerceToFloat64(desc.NumberKind()),
Attributes: keyValues(labels.Iter()),
Attributes: Iterator(labels.Iter()),
StartTimeUnixNano: toNanos(record.StartTime()),
TimeUnixNano: toNanos(record.EndTime()),
Count: uint64(count),
Expand Down Expand Up @@ -566,7 +566,7 @@ func histogramPoint(record export.Record, ek export.ExportKind, a aggregation.Hi
DataPoints: []*metricpb.HistogramDataPoint{
{
Sum: sum.CoerceToFloat64(desc.NumberKind()),
Attributes: keyValues(labels.Iter()),
Attributes: Iterator(labels.Iter()),
StartTimeUnixNano: toNanos(record.StartTime()),
TimeUnixNano: toNanos(record.EndTime()),
Count: uint64(count),
Expand All @@ -579,112 +579,3 @@ func histogramPoint(record export.Record, ek export.ExportKind, a aggregation.Hi
}
return m, nil
}

// keyValues transforms an attribute iterator into an OTLP KeyValues.
func keyValues(iter attribute.Iterator) []*commonpb.KeyValue {
l := iter.Len()
if l == 0 {
return nil
}
result := make([]*commonpb.KeyValue, 0, l)
for iter.Next() {
kv := iter.Label()
result = append(result, &commonpb.KeyValue{
Key: string(kv.Key),
Value: value(kv.Value),
})
}
return result
}

// value transforms an attribute Value into an OTLP AnyValue.
func value(v attribute.Value) *commonpb.AnyValue {
switch v.Type() {
case attribute.BOOL:
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_BoolValue{
BoolValue: v.AsBool(),
},
}
case attribute.INT64:
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_IntValue{
IntValue: v.AsInt64(),
},
}
case attribute.FLOAT64:
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_DoubleValue{
DoubleValue: v.AsFloat64(),
},
}
case attribute.ARRAY:
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_ArrayValue{
ArrayValue: &commonpb.ArrayValue{
Values: arrayValue(v.AsArray()),
},
},
}
default:
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_StringValue{
StringValue: v.Emit(),
},
}
}
}

// arrayValue transforms an attribute Value of ARRAY type into an slice of
// OTLP AnyValue.
func arrayValue(arr interface{}) []*commonpb.AnyValue {
var av []*commonpb.AnyValue
switch val := arr.(type) {
case []bool:
av = make([]*commonpb.AnyValue, len(val))
for i, v := range val {
av[i] = &commonpb.AnyValue{
Value: &commonpb.AnyValue_BoolValue{
BoolValue: v,
},
}
}
case []int:
av = make([]*commonpb.AnyValue, len(val))
for i, v := range val {
av[i] = &commonpb.AnyValue{
Value: &commonpb.AnyValue_IntValue{
IntValue: int64(v),
},
}
}
case []int64:
av = make([]*commonpb.AnyValue, len(val))
for i, v := range val {
av[i] = &commonpb.AnyValue{
Value: &commonpb.AnyValue_IntValue{
IntValue: v,
},
}
}
case []float64:
av = make([]*commonpb.AnyValue, len(val))
for i, v := range val {
av[i] = &commonpb.AnyValue{
Value: &commonpb.AnyValue_DoubleValue{
DoubleValue: v,
},
}
}
case []string:
av = make([]*commonpb.AnyValue, len(val))
for i, v := range val {
av[i] = &commonpb.AnyValue{
Value: &commonpb.AnyValue_StringValue{
StringValue: v,
},
}
}
}
return av
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestStringKeyValues(t *testing.T) {

for _, test := range tests {
labels := attribute.NewSet(test.kvs...)
assert.Equal(t, test.expected, keyValues(labels.Iter()))
assert.Equal(t, test.expected, Iterator(labels.Iter()))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ func TestResourceAttributes(t *testing.T) {
if !assert.Len(t, attrs, 2) {
return
}
assert.ElementsMatch(t, Attributes(attrs), got)
assert.ElementsMatch(t, KeyValues(attrs), got)
}
Loading

0 comments on commit 1cb5cdc

Please sign in to comment.