1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-08-10 22:31:50 +02:00

Remove deprecated Array from attribute package (#2235)

* Remove deprecated Array from attribute pkg

* Add changes to changelog

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
This commit is contained in:
Tyler Yahn
2021-09-10 08:51:02 -07:00
committed by GitHub
parent 360d13027e
commit ef126f5ce1
8 changed files with 9 additions and 314 deletions

View File

@@ -36,15 +36,6 @@ var (
outStrSlice []string
)
func benchmarkAny(k string, v interface{}) func(*testing.B) {
return func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.Any(k, v)
}
}
}
func benchmarkEmit(kv attribute.KeyValue) func(*testing.B) {
return func(b *testing.B) {
b.ReportAllocs()
@@ -54,23 +45,9 @@ func benchmarkEmit(kv attribute.KeyValue) func(*testing.B) {
}
}
func benchmarkArray(k string, v interface{}) func(*testing.B) {
a := attribute.Array(k, v)
return func(b *testing.B) {
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.Array(k, v)
}
})
b.Run("Emit", benchmarkEmit(a))
}
}
func BenchmarkBool(b *testing.B) {
k, v := "bool", true
kv := attribute.Bool(k, v)
array := []bool{true, false, true}
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
@@ -90,9 +67,7 @@ func BenchmarkBool(b *testing.B) {
outBool = kv.Value.AsBool()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
b.Run("Array", benchmarkArray(k, array))
}
func BenchmarkBoolSlice(b *testing.B) {
@@ -117,14 +92,12 @@ func BenchmarkBoolSlice(b *testing.B) {
outBoolSlice = kv.Value.AsBoolSlice()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
}
func BenchmarkInt(b *testing.B) {
k, v := "int", int(42)
kv := attribute.Int(k, v)
array := []int{42, -3, 12}
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
@@ -138,9 +111,7 @@ func BenchmarkInt(b *testing.B) {
outKV = attribute.Int(k, v)
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
b.Run("Array", benchmarkArray(k, array))
}
func BenchmarkIntSlice(b *testing.B) {
@@ -159,26 +130,12 @@ func BenchmarkIntSlice(b *testing.B) {
outKV = attribute.IntSlice(k, v)
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
}
func BenchmarkInt8(b *testing.B) {
b.Run("Any", benchmarkAny("int8", int8(42)))
}
func BenchmarkInt16(b *testing.B) {
b.Run("Any", benchmarkAny("int16", int16(42)))
}
func BenchmarkInt32(b *testing.B) {
b.Run("Any", benchmarkAny("int32", int32(42)))
}
func BenchmarkInt64(b *testing.B) {
k, v := "int64", int64(42)
kv := attribute.Int64(k, v)
array := []int64{42, -3, 12}
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
@@ -198,9 +155,7 @@ func BenchmarkInt64(b *testing.B) {
outInt64 = kv.Value.AsInt64()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
b.Run("Array", benchmarkArray(k, array))
}
func BenchmarkInt64Slice(b *testing.B) {
@@ -225,14 +180,12 @@ func BenchmarkInt64Slice(b *testing.B) {
outInt64Slice = kv.Value.AsInt64Slice()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
}
func BenchmarkFloat64(b *testing.B) {
k, v := "float64", float64(42)
kv := attribute.Float64(k, v)
array := []float64{42, -3, 12}
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
@@ -252,9 +205,7 @@ func BenchmarkFloat64(b *testing.B) {
outFloat64 = kv.Value.AsFloat64()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
b.Run("Array", benchmarkArray(k, array))
}
func BenchmarkFloat64Slice(b *testing.B) {
@@ -279,14 +230,12 @@ func BenchmarkFloat64Slice(b *testing.B) {
outFloat64Slice = kv.Value.AsFloat64Slice()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
}
func BenchmarkString(b *testing.B) {
k, v := "string", "42"
kv := attribute.String(k, v)
array := []string{"forty-two", "negative three", "twelve"}
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
@@ -306,9 +255,7 @@ func BenchmarkString(b *testing.B) {
outStr = kv.Value.AsString()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
b.Run("Array", benchmarkArray(k, array))
}
func BenchmarkStringSlice(b *testing.B) {
@@ -333,10 +280,5 @@ func BenchmarkStringSlice(b *testing.B) {
outStrSlice = kv.Value.AsStringSlice()
}
})
b.Run("Any", benchmarkAny(k, v))
b.Run("Emit", benchmarkEmit(kv))
}
func BenchmarkBytes(b *testing.B) {
b.Run("Any", benchmarkAny("bytes", []byte("bytes")))
}

View File

@@ -128,19 +128,6 @@ func (k Key) StringSlice(v []string) KeyValue {
}
}
// Array creates a KeyValue instance with an ARRAY Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- Array(name, value).
//
// Deprecated: Use the typed *Slice methods instead.
func (k Key) Array(v interface{}) KeyValue {
return KeyValue{
Key: k,
Value: ArrayValue(v),
}
}
// Defined returns true for non-empty keys.
func (k Key) Defined() bool {
return len(k) != 0

View File

@@ -15,9 +15,7 @@
package attribute // import "go.opentelemetry.io/otel/attribute"
import (
"encoding/json"
"fmt"
"reflect"
)
// KeyValue holds a key and value pair.
@@ -86,60 +84,3 @@ func StringSlice(k string, v []string) KeyValue {
func Stringer(k string, v fmt.Stringer) KeyValue {
return Key(k).String(v.String())
}
// Array creates a new key-value pair with a passed name and a array.
// Only arrays of primitive type are supported.
//
// Deprecated: Use the typed *Slice functions instead.
func Array(k string, v interface{}) KeyValue {
return Key(k).Array(v)
}
// Any creates a new key-value pair instance with a passed name and
// automatic type inference. This is slower, and not type-safe.
//
// Deprecated: Use the typed functions instead.
func Any(k string, value interface{}) KeyValue {
if value == nil {
return String(k, "<nil>")
}
if stringer, ok := value.(fmt.Stringer); ok {
return String(k, stringer.String())
}
rv := reflect.ValueOf(value)
switch rv.Kind() {
case reflect.Array:
rv = rv.Slice(0, rv.Len())
fallthrough
case reflect.Slice:
switch reflect.TypeOf(value).Elem().Kind() {
case reflect.Bool:
return BoolSlice(k, rv.Interface().([]bool))
case reflect.Int:
return IntSlice(k, rv.Interface().([]int))
case reflect.Int64:
return Int64Slice(k, rv.Interface().([]int64))
case reflect.Float64:
return Float64Slice(k, rv.Interface().([]float64))
case reflect.String:
return StringSlice(k, rv.Interface().([]string))
default:
return KeyValue{Key: Key(k), Value: Value{vtype: INVALID}}
}
case reflect.Bool:
return Bool(k, rv.Bool())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return Int64(k, rv.Int())
case reflect.Float64:
return Float64(k, rv.Float())
case reflect.String:
return String(k, rv.String())
}
if b, err := json.Marshal(value); b != nil && err == nil {
return String(k, string(b))
}
return String(k, fmt.Sprint(value))
}

View File

@@ -15,7 +15,6 @@
package attribute_test
import (
"strings"
"testing"
"github.com/google/go-cmp/cmp"
@@ -80,87 +79,6 @@ func TestKeyValueConstructors(t *testing.T) {
}
}
func TestAny(t *testing.T) {
builder := &strings.Builder{}
builder.WriteString("foo")
jsonifyStruct := struct {
Public string
private string
Tagged string `json:"tagName"`
Empty string
OmitEmpty string `json:",omitempty"`
Omit string `json:"-"`
}{"foo", "bar", "baz", "", "", "omitted"}
invalidStruct := struct {
N complex64
}{complex(0, 0)}
for _, testcase := range []struct {
key string
value interface{}
wantType attribute.Type
wantValue interface{}
}{
{
key: "bool type inferred",
value: true,
wantType: attribute.BOOL,
wantValue: true,
},
{
key: "int64 type inferred",
value: int64(42),
wantType: attribute.INT64,
wantValue: int64(42),
},
{
key: "float64 type inferred",
value: float64(42.1),
wantType: attribute.FLOAT64,
wantValue: 42.1,
},
{
key: "string type inferred",
value: "foo",
wantType: attribute.STRING,
wantValue: "foo",
},
{
key: "stringer type inferred",
value: builder,
wantType: attribute.STRING,
wantValue: "foo",
},
{
key: "unknown value serialized as %v",
value: nil,
wantType: attribute.STRING,
wantValue: "<nil>",
},
{
key: "JSON struct serialized correctly",
value: &jsonifyStruct,
wantType: attribute.STRING,
wantValue: `{"Public":"foo","tagName":"baz","Empty":""}`,
},
{
key: "Invalid JSON struct falls back to string",
value: &invalidStruct,
wantType: attribute.STRING,
wantValue: "&{(0+0i)}",
},
} {
t.Logf("Running test case %s", testcase.key)
keyValue := attribute.Any(testcase.key, testcase.value)
if keyValue.Value.Type() != testcase.wantType {
t.Errorf("wrong value type, got %#v, expected %#v", keyValue.Value.Type(), testcase.wantType)
}
got := keyValue.Value.AsInterface()
if diff := cmp.Diff(testcase.wantValue, got); diff != "" {
t.Errorf("+got, -want: %s", diff)
}
}
}
func TestKeyValueValid(t *testing.T) {
tests := []struct {
desc string
@@ -206,11 +124,6 @@ func TestKeyValueValid(t *testing.T) {
valid: true,
kv: attribute.String("string", ""),
},
{
desc: "non-empty key with ARRAY type Value should be valid",
valid: true,
kv: attribute.Array("array", []int{}),
},
}
for _, test := range tests {

View File

@@ -17,12 +17,11 @@ func _() {
_ = x[INT64SLICE-6]
_ = x[FLOAT64SLICE-7]
_ = x[STRINGSLICE-8]
_ = x[ARRAY-9]
}
const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICEARRAY"
const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE"
var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71, 76}
var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71}
func (i Type) String() string {
if i < 0 || i >= Type(len(_Type_index)-1) {

View File

@@ -17,7 +17,6 @@ package attribute // import "go.opentelemetry.io/otel/attribute"
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"go.opentelemetry.io/otel/internal"
@@ -55,12 +54,6 @@ const (
FLOAT64SLICE
// STRINGSLICE is a slice of strings Type Value.
STRINGSLICE
// ARRAY is an array Type Value used to store 1-dimensional slices or
// arrays of bool, int, int32, int64, uint, uint32, uint64, float,
// float32, float64, or string types.
//
// Deprecated: Use slice types instead.
ARRAY
)
// BoolValue creates a BOOL Value.
@@ -152,37 +145,6 @@ func StringSliceValue(v []string) Value {
}
}
// ArrayValue creates an ARRAY value from an array or slice.
// Only arrays or slices of bool, int, int64, float, float64, or string types are allowed.
// Specifically, arrays and slices can not contain other arrays, slices, structs, or non-standard
// types. If the passed value is not an array or slice of these types an
// INVALID value is returned.
//
// Deprecated: Use the typed *SliceValue functions instead.
func ArrayValue(v interface{}) Value {
switch reflect.TypeOf(v).Kind() {
case reflect.Array, reflect.Slice:
// get array type regardless of dimensions
typ := reflect.TypeOf(v).Elem()
kind := typ.Kind()
switch kind {
case reflect.Bool, reflect.Int, reflect.Int64,
reflect.Float64, reflect.String:
val := reflect.ValueOf(v)
length := val.Len()
frozen := reflect.Indirect(reflect.New(reflect.ArrayOf(length, typ)))
reflect.Copy(frozen, val)
return Value{
vtype: ARRAY,
slice: frozen.Interface(),
}
default:
return Value{vtype: INVALID}
}
}
return Value{vtype: INVALID}
}
// Type returns a type of the Value.
func (v Value) Type() Type {
return v.vtype
@@ -248,20 +210,11 @@ func (v Value) AsStringSlice() []string {
return nil
}
// AsArray returns the array Value as an interface{}.
//
// Deprecated: Use the typed As*Slice functions instead.
func (v Value) AsArray() interface{} {
return v.slice
}
type unknownValueType struct{}
// AsInterface returns Value's data as interface{}.
func (v Value) AsInterface() interface{} {
switch v.Type() {
case ARRAY:
return v.AsArray()
case BOOL:
return v.AsBool()
case BOOLSLICE:
@@ -285,8 +238,6 @@ func (v Value) AsInterface() interface{} {
// Emit returns a string representation of Value's data.
func (v Value) Emit() string {
switch v.Type() {
case ARRAY:
return fmt.Sprint(v.slice)
case BOOLSLICE:
return fmt.Sprint(*(v.slice.(*[]bool)))
case BOOL:

View File

@@ -15,7 +15,6 @@
package attribute_test
import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
@@ -43,12 +42,6 @@ func TestValue(t *testing.T) {
wantType: attribute.BOOLSLICE,
wantValue: []bool{true, false, true},
},
{
name: "Key.Array([]bool) correctly return key's internal bool values",
value: k.Array([]bool{true, false}).Value,
wantType: attribute.ARRAY,
wantValue: [2]bool{true, false},
},
{
name: "Key.Int64() correctly returns keys's internal int64 value",
value: k.Int64(42).Value,
@@ -61,12 +54,6 @@ func TestValue(t *testing.T) {
wantType: attribute.INT64SLICE,
wantValue: []int64{42, -3, 12},
},
{
name: "Key.Array([]int64) correctly returns keys's internal int64 values",
value: k.Array([]int64{42, 43}).Value,
wantType: attribute.ARRAY,
wantValue: [2]int64{42, 43},
},
{
name: "Key.Int() correctly returns keys's internal signed integral value",
value: k.Int(42).Value,
@@ -79,12 +66,6 @@ func TestValue(t *testing.T) {
wantType: attribute.INT64SLICE,
wantValue: []int64{42, -3, 12},
},
{
name: "Key.Array([]int) correctly returns keys's internal signed integral values",
value: k.Array([]int{42, 43}).Value,
wantType: attribute.ARRAY,
wantValue: [2]int{42, 43},
},
{
name: "Key.Float64() correctly returns keys's internal float64 value",
value: k.Float64(42.1).Value,
@@ -97,12 +78,6 @@ func TestValue(t *testing.T) {
wantType: attribute.FLOAT64SLICE,
wantValue: []float64{42, -3, 12},
},
{
name: "Key.Array([]float64) correctly returns keys's internal float64 values",
value: k.Array([]float64{42, 43}).Value,
wantType: attribute.ARRAY,
wantValue: [2]float64{42, 43},
},
{
name: "Key.String() correctly returns keys's internal string value",
value: k.String("foo").Value,
@@ -115,18 +90,6 @@ func TestValue(t *testing.T) {
wantType: attribute.STRINGSLICE,
wantValue: []string{"forty-two", "negative three", "twelve"},
},
{
name: "Key.Array([]string) correctly return key's internal string values",
value: k.Array([]string{"foo", "bar"}).Value,
wantType: attribute.ARRAY,
wantValue: [2]string{"foo", "bar"},
},
{
name: "Key.Array([][]int) refuses to create multi-dimensional array",
value: k.Array([][]int{{1, 2}, {3, 4}}).Value,
wantType: attribute.INVALID,
wantValue: nil,
},
} {
t.Logf("Running test case %s", testcase.name)
if testcase.value.Type() != testcase.wantType {
@@ -141,11 +104,3 @@ func TestValue(t *testing.T) {
}
}
}
func TestAsArrayValue(t *testing.T) {
v := attribute.ArrayValue([]int{1, 2, 3}).AsArray()
// Ensure the returned dynamic type is stable.
if got, want := reflect.TypeOf(v).Kind(), reflect.Array; got != want {
t.Errorf("AsArray() returned %T, want %T", got, want)
}
}