1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-26 21:05:00 +02:00

log: Add String method to Value and KeyValue (#5117)

This commit is contained in:
Robert Pająk 2024-04-02 10:50:07 +02:00 committed by GitHub
parent b7fdeb9f3a
commit e6e44dee90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 63 additions and 0 deletions

View File

@ -24,6 +24,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add support for `Summary` metrics in the `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` exporters. (#5100)
- Add `otel.scope.name` and `otel.scope.version` tags to spans exported by `go.opentelemetry.io/otel/exporters/zipkin`. (#5108)
- Add support for `AddLink` to `go.opentelemetry.io/otel/bridge/opencensus`. (#5116)
- Add `String` method to `Value` and `KeyValue` in `go.opentelemetry.io/otel/log`. (#5117)
### Changed

View File

@ -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"
@ -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:
// 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())
}
}
// 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 {
@ -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)
}

View File

@ -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