You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-09-16 09:26:25 +02:00
Do not use the user-defined empty set when comparing sets. (#7357)
Fix #7356
This commit is contained in:
@@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix `WithInstrumentationAttributes` options in `go.opentelemetry.io/otel/trace`, `go.opentelemetry.io/otel/metric`, and `go.opentelemetry.io/otel/log` to properly merge attributes when passed multiple times instead of replacing them. Attributes with duplicate keys will use the last value passed. (#7300)
|
- Fix `WithInstrumentationAttributes` options in `go.opentelemetry.io/otel/trace`, `go.opentelemetry.io/otel/metric`, and `go.opentelemetry.io/otel/log` to properly merge attributes when passed multiple times instead of replacing them. Attributes with duplicate keys will use the last value passed. (#7300)
|
||||||
|
- The equality of `attribute.Set` when using the `Equal` method is not affected by the user overriding the empty set pointed to by `attribute.EmptySet` in `go.opentelemetry.io/otel/attribute`. (#7357)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@@ -50,8 +50,18 @@ var (
|
|||||||
// keyValueType is used in computeDistinctReflect.
|
// keyValueType is used in computeDistinctReflect.
|
||||||
keyValueType = reflect.TypeOf(KeyValue{})
|
keyValueType = reflect.TypeOf(KeyValue{})
|
||||||
|
|
||||||
// emptySet is returned for empty attribute sets.
|
// userDefinedEmptySet is an empty set. It was mistakenly exposed to users
|
||||||
emptySet = &Set{
|
// as something they can assign to, so it must remain addressable and
|
||||||
|
// mutable.
|
||||||
|
//
|
||||||
|
// This is kept for backwards compatibility, but should not be used in new code.
|
||||||
|
userDefinedEmptySet = &Set{
|
||||||
|
equivalent: Distinct{
|
||||||
|
iface: [0]KeyValue{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
emptySet = Set{
|
||||||
equivalent: Distinct{
|
equivalent: Distinct{
|
||||||
iface: [0]KeyValue{},
|
iface: [0]KeyValue{},
|
||||||
},
|
},
|
||||||
@@ -62,7 +72,11 @@ var (
|
|||||||
//
|
//
|
||||||
// This is a convenience provided for optimized calling utility.
|
// This is a convenience provided for optimized calling utility.
|
||||||
func EmptySet() *Set {
|
func EmptySet() *Set {
|
||||||
return emptySet
|
// Continue to return the pointer to the user-defined empty set for
|
||||||
|
// backwards-compatibility.
|
||||||
|
//
|
||||||
|
// New code should not use this, instead use emptySet.
|
||||||
|
return userDefinedEmptySet
|
||||||
}
|
}
|
||||||
|
|
||||||
// reflectValue abbreviates reflect.ValueOf(d).
|
// reflectValue abbreviates reflect.ValueOf(d).
|
||||||
@@ -169,12 +183,6 @@ func (l *Set) Encoded(encoder Encoder) string {
|
|||||||
return encoder.Encode(l.Iter())
|
return encoder.Encode(l.Iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
func empty() Set {
|
|
||||||
return Set{
|
|
||||||
equivalent: emptySet.equivalent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSet returns a new Set. See the documentation for
|
// NewSet returns a new Set. See the documentation for
|
||||||
// NewSetWithSortableFiltered for more details.
|
// NewSetWithSortableFiltered for more details.
|
||||||
//
|
//
|
||||||
@@ -204,7 +212,7 @@ func NewSetWithSortable(kvs []KeyValue, _ *Sortable) Set {
|
|||||||
func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
|
func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
|
||||||
// Check for empty set.
|
// Check for empty set.
|
||||||
if len(kvs) == 0 {
|
if len(kvs) == 0 {
|
||||||
return empty(), nil
|
return emptySet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stable sort so the following de-duplication can implement
|
// Stable sort so the following de-duplication can implement
|
||||||
|
@@ -469,6 +469,17 @@ func TestMarshalJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetEqualsEmpty(t *testing.T) {
|
||||||
|
e := attribute.EmptySet()
|
||||||
|
empty := *e
|
||||||
|
|
||||||
|
alt := attribute.NewSet(attribute.String("A", "B"))
|
||||||
|
*e = alt
|
||||||
|
|
||||||
|
var s attribute.Set
|
||||||
|
assert.Truef(t, s.Equals(&empty), "expected %v to equal empty set %v", s, attribute.EmptySet())
|
||||||
|
}
|
||||||
|
|
||||||
type simpleStringer struct {
|
type simpleStringer struct {
|
||||||
val string
|
val string
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user