Skip to content

Commit

Permalink
log: Add String method to Value and KeyValue
Browse files Browse the repository at this point in the history
  • Loading branch information
pellared committed Mar 29, 2024
1 parent ba5d126 commit c3dc713
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
43 changes: 43 additions & 0 deletions log/keyvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ package log // import "go.opentelemetry.io/otel/log"
import (
"bytes"
"errors"
"fmt"
"math"
"slices"
"strconv"
"unsafe"

"go.opentelemetry.io/otel/internal/global"
Expand Down Expand Up @@ -265,6 +267,39 @@ func (v Value) Equal(w Value) bool {
}
}

// String returns Value's value as a string, formatted like [fmt.Sprint].
//
// The returned string is meant for debugging;
// the string representation is not stable.
func (v Value) String() string {
switch v.Kind() {
case KindString:
return v.asString()
case KindInt64:
return strconv.FormatInt(int64(v.num), 10)
case KindFloat64:
return strconv.FormatFloat(v.asFloat64(), 'g', -1, 64)
case KindBool:
return strconv.FormatBool(v.asBool())
case KindBytes:
return fmt.Sprint(v.asBytes())
case KindMap:
return fmt.Sprint(v.asMap())
case KindSlice:
return fmt.Sprint(v.asSlice())
case KindEmpty:
return "<nil>"
default:

Check warning on line 292 in log/keyvalue.go

View check run for this annotation

Codecov / codecov/patch

log/keyvalue.go#L292

Added line #L292 was not covered by tests
// Try to handle this as gracefully as possible.
//
// Don't panic here. The goal here is to have developers find this
// first if a slog.Kind is is not handled. It is
// preferable to have user's open issue asking why their attributes
// have a "unhandled: " prefix than say that their code is panicking.
return fmt.Sprintf("<unhandled log.Kind: %s>", v.Kind())

Check warning on line 299 in log/keyvalue.go

View check run for this annotation

Codecov / codecov/patch

log/keyvalue.go#L299

Added line #L299 was not covered by tests
}
}

// 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 {
Expand Down Expand Up @@ -321,3 +356,11 @@ func Map(key string, value ...KeyValue) KeyValue {
func Empty(key string) KeyValue {
return KeyValue{key, Value{}}
}

// String returns key-value pair as a string, formatted like "key=value".
//
// The returned string is meant for debugging;
// the string representation is not stable.
func (a KeyValue) String() string {
return fmt.Sprintf("%s=%s", a.Key, a.Value)
}
19 changes: 19 additions & 0 deletions log/keyvalue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,25 @@ func TestEmpty(t *testing.T) {
t.Run("AsMap", testErrKind(v.AsMap, "AsMap", k))
}

func TestValueString(t *testing.T) {
for _, test := range []struct {
v log.Value
want string
}{
{log.Int64Value(-3), "-3"},
{log.Float64Value(.15), "0.15"},
{log.BoolValue(true), "true"},
{log.StringValue("foo"), "foo"},
{log.BytesValue([]byte{2, 4, 6}), "[2 4 6]"},
{log.SliceValue(log.IntValue(3), log.StringValue("foo")), "[3 foo]"},
{log.MapValue(log.Int("a", 1), log.Bool("b", true)), "[a=1 b=true]"},
{log.Value{}, "<nil>"},
} {
got := test.v.String()
assert.Equal(t, test.want, got)
}
}

type logSink struct {
logr.LogSink

Expand Down

0 comments on commit c3dc713

Please sign in to comment.