diff --git a/CHANGELOG.md b/CHANGELOG.md index 349564a90..b1f0fe4af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixed - Fix gzipped request body replay on redirect in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8152) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/trace`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/zipkin`. (#8153) diff --git a/exporters/otlp/otlplog/otlploggrpc/internal/transform/attr_test.go b/exporters/otlp/otlplog/otlploggrpc/internal/transform/attr_test.go index 290e5cfdb..7c13c68b1 100644 --- a/exporters/otlp/otlplog/otlploggrpc/internal/transform/attr_test.go +++ b/exporters/otlp/otlplog/otlploggrpc/internal/transform/attr_test.go @@ -25,6 +25,7 @@ var ( attrFloat64 = attribute.Float64("float64", 1) attrFloat64Slice = attribute.Float64Slice("float64 slice", []float64{-1, 1}) attrString = attribute.String("string", "o") + attrBytes = attribute.ByteSlice("bytes", []byte("otlp")) attrStringSlice = attribute.StringSlice("string slice", []string{"o", "n"}) attrEmpty = attribute.KeyValue{ Key: attribute.Key("empty"), @@ -53,6 +54,7 @@ var ( }, }} valStrO = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "o"}} + valAttrBytes = &cpb.AnyValue{Value: &cpb.AnyValue_BytesValue{BytesValue: []byte("otlp")}} valStrN = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "n"}} valStrSlice = &cpb.AnyValue{Value: &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ @@ -69,6 +71,7 @@ var ( kvFloat64 = &cpb.KeyValue{Key: "float64", Value: valDblOne} kvFloat64Slice = &cpb.KeyValue{Key: "float64 slice", Value: valDblSlice} kvString = &cpb.KeyValue{Key: "string", Value: valStrO} + kvAttrBytes = &cpb.KeyValue{Key: "bytes", Value: valAttrBytes} kvStringSlice = &cpb.KeyValue{Key: "string slice", Value: valStrSlice} kvEmpty = &cpb.KeyValue{Key: "empty", Value: &cpb.AnyValue{}} ) @@ -133,6 +136,11 @@ func TestAttrTransforms(t *testing.T) { []attribute.KeyValue{attrString}, []*cpb.KeyValue{kvString}, }, + { + "bytes", + []attribute.KeyValue{attrBytes}, + []*cpb.KeyValue{kvAttrBytes}, + }, { "string slice", []attribute.KeyValue{attrStringSlice}, @@ -150,6 +158,7 @@ func TestAttrTransforms(t *testing.T) { attrFloat64, attrFloat64Slice, attrString, + attrBytes, attrStringSlice, attrEmpty, }, @@ -163,6 +172,7 @@ func TestAttrTransforms(t *testing.T) { kvFloat64, kvFloat64Slice, kvString, + kvAttrBytes, kvStringSlice, kvEmpty, }, diff --git a/exporters/otlp/otlplog/otlploggrpc/internal/transform/log.go b/exporters/otlp/otlplog/otlploggrpc/internal/transform/log.go index 81c05e6e8..1da1ee520 100644 --- a/exporters/otlp/otlplog/otlploggrpc/internal/transform/log.go +++ b/exporters/otlp/otlplog/otlploggrpc/internal/transform/log.go @@ -195,6 +195,10 @@ func AttrValue(v attribute.Value) *cpb.AnyValue { av.Value = &cpb.AnyValue_StringValue{ StringValue: v.AsString(), } + case attribute.BYTESLICE: + av.Value = &cpb.AnyValue_BytesValue{ + BytesValue: v.AsByteSlice(), + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/exporters/otlp/otlplog/otlploghttp/internal/transform/attr_test.go b/exporters/otlp/otlplog/otlploghttp/internal/transform/attr_test.go index 290e5cfdb..7c13c68b1 100644 --- a/exporters/otlp/otlplog/otlploghttp/internal/transform/attr_test.go +++ b/exporters/otlp/otlplog/otlploghttp/internal/transform/attr_test.go @@ -25,6 +25,7 @@ var ( attrFloat64 = attribute.Float64("float64", 1) attrFloat64Slice = attribute.Float64Slice("float64 slice", []float64{-1, 1}) attrString = attribute.String("string", "o") + attrBytes = attribute.ByteSlice("bytes", []byte("otlp")) attrStringSlice = attribute.StringSlice("string slice", []string{"o", "n"}) attrEmpty = attribute.KeyValue{ Key: attribute.Key("empty"), @@ -53,6 +54,7 @@ var ( }, }} valStrO = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "o"}} + valAttrBytes = &cpb.AnyValue{Value: &cpb.AnyValue_BytesValue{BytesValue: []byte("otlp")}} valStrN = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "n"}} valStrSlice = &cpb.AnyValue{Value: &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ @@ -69,6 +71,7 @@ var ( kvFloat64 = &cpb.KeyValue{Key: "float64", Value: valDblOne} kvFloat64Slice = &cpb.KeyValue{Key: "float64 slice", Value: valDblSlice} kvString = &cpb.KeyValue{Key: "string", Value: valStrO} + kvAttrBytes = &cpb.KeyValue{Key: "bytes", Value: valAttrBytes} kvStringSlice = &cpb.KeyValue{Key: "string slice", Value: valStrSlice} kvEmpty = &cpb.KeyValue{Key: "empty", Value: &cpb.AnyValue{}} ) @@ -133,6 +136,11 @@ func TestAttrTransforms(t *testing.T) { []attribute.KeyValue{attrString}, []*cpb.KeyValue{kvString}, }, + { + "bytes", + []attribute.KeyValue{attrBytes}, + []*cpb.KeyValue{kvAttrBytes}, + }, { "string slice", []attribute.KeyValue{attrStringSlice}, @@ -150,6 +158,7 @@ func TestAttrTransforms(t *testing.T) { attrFloat64, attrFloat64Slice, attrString, + attrBytes, attrStringSlice, attrEmpty, }, @@ -163,6 +172,7 @@ func TestAttrTransforms(t *testing.T) { kvFloat64, kvFloat64Slice, kvString, + kvAttrBytes, kvStringSlice, kvEmpty, }, diff --git a/exporters/otlp/otlplog/otlploghttp/internal/transform/log.go b/exporters/otlp/otlplog/otlploghttp/internal/transform/log.go index b5a0f5b86..94826b37a 100644 --- a/exporters/otlp/otlplog/otlploghttp/internal/transform/log.go +++ b/exporters/otlp/otlplog/otlploghttp/internal/transform/log.go @@ -195,6 +195,10 @@ func AttrValue(v attribute.Value) *cpb.AnyValue { av.Value = &cpb.AnyValue_StringValue{ StringValue: v.AsString(), } + case attribute.BYTESLICE: + av.Value = &cpb.AnyValue_BytesValue{ + BytesValue: v.AsByteSlice(), + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go index 3e616a927..6e6e94431 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go @@ -81,6 +81,10 @@ func Value(v attribute.Value) *cpb.AnyValue { av.Value = &cpb.AnyValue_StringValue{ StringValue: v.AsString(), } + case attribute.BYTESLICE: + av.Value = &cpb.AnyValue_BytesValue{ + BytesValue: v.AsByteSlice(), + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute_test.go b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute_test.go index e273afba7..1db746e6c 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute_test.go +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute_test.go @@ -25,6 +25,7 @@ var ( attrFloat64 = attribute.Float64("float64", 1) attrFloat64Slice = attribute.Float64Slice("float64 slice", []float64{-1, 1}) attrString = attribute.String("string", "o") + attrBytes = attribute.ByteSlice("bytes", []byte("otlp")) attrStringSlice = attribute.StringSlice("string slice", []string{"o", "n"}) attrEmpty = attribute.KeyValue{ Key: attribute.Key("empty"), @@ -53,6 +54,7 @@ var ( }, }} valStrO = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "o"}} + valBytes = &cpb.AnyValue{Value: &cpb.AnyValue_BytesValue{BytesValue: []byte("otlp")}} valStrN = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "n"}} valStrSlice = &cpb.AnyValue{Value: &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ @@ -69,6 +71,7 @@ var ( kvFloat64 = &cpb.KeyValue{Key: "float64", Value: valDblOne} kvFloat64Slice = &cpb.KeyValue{Key: "float64 slice", Value: valDblSlice} kvString = &cpb.KeyValue{Key: "string", Value: valStrO} + kvBytes = &cpb.KeyValue{Key: "bytes", Value: valBytes} kvStringSlice = &cpb.KeyValue{Key: "string slice", Value: valStrSlice} kvEmpty = &cpb.KeyValue{Key: "empty", Value: &cpb.AnyValue{}} ) @@ -133,6 +136,11 @@ func TestAttributeTransforms(t *testing.T) { []attribute.KeyValue{attrString}, []*cpb.KeyValue{kvString}, }, + { + "bytes", + []attribute.KeyValue{attrBytes}, + []*cpb.KeyValue{kvBytes}, + }, { "string slice", []attribute.KeyValue{attrStringSlice}, @@ -150,6 +158,7 @@ func TestAttributeTransforms(t *testing.T) { attrFloat64, attrFloat64Slice, attrString, + attrBytes, attrStringSlice, attrEmpty, }, @@ -163,6 +172,7 @@ func TestAttributeTransforms(t *testing.T) { kvFloat64, kvFloat64Slice, kvString, + kvBytes, kvStringSlice, kvEmpty, }, diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go index 9e3d8da1e..c610376bb 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go @@ -81,6 +81,10 @@ func Value(v attribute.Value) *cpb.AnyValue { av.Value = &cpb.AnyValue_StringValue{ StringValue: v.AsString(), } + case attribute.BYTESLICE: + av.Value = &cpb.AnyValue_BytesValue{ + BytesValue: v.AsByteSlice(), + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute_test.go b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute_test.go index e273afba7..1db746e6c 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute_test.go +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute_test.go @@ -25,6 +25,7 @@ var ( attrFloat64 = attribute.Float64("float64", 1) attrFloat64Slice = attribute.Float64Slice("float64 slice", []float64{-1, 1}) attrString = attribute.String("string", "o") + attrBytes = attribute.ByteSlice("bytes", []byte("otlp")) attrStringSlice = attribute.StringSlice("string slice", []string{"o", "n"}) attrEmpty = attribute.KeyValue{ Key: attribute.Key("empty"), @@ -53,6 +54,7 @@ var ( }, }} valStrO = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "o"}} + valBytes = &cpb.AnyValue{Value: &cpb.AnyValue_BytesValue{BytesValue: []byte("otlp")}} valStrN = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "n"}} valStrSlice = &cpb.AnyValue{Value: &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ @@ -69,6 +71,7 @@ var ( kvFloat64 = &cpb.KeyValue{Key: "float64", Value: valDblOne} kvFloat64Slice = &cpb.KeyValue{Key: "float64 slice", Value: valDblSlice} kvString = &cpb.KeyValue{Key: "string", Value: valStrO} + kvBytes = &cpb.KeyValue{Key: "bytes", Value: valBytes} kvStringSlice = &cpb.KeyValue{Key: "string slice", Value: valStrSlice} kvEmpty = &cpb.KeyValue{Key: "empty", Value: &cpb.AnyValue{}} ) @@ -133,6 +136,11 @@ func TestAttributeTransforms(t *testing.T) { []attribute.KeyValue{attrString}, []*cpb.KeyValue{kvString}, }, + { + "bytes", + []attribute.KeyValue{attrBytes}, + []*cpb.KeyValue{kvBytes}, + }, { "string slice", []attribute.KeyValue{attrStringSlice}, @@ -150,6 +158,7 @@ func TestAttributeTransforms(t *testing.T) { attrFloat64, attrFloat64Slice, attrString, + attrBytes, attrStringSlice, attrEmpty, }, @@ -163,6 +172,7 @@ func TestAttributeTransforms(t *testing.T) { kvFloat64, kvFloat64Slice, kvString, + kvBytes, kvStringSlice, kvEmpty, }, diff --git a/exporters/otlp/otlptrace/internal/tracetransform/attribute.go b/exporters/otlp/otlptrace/internal/tracetransform/attribute.go index 12e243e04..513b57cb1 100644 --- a/exporters/otlp/otlptrace/internal/tracetransform/attribute.go +++ b/exporters/otlp/otlptrace/internal/tracetransform/attribute.go @@ -87,6 +87,10 @@ func Value(v attribute.Value) *commonpb.AnyValue { av.Value = &commonpb.AnyValue_StringValue{ StringValue: v.AsString(), } + case attribute.BYTESLICE: + av.Value = &commonpb.AnyValue_BytesValue{ + BytesValue: v.AsByteSlice(), + } case attribute.STRINGSLICE: av.Value = &commonpb.AnyValue_ArrayValue{ ArrayValue: &commonpb.ArrayValue{ diff --git a/exporters/otlp/otlptrace/internal/tracetransform/attribute_test.go b/exporters/otlp/otlptrace/internal/tracetransform/attribute_test.go index d0d1d2868..c268ff841 100644 --- a/exporters/otlp/otlptrace/internal/tracetransform/attribute_test.go +++ b/exporters/otlp/otlptrace/internal/tracetransform/attribute_test.go @@ -26,6 +26,7 @@ func TestAttributes(t *testing.T) { attribute.Int64("int64 to int64", 1234567), attribute.Float64("float64 to double", 1.61), attribute.String("string to string", "string"), + attribute.ByteSlice("bytes to bytes", []byte("bytes")), attribute.Bool("bool to bool", true), {Key: "empty to empty"}, }, @@ -62,6 +63,14 @@ func TestAttributes(t *testing.T) { }, }, }, + { + Key: "bytes to bytes", + Value: &commonpb.AnyValue{ + Value: &commonpb.AnyValue_BytesValue{ + BytesValue: []byte("bytes"), + }, + }, + }, { Key: "bool to bool", Value: &commonpb.AnyValue{ diff --git a/exporters/zipkin/model.go b/exporters/zipkin/model.go index 2854e9a17..05fec4fb3 100644 --- a/exporters/zipkin/model.go +++ b/exporters/zipkin/model.go @@ -174,6 +174,14 @@ func attributeToStringPair(kv attribute.KeyValue) (string, string) { case attribute.STRINGSLICE: data, _ := json.Marshal(kv.Value.AsStringSlice()) return string(kv.Key), string(data) + case attribute.BYTESLICE: + raw := kv.Value.AsByteSlice() + data := make([]int, len(raw)) + for i, b := range raw { + data[i] = int(b) + } + encoded, _ := json.Marshal(data) + return string(kv.Key), string(encoded) default: return string(kv.Key), kv.Value.Emit() } diff --git a/exporters/zipkin/model_test.go b/exporters/zipkin/model_test.go index 854992f26..800388d60 100644 --- a/exporters/zipkin/model_test.go +++ b/exporters/zipkin/model_test.go @@ -982,6 +982,15 @@ func TestModelConversion(t *testing.T) { require.Equal(t, expectedOutputBatch, gottenOutputBatch) } +func TestAttributeToStringPairByteSlice(t *testing.T) { + t.Parallel() + + k, v := attributeToStringPair(attribute.ByteSlice("bytes", []byte{1, 2, 3})) + + assert.Equal(t, "bytes", k) + assert.Equal(t, "[1,2,3]", v) +} + func zkmodelIDPtr(n uint64) *zkmodel.ID { id := zkmodel.ID(n) return &id diff --git a/internal/shared/otlp/otlplog/transform/attr_test.go.tmpl b/internal/shared/otlp/otlplog/transform/attr_test.go.tmpl index 290e5cfdb..7c13c68b1 100644 --- a/internal/shared/otlp/otlplog/transform/attr_test.go.tmpl +++ b/internal/shared/otlp/otlplog/transform/attr_test.go.tmpl @@ -25,6 +25,7 @@ var ( attrFloat64 = attribute.Float64("float64", 1) attrFloat64Slice = attribute.Float64Slice("float64 slice", []float64{-1, 1}) attrString = attribute.String("string", "o") + attrBytes = attribute.ByteSlice("bytes", []byte("otlp")) attrStringSlice = attribute.StringSlice("string slice", []string{"o", "n"}) attrEmpty = attribute.KeyValue{ Key: attribute.Key("empty"), @@ -53,6 +54,7 @@ var ( }, }} valStrO = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "o"}} + valAttrBytes = &cpb.AnyValue{Value: &cpb.AnyValue_BytesValue{BytesValue: []byte("otlp")}} valStrN = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "n"}} valStrSlice = &cpb.AnyValue{Value: &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ @@ -69,6 +71,7 @@ var ( kvFloat64 = &cpb.KeyValue{Key: "float64", Value: valDblOne} kvFloat64Slice = &cpb.KeyValue{Key: "float64 slice", Value: valDblSlice} kvString = &cpb.KeyValue{Key: "string", Value: valStrO} + kvAttrBytes = &cpb.KeyValue{Key: "bytes", Value: valAttrBytes} kvStringSlice = &cpb.KeyValue{Key: "string slice", Value: valStrSlice} kvEmpty = &cpb.KeyValue{Key: "empty", Value: &cpb.AnyValue{}} ) @@ -133,6 +136,11 @@ func TestAttrTransforms(t *testing.T) { []attribute.KeyValue{attrString}, []*cpb.KeyValue{kvString}, }, + { + "bytes", + []attribute.KeyValue{attrBytes}, + []*cpb.KeyValue{kvAttrBytes}, + }, { "string slice", []attribute.KeyValue{attrStringSlice}, @@ -150,6 +158,7 @@ func TestAttrTransforms(t *testing.T) { attrFloat64, attrFloat64Slice, attrString, + attrBytes, attrStringSlice, attrEmpty, }, @@ -163,6 +172,7 @@ func TestAttrTransforms(t *testing.T) { kvFloat64, kvFloat64Slice, kvString, + kvAttrBytes, kvStringSlice, kvEmpty, }, diff --git a/internal/shared/otlp/otlplog/transform/log.go.tmpl b/internal/shared/otlp/otlplog/transform/log.go.tmpl index b5a0f5b86..94826b37a 100644 --- a/internal/shared/otlp/otlplog/transform/log.go.tmpl +++ b/internal/shared/otlp/otlplog/transform/log.go.tmpl @@ -195,6 +195,10 @@ func AttrValue(v attribute.Value) *cpb.AnyValue { av.Value = &cpb.AnyValue_StringValue{ StringValue: v.AsString(), } + case attribute.BYTESLICE: + av.Value = &cpb.AnyValue_BytesValue{ + BytesValue: v.AsByteSlice(), + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl b/internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl index 8c5e30b65..030ef0b02 100644 --- a/internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl +++ b/internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl @@ -81,6 +81,10 @@ func Value(v attribute.Value) *cpb.AnyValue { av.Value = &cpb.AnyValue_StringValue{ StringValue: v.AsString(), } + case attribute.BYTESLICE: + av.Value = &cpb.AnyValue_BytesValue{ + BytesValue: v.AsByteSlice(), + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/internal/shared/otlp/otlpmetric/transform/attribute_test.go.tmpl b/internal/shared/otlp/otlpmetric/transform/attribute_test.go.tmpl index e273afba7..1db746e6c 100644 --- a/internal/shared/otlp/otlpmetric/transform/attribute_test.go.tmpl +++ b/internal/shared/otlp/otlpmetric/transform/attribute_test.go.tmpl @@ -25,6 +25,7 @@ var ( attrFloat64 = attribute.Float64("float64", 1) attrFloat64Slice = attribute.Float64Slice("float64 slice", []float64{-1, 1}) attrString = attribute.String("string", "o") + attrBytes = attribute.ByteSlice("bytes", []byte("otlp")) attrStringSlice = attribute.StringSlice("string slice", []string{"o", "n"}) attrEmpty = attribute.KeyValue{ Key: attribute.Key("empty"), @@ -53,6 +54,7 @@ var ( }, }} valStrO = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "o"}} + valBytes = &cpb.AnyValue{Value: &cpb.AnyValue_BytesValue{BytesValue: []byte("otlp")}} valStrN = &cpb.AnyValue{Value: &cpb.AnyValue_StringValue{StringValue: "n"}} valStrSlice = &cpb.AnyValue{Value: &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ @@ -69,6 +71,7 @@ var ( kvFloat64 = &cpb.KeyValue{Key: "float64", Value: valDblOne} kvFloat64Slice = &cpb.KeyValue{Key: "float64 slice", Value: valDblSlice} kvString = &cpb.KeyValue{Key: "string", Value: valStrO} + kvBytes = &cpb.KeyValue{Key: "bytes", Value: valBytes} kvStringSlice = &cpb.KeyValue{Key: "string slice", Value: valStrSlice} kvEmpty = &cpb.KeyValue{Key: "empty", Value: &cpb.AnyValue{}} ) @@ -133,6 +136,11 @@ func TestAttributeTransforms(t *testing.T) { []attribute.KeyValue{attrString}, []*cpb.KeyValue{kvString}, }, + { + "bytes", + []attribute.KeyValue{attrBytes}, + []*cpb.KeyValue{kvBytes}, + }, { "string slice", []attribute.KeyValue{attrStringSlice}, @@ -150,6 +158,7 @@ func TestAttributeTransforms(t *testing.T) { attrFloat64, attrFloat64Slice, attrString, + attrBytes, attrStringSlice, attrEmpty, }, @@ -163,6 +172,7 @@ func TestAttributeTransforms(t *testing.T) { kvFloat64, kvFloat64Slice, kvString, + kvBytes, kvStringSlice, kvEmpty, }, diff --git a/trace/auto.go b/trace/auto.go index 9316fd0ac..af402d6a8 100644 --- a/trace/auto.go +++ b/trace/auto.go @@ -314,6 +314,8 @@ func convAttrValue(value attribute.Value) telemetry.Value { case attribute.STRING: v := truncate(maxSpan.AttrValueLen, value.AsString()) return telemetry.StringValue(v) + case attribute.BYTESLICE: + return telemetry.BytesValue(value.AsByteSlice()) case attribute.BOOLSLICE: slice := value.AsBoolSlice() out := make([]telemetry.Value, 0, len(slice)) diff --git a/trace/auto_test.go b/trace/auto_test.go index f0a2aebf5..0abfe8a89 100644 --- a/trace/auto_test.go +++ b/trace/auto_test.go @@ -164,6 +164,15 @@ func TestSpanKindTransform(t *testing.T) { } } +func TestConvAttrValueBytes(t *testing.T) { + t.Parallel() + + val := convAttrValue(attribute.ByteSliceValue([]byte("bytes"))) + + assert.Equal(t, telemetry.ValueKindBytes, val.Kind()) + assert.Equal(t, []byte("bytes"), val.AsBytes()) +} + func TestTracerStartPropagatesOrigCtx(t *testing.T) { t.Parallel()