You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-07-17 01:12:45 +02:00
Deprecate Array attribute in favor of *Slice types (#2162)
* Deprecate Array attribute in favor of *Slice types * Use new attr types in Jaeger exporter * Use slice attr types in otlpmetric * Use slice attr types in otlptrace * Use slice attr types in zipkin exporter * Remove array attr test from deprectated oteltest func * Use StringSlice for cmd arg resource attr * Add changes to the changelog * Remove use of deprecated Array func
This commit is contained in:
@ -11,6 +11,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added `ErrorHandlerFunc` to use a function as an `"go.opentelemetry.io/otel".ErrorHandler`. (#2149)
|
- Added `ErrorHandlerFunc` to use a function as an `"go.opentelemetry.io/otel".ErrorHandler`. (#2149)
|
||||||
|
- Added typed slice attribute types and functionality to the `go.opentelemetry.io/otel/attribute` package to replace the existing array type and functions. (#2162)
|
||||||
|
- `BoolSlice`, `IntSlice`, `Int64Slice`, `Float64Slice`, and `StringSlice` replace the use of the `Array` function in the package.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -21,6 +23,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
- The `go.opentelemetry.io/otel/bridge/opencensus/utils` package is deprecated.
|
- The `go.opentelemetry.io/otel/bridge/opencensus/utils` package is deprecated.
|
||||||
All functionality from this package now exists in the `go.opentelemetry.io/otel/bridge/opencensus` package.
|
All functionality from this package now exists in the `go.opentelemetry.io/otel/bridge/opencensus` package.
|
||||||
The functions from that package should be used instead. (#2166)
|
The functions from that package should be used instead. (#2166)
|
||||||
|
- The `"go.opentelemetry.io/otel/attribute".Array` function and the related `ARRAY` value type is deprecated.
|
||||||
|
Use the typed `*Slice` functions and types added to the package instead. (#2162)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -27,9 +27,13 @@ var (
|
|||||||
outKV attribute.KeyValue
|
outKV attribute.KeyValue
|
||||||
|
|
||||||
outBool bool
|
outBool bool
|
||||||
|
outBoolSlice []bool
|
||||||
outInt64 int64
|
outInt64 int64
|
||||||
|
outInt64Slice []int64
|
||||||
outFloat64 float64
|
outFloat64 float64
|
||||||
|
outFloat64Slice []float64
|
||||||
outStr string
|
outStr string
|
||||||
|
outStrSlice []string
|
||||||
)
|
)
|
||||||
|
|
||||||
func benchmarkAny(k string, v interface{}) func(*testing.B) {
|
func benchmarkAny(k string, v interface{}) func(*testing.B) {
|
||||||
@ -91,6 +95,32 @@ func BenchmarkBool(b *testing.B) {
|
|||||||
b.Run("Array", benchmarkArray(k, array))
|
b.Run("Array", benchmarkArray(k, array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkBoolSlice(b *testing.B) {
|
||||||
|
k, v := "bool slice", []bool{true, false, true}
|
||||||
|
kv := attribute.BoolSlice(k, v)
|
||||||
|
|
||||||
|
b.Run("Value", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outV = attribute.BoolSliceValue(v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("KeyValue", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outKV = attribute.BoolSlice(k, v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("AsBoolSlice", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outBoolSlice = kv.Value.AsBoolSlice()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Any", benchmarkAny(k, v))
|
||||||
|
b.Run("Emit", benchmarkEmit(kv))
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkInt(b *testing.B) {
|
func BenchmarkInt(b *testing.B) {
|
||||||
k, v := "int", int(42)
|
k, v := "int", int(42)
|
||||||
kv := attribute.Int(k, v)
|
kv := attribute.Int(k, v)
|
||||||
@ -113,6 +143,26 @@ func BenchmarkInt(b *testing.B) {
|
|||||||
b.Run("Array", benchmarkArray(k, array))
|
b.Run("Array", benchmarkArray(k, array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkIntSlice(b *testing.B) {
|
||||||
|
k, v := "int slice", []int{42, -3, 12}
|
||||||
|
kv := attribute.IntSlice(k, v)
|
||||||
|
|
||||||
|
b.Run("Value", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outV = attribute.IntSliceValue(v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("KeyValue", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outKV = attribute.IntSlice(k, v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Any", benchmarkAny(k, v))
|
||||||
|
b.Run("Emit", benchmarkEmit(kv))
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkInt8(b *testing.B) {
|
func BenchmarkInt8(b *testing.B) {
|
||||||
b.Run("Any", benchmarkAny("int8", int8(42)))
|
b.Run("Any", benchmarkAny("int8", int8(42)))
|
||||||
}
|
}
|
||||||
@ -153,6 +203,32 @@ func BenchmarkInt64(b *testing.B) {
|
|||||||
b.Run("Array", benchmarkArray(k, array))
|
b.Run("Array", benchmarkArray(k, array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkInt64Slice(b *testing.B) {
|
||||||
|
k, v := "int64 slice", []int64{42, -3, 12}
|
||||||
|
kv := attribute.Int64Slice(k, v)
|
||||||
|
|
||||||
|
b.Run("Value", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outV = attribute.Int64SliceValue(v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("KeyValue", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outKV = attribute.Int64Slice(k, v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("AsInt64Slice", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outInt64Slice = kv.Value.AsInt64Slice()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Any", benchmarkAny(k, v))
|
||||||
|
b.Run("Emit", benchmarkEmit(kv))
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkFloat64(b *testing.B) {
|
func BenchmarkFloat64(b *testing.B) {
|
||||||
k, v := "float64", float64(42)
|
k, v := "float64", float64(42)
|
||||||
kv := attribute.Float64(k, v)
|
kv := attribute.Float64(k, v)
|
||||||
@ -181,6 +257,32 @@ func BenchmarkFloat64(b *testing.B) {
|
|||||||
b.Run("Array", benchmarkArray(k, array))
|
b.Run("Array", benchmarkArray(k, array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkFloat64Slice(b *testing.B) {
|
||||||
|
k, v := "float64 slice", []float64{42, -3, 12}
|
||||||
|
kv := attribute.Float64Slice(k, v)
|
||||||
|
|
||||||
|
b.Run("Value", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outV = attribute.Float64SliceValue(v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("KeyValue", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outKV = attribute.Float64Slice(k, v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("AsFloat64Slice", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outFloat64Slice = kv.Value.AsFloat64Slice()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Any", benchmarkAny(k, v))
|
||||||
|
b.Run("Emit", benchmarkEmit(kv))
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkString(b *testing.B) {
|
func BenchmarkString(b *testing.B) {
|
||||||
k, v := "string", "42"
|
k, v := "string", "42"
|
||||||
kv := attribute.String(k, v)
|
kv := attribute.String(k, v)
|
||||||
@ -209,12 +311,32 @@ func BenchmarkString(b *testing.B) {
|
|||||||
b.Run("Array", benchmarkArray(k, array))
|
b.Run("Array", benchmarkArray(k, array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkStringSlice(b *testing.B) {
|
||||||
|
k, v := "float64 slice", []string{"forty-two", "negative three", "twelve"}
|
||||||
|
kv := attribute.StringSlice(k, v)
|
||||||
|
|
||||||
|
b.Run("Value", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outV = attribute.StringSliceValue(v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("KeyValue", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outKV = attribute.StringSlice(k, v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("AsStringSlice", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
outStrSlice = kv.Value.AsStringSlice()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Any", benchmarkAny(k, v))
|
||||||
|
b.Run("Emit", benchmarkEmit(kv))
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkBytes(b *testing.B) {
|
func BenchmarkBytes(b *testing.B) {
|
||||||
b.Run("Any", benchmarkAny("bytes", []byte("bytes")))
|
b.Run("Any", benchmarkAny("bytes", []byte("bytes")))
|
||||||
}
|
}
|
||||||
|
|
||||||
type test struct{}
|
|
||||||
|
|
||||||
func BenchmarkStruct(b *testing.B) {
|
|
||||||
b.Run("Any", benchmarkAny("struct", test{}))
|
|
||||||
}
|
|
||||||
|
@ -29,6 +29,17 @@ func (k Key) Bool(v bool) KeyValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BoolSlice creates a KeyValue instance with a BOOLSLICE Value.
|
||||||
|
//
|
||||||
|
// If creating both a key and value at the same time, use the provided
|
||||||
|
// convenience function instead -- BoolSlice(name, value).
|
||||||
|
func (k Key) BoolSlice(v []bool) KeyValue {
|
||||||
|
return KeyValue{
|
||||||
|
Key: k,
|
||||||
|
Value: BoolSliceValue(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Int creates a KeyValue instance with an INT64 Value.
|
// Int creates a KeyValue instance with an INT64 Value.
|
||||||
//
|
//
|
||||||
// If creating both a key and value at the same time, use the provided
|
// If creating both a key and value at the same time, use the provided
|
||||||
@ -40,6 +51,17 @@ func (k Key) Int(v int) KeyValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IntSlice creates a KeyValue instance with an INT64SLICE Value.
|
||||||
|
//
|
||||||
|
// If creating both a key and value at the same time, use the provided
|
||||||
|
// convenience function instead -- IntSlice(name, value).
|
||||||
|
func (k Key) IntSlice(v []int) KeyValue {
|
||||||
|
return KeyValue{
|
||||||
|
Key: k,
|
||||||
|
Value: IntSliceValue(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Int64 creates a KeyValue instance with an INT64 Value.
|
// Int64 creates a KeyValue instance with an INT64 Value.
|
||||||
//
|
//
|
||||||
// If creating both a key and value at the same time, use the provided
|
// If creating both a key and value at the same time, use the provided
|
||||||
@ -51,6 +73,17 @@ func (k Key) Int64(v int64) KeyValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Int64Slice creates a KeyValue instance with an INT64SLICE Value.
|
||||||
|
//
|
||||||
|
// If creating both a key and value at the same time, use the provided
|
||||||
|
// convenience function instead -- Int64Slice(name, value).
|
||||||
|
func (k Key) Int64Slice(v []int64) KeyValue {
|
||||||
|
return KeyValue{
|
||||||
|
Key: k,
|
||||||
|
Value: Int64SliceValue(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Float64 creates a KeyValue instance with a FLOAT64 Value.
|
// Float64 creates a KeyValue instance with a FLOAT64 Value.
|
||||||
//
|
//
|
||||||
// If creating both a key and value at the same time, use the provided
|
// If creating both a key and value at the same time, use the provided
|
||||||
@ -62,6 +95,17 @@ func (k Key) Float64(v float64) KeyValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value.
|
||||||
|
//
|
||||||
|
// If creating both a key and value at the same time, use the provided
|
||||||
|
// convenience function instead -- Float64(name, value).
|
||||||
|
func (k Key) Float64Slice(v []float64) KeyValue {
|
||||||
|
return KeyValue{
|
||||||
|
Key: k,
|
||||||
|
Value: Float64SliceValue(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// String creates a KeyValue instance with a STRING Value.
|
// String creates a KeyValue instance with a STRING Value.
|
||||||
//
|
//
|
||||||
// If creating both a key and value at the same time, use the provided
|
// If creating both a key and value at the same time, use the provided
|
||||||
@ -73,10 +117,23 @@ func (k Key) String(v string) KeyValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringSlice creates a KeyValue instance with a STRINGSLICE Value.
|
||||||
|
//
|
||||||
|
// If creating both a key and value at the same time, use the provided
|
||||||
|
// convenience function instead -- StringSlice(name, value).
|
||||||
|
func (k Key) StringSlice(v []string) KeyValue {
|
||||||
|
return KeyValue{
|
||||||
|
Key: k,
|
||||||
|
Value: StringSliceValue(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Array creates a KeyValue instance with an ARRAY Value.
|
// Array creates a KeyValue instance with an ARRAY Value.
|
||||||
//
|
//
|
||||||
// If creating both a key and value at the same time, use the provided
|
// If creating both a key and value at the same time, use the provided
|
||||||
// convenience function instead -- Array(name, value).
|
// convenience function instead -- Array(name, value).
|
||||||
|
//
|
||||||
|
// Deprecated: Use the typed *Slice methods instead.
|
||||||
func (k Key) Array(v interface{}) KeyValue {
|
func (k Key) Array(v interface{}) KeyValue {
|
||||||
return KeyValue{
|
return KeyValue{
|
||||||
Key: k,
|
Key: k,
|
||||||
|
@ -36,26 +36,51 @@ func Bool(k string, v bool) KeyValue {
|
|||||||
return Key(k).Bool(v)
|
return Key(k).Bool(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BoolSlice creates a KeyValue with a BOOLSLICE Value type.
|
||||||
|
func BoolSlice(k string, v []bool) KeyValue {
|
||||||
|
return Key(k).BoolSlice(v)
|
||||||
|
}
|
||||||
|
|
||||||
// Int creates a KeyValue with an INT64 Value type.
|
// Int creates a KeyValue with an INT64 Value type.
|
||||||
func Int(k string, v int) KeyValue {
|
func Int(k string, v int) KeyValue {
|
||||||
return Key(k).Int(v)
|
return Key(k).Int(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64 creates a KeyValue with a INT64 Value type.
|
// IntSlice creates a KeyValue with an INT64SLICE Value type.
|
||||||
|
func IntSlice(k string, v []int) KeyValue {
|
||||||
|
return Key(k).IntSlice(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 creates a KeyValue with an INT64 Value type.
|
||||||
func Int64(k string, v int64) KeyValue {
|
func Int64(k string, v int64) KeyValue {
|
||||||
return Key(k).Int64(v)
|
return Key(k).Int64(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Int64Slice creates a KeyValue with an INT64SLICE Value type.
|
||||||
|
func Int64Slice(k string, v []int64) KeyValue {
|
||||||
|
return Key(k).Int64Slice(v)
|
||||||
|
}
|
||||||
|
|
||||||
// Float64 creates a KeyValue with a FLOAT64 Value type.
|
// Float64 creates a KeyValue with a FLOAT64 Value type.
|
||||||
func Float64(k string, v float64) KeyValue {
|
func Float64(k string, v float64) KeyValue {
|
||||||
return Key(k).Float64(v)
|
return Key(k).Float64(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type.
|
||||||
|
func Float64Slice(k string, v []float64) KeyValue {
|
||||||
|
return Key(k).Float64Slice(v)
|
||||||
|
}
|
||||||
|
|
||||||
// String creates a KeyValue with a STRING Value type.
|
// String creates a KeyValue with a STRING Value type.
|
||||||
func String(k, v string) KeyValue {
|
func String(k, v string) KeyValue {
|
||||||
return Key(k).String(v)
|
return Key(k).String(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringSlice creates a KeyValue with a STRINGSLICE Value type.
|
||||||
|
func StringSlice(k string, v []string) KeyValue {
|
||||||
|
return Key(k).StringSlice(v)
|
||||||
|
}
|
||||||
|
|
||||||
// Stringer creates a new key-value pair with a passed name and a string
|
// Stringer creates a new key-value pair with a passed name and a string
|
||||||
// value generated by the passed Stringer interface.
|
// value generated by the passed Stringer interface.
|
||||||
func Stringer(k string, v fmt.Stringer) KeyValue {
|
func Stringer(k string, v fmt.Stringer) KeyValue {
|
||||||
@ -64,6 +89,8 @@ func Stringer(k string, v fmt.Stringer) KeyValue {
|
|||||||
|
|
||||||
// Array creates a new key-value pair with a passed name and a array.
|
// Array creates a new key-value pair with a passed name and a array.
|
||||||
// Only arrays of primitive type are supported.
|
// Only arrays of primitive type are supported.
|
||||||
|
//
|
||||||
|
// Deprecated: Use the typed *Slice functions instead.
|
||||||
func Array(k string, v interface{}) KeyValue {
|
func Array(k string, v interface{}) KeyValue {
|
||||||
return Key(k).Array(v)
|
return Key(k).Array(v)
|
||||||
}
|
}
|
||||||
@ -82,8 +109,24 @@ func Any(k string, value interface{}) KeyValue {
|
|||||||
rv := reflect.ValueOf(value)
|
rv := reflect.ValueOf(value)
|
||||||
|
|
||||||
switch rv.Kind() {
|
switch rv.Kind() {
|
||||||
case reflect.Array, reflect.Slice:
|
case reflect.Array:
|
||||||
return Array(k, value)
|
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:
|
case reflect.Bool:
|
||||||
return Bool(k, rv.Bool())
|
return Bool(k, rv.Bool())
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
@ -13,12 +13,16 @@ func _() {
|
|||||||
_ = x[INT64-2]
|
_ = x[INT64-2]
|
||||||
_ = x[FLOAT64-3]
|
_ = x[FLOAT64-3]
|
||||||
_ = x[STRING-4]
|
_ = x[STRING-4]
|
||||||
_ = x[ARRAY-5]
|
_ = x[BOOLSLICE-5]
|
||||||
|
_ = x[INT64SLICE-6]
|
||||||
|
_ = x[FLOAT64SLICE-7]
|
||||||
|
_ = x[STRINGSLICE-8]
|
||||||
|
_ = x[ARRAY-9]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGARRAY"
|
const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICEARRAY"
|
||||||
|
|
||||||
var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 34}
|
var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71, 76}
|
||||||
|
|
||||||
func (i Type) String() string {
|
func (i Type) String() string {
|
||||||
if i < 0 || i >= Type(len(_Type_index)-1) {
|
if i < 0 || i >= Type(len(_Type_index)-1) {
|
||||||
|
@ -33,9 +33,7 @@ type Value struct {
|
|||||||
vtype Type
|
vtype Type
|
||||||
numeric uint64
|
numeric uint64
|
||||||
stringly string
|
stringly string
|
||||||
// TODO Lazy value type?
|
slice interface{}
|
||||||
|
|
||||||
array interface{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -49,9 +47,19 @@ const (
|
|||||||
FLOAT64
|
FLOAT64
|
||||||
// STRING is a string Type Value.
|
// STRING is a string Type Value.
|
||||||
STRING
|
STRING
|
||||||
|
// BOOLSLICE is a slice of booleans Type Value.
|
||||||
|
BOOLSLICE
|
||||||
|
// INT64SLICE is a slice of 64-bit signed integral numbers Type Value.
|
||||||
|
INT64SLICE
|
||||||
|
// FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value.
|
||||||
|
FLOAT64SLICE
|
||||||
|
// STRINGSLICE is a slice of strings Type Value.
|
||||||
|
STRINGSLICE
|
||||||
// ARRAY is an array Type Value used to store 1-dimensional slices or
|
// ARRAY is an array Type Value used to store 1-dimensional slices or
|
||||||
// arrays of bool, int, int32, int64, uint, uint32, uint64, float,
|
// arrays of bool, int, int32, int64, uint, uint32, uint64, float,
|
||||||
// float32, float64, or string types.
|
// float32, float64, or string types.
|
||||||
|
//
|
||||||
|
// Deprecated: Use slice types instead.
|
||||||
ARRAY
|
ARRAY
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -63,11 +71,33 @@ func BoolValue(v bool) Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BoolSliceValue creates a BOOLSLICE Value.
|
||||||
|
func BoolSliceValue(v []bool) Value {
|
||||||
|
cp := make([]bool, len(v))
|
||||||
|
copy(cp, v)
|
||||||
|
return Value{
|
||||||
|
vtype: BOOLSLICE,
|
||||||
|
slice: cp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IntValue creates an INT64 Value.
|
// IntValue creates an INT64 Value.
|
||||||
func IntValue(v int) Value {
|
func IntValue(v int) Value {
|
||||||
return Int64Value(int64(v))
|
return Int64Value(int64(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IntSliceValue creates an INTSLICE Value.
|
||||||
|
func IntSliceValue(v []int) Value {
|
||||||
|
cp := make([]int64, 0, len(v))
|
||||||
|
for _, i := range v {
|
||||||
|
cp = append(cp, int64(i))
|
||||||
|
}
|
||||||
|
return Value{
|
||||||
|
vtype: INT64SLICE,
|
||||||
|
slice: cp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Int64Value creates an INT64 Value.
|
// Int64Value creates an INT64 Value.
|
||||||
func Int64Value(v int64) Value {
|
func Int64Value(v int64) Value {
|
||||||
return Value{
|
return Value{
|
||||||
@ -76,6 +106,16 @@ func Int64Value(v int64) Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Int64SliceValue creates an INT64SLICE Value.
|
||||||
|
func Int64SliceValue(v []int64) Value {
|
||||||
|
cp := make([]int64, len(v))
|
||||||
|
copy(cp, v)
|
||||||
|
return Value{
|
||||||
|
vtype: INT64SLICE,
|
||||||
|
slice: cp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Float64Value creates a FLOAT64 Value.
|
// Float64Value creates a FLOAT64 Value.
|
||||||
func Float64Value(v float64) Value {
|
func Float64Value(v float64) Value {
|
||||||
return Value{
|
return Value{
|
||||||
@ -84,6 +124,16 @@ func Float64Value(v float64) Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Float64SliceValue creates a FLOAT64SLICE Value.
|
||||||
|
func Float64SliceValue(v []float64) Value {
|
||||||
|
cp := make([]float64, len(v))
|
||||||
|
copy(cp, v)
|
||||||
|
return Value{
|
||||||
|
vtype: FLOAT64SLICE,
|
||||||
|
slice: cp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// StringValue creates a STRING Value.
|
// StringValue creates a STRING Value.
|
||||||
func StringValue(v string) Value {
|
func StringValue(v string) Value {
|
||||||
return Value{
|
return Value{
|
||||||
@ -92,11 +142,23 @@ func StringValue(v string) Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringSliceValue creates a STRINGSLICE Value.
|
||||||
|
func StringSliceValue(v []string) Value {
|
||||||
|
cp := make([]string, len(v))
|
||||||
|
copy(cp, v)
|
||||||
|
return Value{
|
||||||
|
vtype: STRINGSLICE,
|
||||||
|
slice: cp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ArrayValue creates an ARRAY value from an array or slice.
|
// 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.
|
// 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
|
// 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
|
// types. If the passed value is not an array or slice of these types an
|
||||||
// INVALID value is returned.
|
// INVALID value is returned.
|
||||||
|
//
|
||||||
|
// Deprecated: Use the typed *SliceValue functions instead.
|
||||||
func ArrayValue(v interface{}) Value {
|
func ArrayValue(v interface{}) Value {
|
||||||
switch reflect.TypeOf(v).Kind() {
|
switch reflect.TypeOf(v).Kind() {
|
||||||
case reflect.Array, reflect.Slice:
|
case reflect.Array, reflect.Slice:
|
||||||
@ -112,7 +174,7 @@ func ArrayValue(v interface{}) Value {
|
|||||||
reflect.Copy(frozen, val)
|
reflect.Copy(frozen, val)
|
||||||
return Value{
|
return Value{
|
||||||
vtype: ARRAY,
|
vtype: ARRAY,
|
||||||
array: frozen.Interface(),
|
slice: frozen.Interface(),
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return Value{vtype: INVALID}
|
return Value{vtype: INVALID}
|
||||||
@ -132,27 +194,65 @@ func (v Value) AsBool() bool {
|
|||||||
return internal.RawToBool(v.numeric)
|
return internal.RawToBool(v.numeric)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsBoolSlice returns the []bool value. Make sure that the Value's type is
|
||||||
|
// BOOLSLICE.
|
||||||
|
func (v Value) AsBoolSlice() []bool {
|
||||||
|
if s, ok := v.slice.([]bool); ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AsInt64 returns the int64 value. Make sure that the Value's type is
|
// AsInt64 returns the int64 value. Make sure that the Value's type is
|
||||||
// INT64.
|
// INT64.
|
||||||
func (v Value) AsInt64() int64 {
|
func (v Value) AsInt64() int64 {
|
||||||
return internal.RawToInt64(v.numeric)
|
return internal.RawToInt64(v.numeric)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsInt64Slice returns the []int64 value. Make sure that the Value's type is
|
||||||
|
// INT64SLICE.
|
||||||
|
func (v Value) AsInt64Slice() []int64 {
|
||||||
|
if s, ok := v.slice.([]int64); ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AsFloat64 returns the float64 value. Make sure that the Value's
|
// AsFloat64 returns the float64 value. Make sure that the Value's
|
||||||
// type is FLOAT64.
|
// type is FLOAT64.
|
||||||
func (v Value) AsFloat64() float64 {
|
func (v Value) AsFloat64() float64 {
|
||||||
return internal.RawToFloat64(v.numeric)
|
return internal.RawToFloat64(v.numeric)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is
|
||||||
|
// INT64SLICE.
|
||||||
|
func (v Value) AsFloat64Slice() []float64 {
|
||||||
|
if s, ok := v.slice.([]float64); ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AsString returns the string value. Make sure that the Value's type
|
// AsString returns the string value. Make sure that the Value's type
|
||||||
// is STRING.
|
// is STRING.
|
||||||
func (v Value) AsString() string {
|
func (v Value) AsString() string {
|
||||||
return v.stringly
|
return v.stringly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsStringSlice returns the []string value. Make sure that the Value's type is
|
||||||
|
// INT64SLICE.
|
||||||
|
func (v Value) AsStringSlice() []string {
|
||||||
|
if s, ok := v.slice.([]string); ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AsArray returns the array Value as an interface{}.
|
// AsArray returns the array Value as an interface{}.
|
||||||
|
//
|
||||||
|
// Deprecated: Use the typed As*Slice functions instead.
|
||||||
func (v Value) AsArray() interface{} {
|
func (v Value) AsArray() interface{} {
|
||||||
return v.array
|
return v.slice
|
||||||
}
|
}
|
||||||
|
|
||||||
type unknownValueType struct{}
|
type unknownValueType struct{}
|
||||||
@ -164,12 +264,20 @@ func (v Value) AsInterface() interface{} {
|
|||||||
return v.AsArray()
|
return v.AsArray()
|
||||||
case BOOL:
|
case BOOL:
|
||||||
return v.AsBool()
|
return v.AsBool()
|
||||||
|
case BOOLSLICE:
|
||||||
|
return v.AsBoolSlice()
|
||||||
case INT64:
|
case INT64:
|
||||||
return v.AsInt64()
|
return v.AsInt64()
|
||||||
|
case INT64SLICE:
|
||||||
|
return v.AsInt64Slice()
|
||||||
case FLOAT64:
|
case FLOAT64:
|
||||||
return v.AsFloat64()
|
return v.AsFloat64()
|
||||||
|
case FLOAT64SLICE:
|
||||||
|
return v.AsFloat64Slice()
|
||||||
case STRING:
|
case STRING:
|
||||||
return v.stringly
|
return v.stringly
|
||||||
|
case STRINGSLICE:
|
||||||
|
return v.AsStringSlice()
|
||||||
}
|
}
|
||||||
return unknownValueType{}
|
return unknownValueType{}
|
||||||
}
|
}
|
||||||
@ -177,8 +285,8 @@ func (v Value) AsInterface() interface{} {
|
|||||||
// Emit returns a string representation of Value's data.
|
// Emit returns a string representation of Value's data.
|
||||||
func (v Value) Emit() string {
|
func (v Value) Emit() string {
|
||||||
switch v.Type() {
|
switch v.Type() {
|
||||||
case ARRAY:
|
case ARRAY, BOOLSLICE, INT64SLICE, FLOAT64SLICE, STRINGSLICE:
|
||||||
return fmt.Sprint(v.array)
|
return fmt.Sprint(v.slice)
|
||||||
case BOOL:
|
case BOOL:
|
||||||
return strconv.FormatBool(v.AsBool())
|
return strconv.FormatBool(v.AsBool())
|
||||||
case INT64:
|
case INT64:
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
|
|
||||||
func TestValue(t *testing.T) {
|
func TestValue(t *testing.T) {
|
||||||
k := attribute.Key("test")
|
k := attribute.Key("test")
|
||||||
bli := getBitlessInfo(42)
|
|
||||||
for _, testcase := range []struct {
|
for _, testcase := range []struct {
|
||||||
name string
|
name string
|
||||||
value attribute.Value
|
value attribute.Value
|
||||||
@ -38,6 +37,12 @@ func TestValue(t *testing.T) {
|
|||||||
wantType: attribute.BOOL,
|
wantType: attribute.BOOL,
|
||||||
wantValue: true,
|
wantValue: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Key.BoolSlice() correctly returns keys's internal []bool value",
|
||||||
|
value: k.BoolSlice([]bool{true, false, true}).Value,
|
||||||
|
wantType: attribute.BOOLSLICE,
|
||||||
|
wantValue: []bool{true, false, true},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Key.Array([]bool) correctly return key's internal bool values",
|
name: "Key.Array([]bool) correctly return key's internal bool values",
|
||||||
value: k.Array([]bool{true, false}).Value,
|
value: k.Array([]bool{true, false}).Value,
|
||||||
@ -51,22 +56,10 @@ func TestValue(t *testing.T) {
|
|||||||
wantValue: int64(42),
|
wantValue: int64(42),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Key.Float64() correctly returns keys's internal float64 value",
|
name: "Key.Int64Slice() correctly returns keys's internal []int64 value",
|
||||||
value: k.Float64(42.1).Value,
|
value: k.Int64Slice([]int64{42, -3, 12}).Value,
|
||||||
wantType: attribute.FLOAT64,
|
wantType: attribute.INT64SLICE,
|
||||||
wantValue: 42.1,
|
wantValue: []int64{42, -3, 12},
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Key.String() correctly returns keys's internal string value",
|
|
||||||
value: k.String("foo").Value,
|
|
||||||
wantType: attribute.STRING,
|
|
||||||
wantValue: "foo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Key.Int() correctly returns keys's internal signed integral value",
|
|
||||||
value: k.Int(bli.intValue).Value,
|
|
||||||
wantType: bli.signedType,
|
|
||||||
wantValue: bli.signedValue,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Key.Array([]int64) correctly returns keys's internal int64 values",
|
name: "Key.Array([]int64) correctly returns keys's internal int64 values",
|
||||||
@ -75,16 +68,16 @@ func TestValue(t *testing.T) {
|
|||||||
wantValue: [2]int64{42, 43},
|
wantValue: [2]int64{42, 43},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Key.Array([]float64) correctly returns keys's internal float64 values",
|
name: "Key.Int() correctly returns keys's internal signed integral value",
|
||||||
value: k.Array([]float64{42, 43}).Value,
|
value: k.Int(42).Value,
|
||||||
wantType: attribute.ARRAY,
|
wantType: attribute.INT64,
|
||||||
wantValue: [2]float64{42, 43},
|
wantValue: int64(42),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Key.Array([]string) correctly return key's internal string values",
|
name: "Key.IntSlice() correctly returns keys's internal []int64 value",
|
||||||
value: k.Array([]string{"foo", "bar"}).Value,
|
value: k.IntSlice([]int{42, -3, 12}).Value,
|
||||||
wantType: attribute.ARRAY,
|
wantType: attribute.INT64SLICE,
|
||||||
wantValue: [2]string{"foo", "bar"},
|
wantValue: []int64{42, -3, 12},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Key.Array([]int) correctly returns keys's internal signed integral values",
|
name: "Key.Array([]int) correctly returns keys's internal signed integral values",
|
||||||
@ -92,6 +85,42 @@ func TestValue(t *testing.T) {
|
|||||||
wantType: attribute.ARRAY,
|
wantType: attribute.ARRAY,
|
||||||
wantValue: [2]int{42, 43},
|
wantValue: [2]int{42, 43},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Key.Float64() correctly returns keys's internal float64 value",
|
||||||
|
value: k.Float64(42.1).Value,
|
||||||
|
wantType: attribute.FLOAT64,
|
||||||
|
wantValue: 42.1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Key.Float64Slice() correctly returns keys's internal []float64 value",
|
||||||
|
value: k.Float64Slice([]float64{42, -3, 12}).Value,
|
||||||
|
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,
|
||||||
|
wantType: attribute.STRING,
|
||||||
|
wantValue: "foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Key.StringSlice() correctly returns keys's internal []string value",
|
||||||
|
value: k.StringSlice([]string{"forty-two", "negative three", "twelve"}).Value,
|
||||||
|
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",
|
name: "Key.Array([][]int) refuses to create multi-dimensional array",
|
||||||
value: k.Array([][]int{{1, 2}, {3, 4}}).Value,
|
value: k.Array([][]int{{1, 2}, {3, 4}}).Value,
|
||||||
@ -113,22 +142,6 @@ func TestValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type bitlessInfo struct {
|
|
||||||
intValue int
|
|
||||||
uintValue uint
|
|
||||||
signedType attribute.Type
|
|
||||||
signedValue interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBitlessInfo(i int) bitlessInfo {
|
|
||||||
return bitlessInfo{
|
|
||||||
intValue: i,
|
|
||||||
uintValue: uint(i),
|
|
||||||
signedType: attribute.INT64,
|
|
||||||
signedValue: int64(i),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAsArrayValue(t *testing.T) {
|
func TestAsArrayValue(t *testing.T) {
|
||||||
v := attribute.ArrayValue([]int{1, 2, 3}).AsArray()
|
v := attribute.ArrayValue([]int{1, 2, 3}).AsArray()
|
||||||
// Ensure the returned dynamic type is stable.
|
// Ensure the returned dynamic type is stable.
|
||||||
|
@ -248,8 +248,11 @@ func keyValueToTag(keyValue attribute.KeyValue) *gen.Tag {
|
|||||||
VDouble: &f,
|
VDouble: &f,
|
||||||
VType: gen.TagType_DOUBLE,
|
VType: gen.TagType_DOUBLE,
|
||||||
}
|
}
|
||||||
case attribute.ARRAY:
|
case attribute.BOOLSLICE,
|
||||||
json, _ := json.Marshal(keyValue.Value.AsArray())
|
attribute.INT64SLICE,
|
||||||
|
attribute.FLOAT64SLICE,
|
||||||
|
attribute.STRINGSLICE:
|
||||||
|
json, _ := json.Marshal(keyValue.Value.AsInterface())
|
||||||
a := (string)(json)
|
a := (string)(json)
|
||||||
tag = &gen.Tag{
|
tag = &gen.Tag{
|
||||||
Key: string(keyValue.Key),
|
Key: string(keyValue.Key),
|
||||||
|
@ -323,7 +323,7 @@ func Test_spanSnapshotToThrift(t *testing.T) {
|
|||||||
StartTime: now,
|
StartTime: now,
|
||||||
EndTime: now,
|
EndTime: now,
|
||||||
Attributes: []attribute.KeyValue{
|
Attributes: []attribute.KeyValue{
|
||||||
attribute.Array("arr", []int{0, 1, 2, 3}),
|
attribute.IntSlice("arr", []int{0, 1, 2, 3}),
|
||||||
},
|
},
|
||||||
Status: sdktrace.Status{
|
Status: sdktrace.Status{
|
||||||
Code: codes.Unset,
|
Code: codes.Unset,
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
package metrictransform
|
package metrictransform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
||||||
|
|
||||||
@ -68,22 +66,40 @@ func Value(v attribute.Value) *commonpb.AnyValue {
|
|||||||
av.Value = &commonpb.AnyValue_BoolValue{
|
av.Value = &commonpb.AnyValue_BoolValue{
|
||||||
BoolValue: v.AsBool(),
|
BoolValue: v.AsBool(),
|
||||||
}
|
}
|
||||||
|
case attribute.BOOLSLICE:
|
||||||
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
|
Values: boolSliceValues(v.AsBoolSlice()),
|
||||||
|
},
|
||||||
|
}
|
||||||
case attribute.INT64:
|
case attribute.INT64:
|
||||||
av.Value = &commonpb.AnyValue_IntValue{
|
av.Value = &commonpb.AnyValue_IntValue{
|
||||||
IntValue: v.AsInt64(),
|
IntValue: v.AsInt64(),
|
||||||
}
|
}
|
||||||
|
case attribute.INT64SLICE:
|
||||||
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
|
Values: int64SliceValues(v.AsInt64Slice()),
|
||||||
|
},
|
||||||
|
}
|
||||||
case attribute.FLOAT64:
|
case attribute.FLOAT64:
|
||||||
av.Value = &commonpb.AnyValue_DoubleValue{
|
av.Value = &commonpb.AnyValue_DoubleValue{
|
||||||
DoubleValue: v.AsFloat64(),
|
DoubleValue: v.AsFloat64(),
|
||||||
}
|
}
|
||||||
|
case attribute.FLOAT64SLICE:
|
||||||
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
|
Values: float64SliceValues(v.AsFloat64Slice()),
|
||||||
|
},
|
||||||
|
}
|
||||||
case attribute.STRING:
|
case attribute.STRING:
|
||||||
av.Value = &commonpb.AnyValue_StringValue{
|
av.Value = &commonpb.AnyValue_StringValue{
|
||||||
StringValue: v.AsString(),
|
StringValue: v.AsString(),
|
||||||
}
|
}
|
||||||
case attribute.ARRAY:
|
case attribute.STRINGSLICE:
|
||||||
av.Value = &commonpb.AnyValue_ArrayValue{
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
ArrayValue: &commonpb.ArrayValue{
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
Values: arrayValues(v),
|
Values: stringSliceValues(v.AsStringSlice()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -94,56 +110,50 @@ func Value(v attribute.Value) *commonpb.AnyValue {
|
|||||||
return av
|
return av
|
||||||
}
|
}
|
||||||
|
|
||||||
func arrayValues(v attribute.Value) []*commonpb.AnyValue {
|
func boolSliceValues(vals []bool) []*commonpb.AnyValue {
|
||||||
a := v.AsArray()
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
aType := reflect.TypeOf(a)
|
for i, v := range vals {
|
||||||
var valueFunc func(reflect.Value) *commonpb.AnyValue
|
converted[i] = &commonpb.AnyValue{
|
||||||
switch aType.Elem().Kind() {
|
|
||||||
case reflect.Bool:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_BoolValue{
|
Value: &commonpb.AnyValue_BoolValue{
|
||||||
BoolValue: v.Bool(),
|
BoolValue: v,
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Int, reflect.Int64:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_IntValue{
|
|
||||||
IntValue: v.Int(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Uintptr:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_IntValue{
|
|
||||||
IntValue: int64(v.Uint()),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Float64:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_DoubleValue{
|
|
||||||
DoubleValue: v.Float(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.String:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_StringValue{
|
|
||||||
StringValue: v.String(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return converted
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([]*commonpb.AnyValue, aType.Len())
|
func int64SliceValues(vals []int64) []*commonpb.AnyValue {
|
||||||
for i, aValue := 0, reflect.ValueOf(a); i < aValue.Len(); i++ {
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
results[i] = valueFunc(aValue.Index(i))
|
for i, v := range vals {
|
||||||
|
converted[i] = &commonpb.AnyValue{
|
||||||
|
Value: &commonpb.AnyValue_IntValue{
|
||||||
|
IntValue: v,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return results
|
}
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|
||||||
|
func float64SliceValues(vals []float64) []*commonpb.AnyValue {
|
||||||
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
|
for i, v := range vals {
|
||||||
|
converted[i] = &commonpb.AnyValue{
|
||||||
|
Value: &commonpb.AnyValue_DoubleValue{
|
||||||
|
DoubleValue: v,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringSliceValues(vals []string) []*commonpb.AnyValue {
|
||||||
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
|
for i, v := range vals {
|
||||||
|
converted[i] = &commonpb.AnyValue{
|
||||||
|
Value: &commonpb.AnyValue_StringValue{
|
||||||
|
StringValue: v,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return converted
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,10 @@ func TestArrayAttributes(t *testing.T) {
|
|||||||
{nil, nil},
|
{nil, nil},
|
||||||
{
|
{
|
||||||
[]attribute.KeyValue{
|
[]attribute.KeyValue{
|
||||||
attribute.Array("invalid", [][]string{{"1", "2"}, {"a"}}),
|
{
|
||||||
|
Key: attribute.Key("invalid"),
|
||||||
|
Value: attribute.Value{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[]*commonpb.KeyValue{
|
[]*commonpb.KeyValue{
|
||||||
{
|
{
|
||||||
@ -127,18 +130,18 @@ func TestArrayAttributes(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]attribute.KeyValue{
|
[]attribute.KeyValue{
|
||||||
attribute.Array("bool array to bool array", []bool{true, false}),
|
attribute.BoolSlice("bool slice to bool array", []bool{true, false}),
|
||||||
attribute.Array("int array to int64 array", []int{1, 2, 3}),
|
attribute.IntSlice("int slice to int64 array", []int{1, 2, 3}),
|
||||||
attribute.Array("int64 array to int64 array", []int64{1, 2, 3}),
|
attribute.Int64Slice("int64 slice to int64 array", []int64{1, 2, 3}),
|
||||||
attribute.Array("float64 array to double array", []float64{1.11, 2.22, 3.33}),
|
attribute.Float64Slice("float64 slice to double array", []float64{1.11, 2.22, 3.33}),
|
||||||
attribute.Array("string array to string array", []string{"foo", "bar", "baz"}),
|
attribute.StringSlice("string slice to string array", []string{"foo", "bar", "baz"}),
|
||||||
},
|
},
|
||||||
[]*commonpb.KeyValue{
|
[]*commonpb.KeyValue{
|
||||||
newOTelBoolArray("bool array to bool array", []bool{true, false}),
|
newOTelBoolArray("bool slice to bool array", []bool{true, false}),
|
||||||
newOTelIntArray("int array to int64 array", []int64{1, 2, 3}),
|
newOTelIntArray("int slice to int64 array", []int64{1, 2, 3}),
|
||||||
newOTelIntArray("int64 array to int64 array", []int64{1, 2, 3}),
|
newOTelIntArray("int64 slice to int64 array", []int64{1, 2, 3}),
|
||||||
newOTelDoubleArray("float64 array to double array", []float64{1.11, 2.22, 3.33}),
|
newOTelDoubleArray("float64 slice to double array", []float64{1.11, 2.22, 3.33}),
|
||||||
newOTelStringArray("string array to string array", []string{"foo", "bar", "baz"}),
|
newOTelStringArray("string slice to string array", []string{"foo", "bar", "baz"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
package tracetransform
|
package tracetransform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
||||||
|
|
||||||
@ -68,22 +66,40 @@ func Value(v attribute.Value) *commonpb.AnyValue {
|
|||||||
av.Value = &commonpb.AnyValue_BoolValue{
|
av.Value = &commonpb.AnyValue_BoolValue{
|
||||||
BoolValue: v.AsBool(),
|
BoolValue: v.AsBool(),
|
||||||
}
|
}
|
||||||
|
case attribute.BOOLSLICE:
|
||||||
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
|
Values: boolSliceValues(v.AsBoolSlice()),
|
||||||
|
},
|
||||||
|
}
|
||||||
case attribute.INT64:
|
case attribute.INT64:
|
||||||
av.Value = &commonpb.AnyValue_IntValue{
|
av.Value = &commonpb.AnyValue_IntValue{
|
||||||
IntValue: v.AsInt64(),
|
IntValue: v.AsInt64(),
|
||||||
}
|
}
|
||||||
|
case attribute.INT64SLICE:
|
||||||
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
|
Values: int64SliceValues(v.AsInt64Slice()),
|
||||||
|
},
|
||||||
|
}
|
||||||
case attribute.FLOAT64:
|
case attribute.FLOAT64:
|
||||||
av.Value = &commonpb.AnyValue_DoubleValue{
|
av.Value = &commonpb.AnyValue_DoubleValue{
|
||||||
DoubleValue: v.AsFloat64(),
|
DoubleValue: v.AsFloat64(),
|
||||||
}
|
}
|
||||||
|
case attribute.FLOAT64SLICE:
|
||||||
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
|
Values: float64SliceValues(v.AsFloat64Slice()),
|
||||||
|
},
|
||||||
|
}
|
||||||
case attribute.STRING:
|
case attribute.STRING:
|
||||||
av.Value = &commonpb.AnyValue_StringValue{
|
av.Value = &commonpb.AnyValue_StringValue{
|
||||||
StringValue: v.AsString(),
|
StringValue: v.AsString(),
|
||||||
}
|
}
|
||||||
case attribute.ARRAY:
|
case attribute.STRINGSLICE:
|
||||||
av.Value = &commonpb.AnyValue_ArrayValue{
|
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||||
ArrayValue: &commonpb.ArrayValue{
|
ArrayValue: &commonpb.ArrayValue{
|
||||||
Values: arrayValues(v),
|
Values: stringSliceValues(v.AsStringSlice()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -94,56 +110,50 @@ func Value(v attribute.Value) *commonpb.AnyValue {
|
|||||||
return av
|
return av
|
||||||
}
|
}
|
||||||
|
|
||||||
func arrayValues(v attribute.Value) []*commonpb.AnyValue {
|
func boolSliceValues(vals []bool) []*commonpb.AnyValue {
|
||||||
a := v.AsArray()
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
aType := reflect.TypeOf(a)
|
for i, v := range vals {
|
||||||
var valueFunc func(reflect.Value) *commonpb.AnyValue
|
converted[i] = &commonpb.AnyValue{
|
||||||
switch aType.Elem().Kind() {
|
|
||||||
case reflect.Bool:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_BoolValue{
|
Value: &commonpb.AnyValue_BoolValue{
|
||||||
BoolValue: v.Bool(),
|
BoolValue: v,
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Int, reflect.Int64:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_IntValue{
|
|
||||||
IntValue: v.Int(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Uintptr:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_IntValue{
|
|
||||||
IntValue: int64(v.Uint()),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Float64:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_DoubleValue{
|
|
||||||
DoubleValue: v.Float(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.String:
|
|
||||||
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
|
|
||||||
return &commonpb.AnyValue{
|
|
||||||
Value: &commonpb.AnyValue_StringValue{
|
|
||||||
StringValue: v.String(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return converted
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([]*commonpb.AnyValue, aType.Len())
|
func int64SliceValues(vals []int64) []*commonpb.AnyValue {
|
||||||
for i, aValue := 0, reflect.ValueOf(a); i < aValue.Len(); i++ {
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
results[i] = valueFunc(aValue.Index(i))
|
for i, v := range vals {
|
||||||
|
converted[i] = &commonpb.AnyValue{
|
||||||
|
Value: &commonpb.AnyValue_IntValue{
|
||||||
|
IntValue: v,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return results
|
}
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|
||||||
|
func float64SliceValues(vals []float64) []*commonpb.AnyValue {
|
||||||
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
|
for i, v := range vals {
|
||||||
|
converted[i] = &commonpb.AnyValue{
|
||||||
|
Value: &commonpb.AnyValue_DoubleValue{
|
||||||
|
DoubleValue: v,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringSliceValues(vals []string) []*commonpb.AnyValue {
|
||||||
|
converted := make([]*commonpb.AnyValue, len(vals))
|
||||||
|
for i, v := range vals {
|
||||||
|
converted[i] = &commonpb.AnyValue{
|
||||||
|
Value: &commonpb.AnyValue_StringValue{
|
||||||
|
StringValue: v,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return converted
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,10 @@ func TestArrayAttributes(t *testing.T) {
|
|||||||
{nil, nil},
|
{nil, nil},
|
||||||
{
|
{
|
||||||
[]attribute.KeyValue{
|
[]attribute.KeyValue{
|
||||||
attribute.Array("invalid", [][]string{{"1", "2"}, {"a"}}),
|
{
|
||||||
|
Key: attribute.Key("invalid"),
|
||||||
|
Value: attribute.Value{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[]*commonpb.KeyValue{
|
[]*commonpb.KeyValue{
|
||||||
{
|
{
|
||||||
@ -127,18 +130,18 @@ func TestArrayAttributes(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]attribute.KeyValue{
|
[]attribute.KeyValue{
|
||||||
attribute.Array("bool array to bool array", []bool{true, false}),
|
attribute.BoolSlice("bool slice to bool array", []bool{true, false}),
|
||||||
attribute.Array("int array to int64 array", []int{1, 2, 3}),
|
attribute.IntSlice("int slice to int64 array", []int{1, 2, 3}),
|
||||||
attribute.Array("int64 array to int64 array", []int64{1, 2, 3}),
|
attribute.Int64Slice("int64 slice to int64 array", []int64{1, 2, 3}),
|
||||||
attribute.Array("float64 array to double array", []float64{1.11, 2.22, 3.33}),
|
attribute.Float64Slice("float64 slice to double array", []float64{1.11, 2.22, 3.33}),
|
||||||
attribute.Array("string array to string array", []string{"foo", "bar", "baz"}),
|
attribute.StringSlice("string slice to string array", []string{"foo", "bar", "baz"}),
|
||||||
},
|
},
|
||||||
[]*commonpb.KeyValue{
|
[]*commonpb.KeyValue{
|
||||||
newOTelBoolArray("bool array to bool array", []bool{true, false}),
|
newOTelBoolArray("bool slice to bool array", []bool{true, false}),
|
||||||
newOTelIntArray("int array to int64 array", []int64{1, 2, 3}),
|
newOTelIntArray("int slice to int64 array", []int64{1, 2, 3}),
|
||||||
newOTelIntArray("int64 array to int64 array", []int64{1, 2, 3}),
|
newOTelIntArray("int64 slice to int64 array", []int64{1, 2, 3}),
|
||||||
newOTelDoubleArray("float64 array to double array", []float64{1.11, 2.22, 3.33}),
|
newOTelDoubleArray("float64 slice to double array", []float64{1.11, 2.22, 3.33}),
|
||||||
newOTelStringArray("string array to string array", []string{"foo", "bar", "baz"}),
|
newOTelStringArray("string slice to string array", []string{"foo", "bar", "baz"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
@ -181,9 +181,18 @@ func toZipkinTags(data tracesdk.ReadOnlySpan) map[string]string {
|
|||||||
m := make(map[string]string, len(attr)+len(extraZipkinTags))
|
m := make(map[string]string, len(attr)+len(extraZipkinTags))
|
||||||
for _, kv := range attr {
|
for _, kv := range attr {
|
||||||
switch kv.Value.Type() {
|
switch kv.Value.Type() {
|
||||||
// For array attributes, serialize as JSON list string.
|
// For slice attributes, serialize as JSON list string.
|
||||||
case attribute.ARRAY:
|
case attribute.BOOLSLICE:
|
||||||
json, _ := json.Marshal(kv.Value.AsArray())
|
json, _ := json.Marshal(kv.Value.AsBoolSlice())
|
||||||
|
m[(string)(kv.Key)] = (string)(json)
|
||||||
|
case attribute.INT64SLICE:
|
||||||
|
json, _ := json.Marshal(kv.Value.AsInt64Slice())
|
||||||
|
m[(string)(kv.Key)] = (string)(json)
|
||||||
|
case attribute.FLOAT64SLICE:
|
||||||
|
json, _ := json.Marshal(kv.Value.AsFloat64Slice())
|
||||||
|
m[(string)(kv.Key)] = (string)(json)
|
||||||
|
case attribute.STRINGSLICE:
|
||||||
|
json, _ := json.Marshal(kv.Value.AsStringSlice())
|
||||||
m[(string)(kv.Key)] = (string)(json)
|
m[(string)(kv.Key)] = (string)(json)
|
||||||
default:
|
default:
|
||||||
m[(string)(kv.Key)] = kv.Value.Emit()
|
m[(string)(kv.Key)] = kv.Value.Emit()
|
||||||
|
@ -59,7 +59,7 @@ func TestModelConversion(t *testing.T) {
|
|||||||
Attributes: []attribute.KeyValue{
|
Attributes: []attribute.KeyValue{
|
||||||
attribute.Int64("attr1", 42),
|
attribute.Int64("attr1", 42),
|
||||||
attribute.String("attr2", "bar"),
|
attribute.String("attr2", "bar"),
|
||||||
attribute.Array("attr3", []int{0, 1, 2}),
|
attribute.IntSlice("attr3", []int{0, 1, 2}),
|
||||||
},
|
},
|
||||||
Events: []tracesdk.Event{
|
Events: []tracesdk.Event{
|
||||||
{
|
{
|
||||||
|
@ -33,9 +33,8 @@ func TestTraceStateFromKeyValues(t *testing.T) {
|
|||||||
attribute.Bool("key1", true),
|
attribute.Bool("key1", true),
|
||||||
attribute.Int64("key2", 1),
|
attribute.Int64("key2", 1),
|
||||||
attribute.Float64("key3", 1.1),
|
attribute.Float64("key3", 1.1),
|
||||||
attribute.Array("key4", []int{1, 1}),
|
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
expected := "key0=string,key1=true,key2=1,key3=1.1,key4=[1 1]"
|
expected := "key0=string,key1=true,key2=1,key3=1.1"
|
||||||
assert.Equal(t, expected, ts.String())
|
assert.Equal(t, expected, ts.String())
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ func (processExecutablePathDetector) Detect(ctx context.Context) (*Resource, err
|
|||||||
// Detect returns a *Resource that describes all the command arguments as received
|
// Detect returns a *Resource that describes all the command arguments as received
|
||||||
// by the process.
|
// by the process.
|
||||||
func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) {
|
func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgsKey.Array(commandArgs())), nil
|
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgsKey.StringSlice(commandArgs())), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect returns a *Resource that describes the username of the user that owns the
|
// Detect returns a *Resource that describes the username of the user that owns the
|
||||||
|
Reference in New Issue
Block a user