1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-11-24 08:22:25 +02:00

logs: Add empty value for KeyValue (#5076)

* Add empty value for KeyValue

* Update CHANGELOG

* Apply suggestions from code review

Co-authored-by: Robert Pająk <pellared@hotmail.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>

* Fix comments

* Update log/keyvalue.go

Co-authored-by: Damien Mathieu <42@dmathieu.com>

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Co-authored-by: Damien Mathieu <42@dmathieu.com>
This commit is contained in:
Sam Xie 2024-03-15 07:52:24 -07:00 committed by GitHub
parent 42c1708ed5
commit 47ac0d4df8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 10 deletions

View File

@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp`. (#4906)
- Add `SeverityUndefined` `const` to `go.opentelemetry.io/otel/log`.
This value represents an unset severity level. (#5072)
- Add `Empty` function in `go.opentelemetry.io/otel/log` to return a `KeyValue` for an empty value. (#5076)
### Changed

View File

@ -34,6 +34,7 @@ const (
)
// A Value represents a structured log value.
// A zero value is valid and represents an empty value.
type Value struct {
// Ensure forward compatibility by explicitly making this not comparable.
noCmp [0]func() //nolint: unused // This is indeed used.
@ -264,7 +265,7 @@ func (v Value) Equal(w Value) bool {
}
}
// An KeyValue is a key-value pair used to represent a log attribute (a
// A KeyValue is a key-value pair used to represent a log attribute (a
// superset of [go.opentelemetry.io/otel/attribute.KeyValue]) and map item.
type KeyValue struct {
Key string
@ -276,42 +277,47 @@ func (a KeyValue) Equal(b KeyValue) bool {
return a.Key == b.Key && a.Value.Equal(b.Value)
}
// String returns an KeyValue for a string value.
// String returns a KeyValue for a string value.
func String(key, value string) KeyValue {
return KeyValue{key, StringValue(value)}
}
// Int64 returns an KeyValue for an int64 value.
// Int64 returns a KeyValue for an int64 value.
func Int64(key string, value int64) KeyValue {
return KeyValue{key, Int64Value(value)}
}
// Int returns an KeyValue for an int value.
// Int returns a KeyValue for an int value.
func Int(key string, value int) KeyValue {
return KeyValue{key, IntValue(value)}
}
// Float64 returns an KeyValue for a float64 value.
// Float64 returns a KeyValue for a float64 value.
func Float64(key string, value float64) KeyValue {
return KeyValue{key, Float64Value(value)}
}
// Bool returns an KeyValue for a bool value.
// Bool returns a KeyValue for a bool value.
func Bool(key string, value bool) KeyValue {
return KeyValue{key, BoolValue(value)}
}
// Bytes returns an KeyValue for a []byte value.
// Bytes returns a KeyValue for a []byte value.
func Bytes(key string, value []byte) KeyValue {
return KeyValue{key, BytesValue(value)}
}
// Slice returns an KeyValue for a []Value value.
// Slice returns a KeyValue for a []Value value.
func Slice(key string, value ...Value) KeyValue {
return KeyValue{key, SliceValue(value...)}
}
// Map returns an KeyValue for a map value.
// Map returns a KeyValue for a map value.
func Map(key string, value ...KeyValue) KeyValue {
return KeyValue{key, MapValue(value...)}
}
// Empty returns a KeyValue with an empty value.
func Empty(key string) KeyValue {
return KeyValue{key, Value{}}
}

View File

@ -60,6 +60,7 @@ func TestValueEqual(t *testing.T) {
log.MapValue(
log.Slice("l", log.IntValue(3), log.StringValue("foo")),
log.Bytes("b", []byte{3, 5, 7}),
log.Empty("e"),
),
}
for i, v1 := range vals {
@ -69,7 +70,7 @@ func TestValueEqual(t *testing.T) {
}
}
func TestEmpty(t *testing.T) {
func TestValueEmpty(t *testing.T) {
v := log.Value{}
t.Run("Value.Empty", func(t *testing.T) {
assert.True(t, v.Empty())
@ -246,6 +247,23 @@ func TestMap(t *testing.T) {
})
}
func TestEmpty(t *testing.T) {
const key = "key"
kv := log.Empty(key)
assert.Equal(t, key, kv.Key, "incorrect key")
assert.True(t, kv.Value.Empty(), "value not empty")
v, k := kv.Value, log.KindEmpty
t.Run("AsBool", testErrKind(v.AsBool, "AsBool", k))
t.Run("AsFloat64", testErrKind(v.AsFloat64, "AsFloat64", k))
t.Run("AsInt64", testErrKind(v.AsInt64, "AsInt64", k))
t.Run("AsString", testErrKind(v.AsString, "AsString", k))
t.Run("AsBytes", testErrKind(v.AsBytes, "AsBytes", k))
t.Run("AsSlice", testErrKind(v.AsSlice, "AsSlice", k))
t.Run("AsMap", testErrKind(v.AsMap, "AsMap", k))
}
type logSink struct {
logr.LogSink