Skip to content

Commit 6059450

Browse files
committed
Use a public context baggage key
In order to facilitate the deprecation of this library and allow a smoother migration to other logging libraries, this library will now store the baggage values in a public key string, which can be read by anyone, so even if someone sets the key by this deprecated library, we still can read it by a newer library in another layer. This is backwards compatible, since we're just making private things public, except for the unlikely case where the key would collide with someone other's key.
1 parent b7b430d commit 6059450

File tree

5 files changed

+70
-46
lines changed

5 files changed

+70
-46
lines changed

baggage.go

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,50 @@ import (
66
"fmt"
77
"math/rand"
88
"strconv"
9-
10-
"github.com/cabify/go-logging/internal"
119
)
1210

11+
// BaggageContextKey is the key to be used for the baggage map[string]interface{} in
12+
// context.*Value.
13+
// It's intentionally a public string type, so the deprecation of this library is easier, since a public
14+
// string type can be defined in another package
15+
var BaggageContextKey interface{} = "logctx-data-map-string-interface"
16+
1317
const loggerRequestIDLength = 7
1418

19+
// Baggage is a handy helper to extract the baggage from the context, probably to be used with another logger
20+
func Baggage(ctx context.Context) map[string]interface{} {
21+
if baggage, ok := ctx.Value(BaggageContextKey).(map[string]interface{}); ok {
22+
return baggage
23+
}
24+
25+
return map[string]interface{}{}
26+
}
27+
1528
// WithBaggageValue returns a context with the added key value pair in the baggage store.
1629
func WithBaggageValue(ctx context.Context, key, value string) context.Context {
17-
oldBaggage, ok := ctx.Value(internal.BaggageContextKey).(internal.Baggage)
30+
oldBaggage, ok := ctx.Value(BaggageContextKey).(map[string]interface{})
1831

1932
if !ok {
20-
return context.WithValue(ctx, internal.BaggageContextKey, internal.Baggage{key: value})
33+
return context.WithValue(ctx, BaggageContextKey, map[string]interface{}{key: value})
2134
}
2235

23-
newBaggage := make(internal.Baggage, len(oldBaggage)+1)
36+
newBaggage := make(map[string]interface{}, len(oldBaggage)+1)
2437
for oldKey, oldValue := range oldBaggage {
2538
newBaggage[oldKey] = oldValue
2639
}
2740
newBaggage[key] = value
2841

29-
return context.WithValue(ctx, internal.BaggageContextKey, newBaggage)
42+
return context.WithValue(ctx, BaggageContextKey, newBaggage)
3043
}
3144

3245
// WithBaggageValues returns a context with all key value pairs added to the baggage store.
3346
func WithBaggageValues(ctx context.Context, keyValue map[string]string) context.Context {
34-
oldBaggage, ok := ctx.Value(internal.BaggageContextKey).(internal.Baggage)
47+
oldBaggage, ok := ctx.Value(BaggageContextKey).(map[string]interface{})
3548
if !ok {
36-
return context.WithValue(ctx, internal.BaggageContextKey, internal.Baggage(keyValue))
49+
return context.WithValue(ctx, BaggageContextKey, toMapStringInterface(keyValue))
3750
}
3851

39-
newBaggage := make(internal.Baggage, len(oldBaggage)+len(keyValue))
52+
newBaggage := make(map[string]interface{}, len(oldBaggage)+len(keyValue))
4053
for oldKey, oldValue := range oldBaggage {
4154
newBaggage[oldKey] = oldValue
4255
}
@@ -45,16 +58,16 @@ func WithBaggageValues(ctx context.Context, keyValue map[string]string) context.
4558
newBaggage[newKey] = newValue
4659
}
4760

48-
return context.WithValue(ctx, internal.BaggageContextKey, newBaggage)
61+
return context.WithValue(ctx, BaggageContextKey, newBaggage)
4962
}
5063

5164
// NewContextWithBaggageFrom returns a new context with baggage values obtained from another context
5265
func NewContextWithBaggageFrom(ctx context.Context) context.Context {
53-
oldBaggage, ok := ctx.Value(internal.BaggageContextKey).(internal.Baggage)
66+
oldBaggage, ok := ctx.Value(BaggageContextKey).(map[string]interface{})
5467
if !ok {
5568
return context.Background()
5669
}
57-
return context.WithValue(context.Background(), internal.BaggageContextKey, oldBaggage)
70+
return context.WithValue(context.Background(), BaggageContextKey, oldBaggage)
5871
}
5972

6073
// NewContextFromWithValue creates a new context with baggage values from ctx plus the provided one
@@ -71,3 +84,11 @@ func NewID() string {
7184
encoded := md5.Sum([]byte(strconv.FormatInt(data, 16)))
7285
return fmt.Sprintf("%x", encoded)[:loggerRequestIDLength]
7386
}
87+
88+
func toMapStringInterface(original map[string]string) map[string]interface{} {
89+
m := make(map[string]interface{}, len(original))
90+
for k, v := range original {
91+
m[k] = v
92+
}
93+
return m
94+
}

context_logger.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,27 @@ package log
22

33
import (
44
"context"
5-
6-
"github.com/cabify/go-logging/internal"
5+
"fmt"
6+
"sort"
7+
"strings"
78
)
89

910
type baggageLogger struct {
1011
Logger
1112
ctx context.Context
1213
}
1314

15+
func baggageString(b map[string]interface{}) string {
16+
var kvPairs []string
17+
for key, value := range b {
18+
kvPairs = append(kvPairs, fmt.Sprintf("%s:%v", key, value))
19+
}
20+
21+
sort.Strings(kvPairs)
22+
23+
return strings.Join(kvPairs, ": ")
24+
}
25+
1426
func newBaggageLogger(ctx context.Context, base Logger) baggageLogger {
1527
return baggageLogger{
1628
Logger: base,
@@ -19,12 +31,12 @@ func newBaggageLogger(ctx context.Context, base Logger) baggageLogger {
1931
}
2032

2133
func (l baggageLogger) getContextString() string {
22-
baggage, ok := l.ctx.Value(internal.BaggageContextKey).(internal.Baggage)
34+
baggage, ok := l.ctx.Value(BaggageContextKey).(map[string]interface{})
2335
if !ok {
2436
return ""
2537
}
2638

27-
return baggage.String() + ": "
39+
return baggageString(baggage) + ": "
2840
}
2941

3042
func (l baggageLogger) Fatal(args ...interface{}) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package log_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
log "github.com/cabify/go-logging"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestBaggageCanBeReadFromOtherPackages(t *testing.T) {
12+
ctx := context.Background()
13+
ctx = log.WithBaggageValue(ctx, "key", "value")
14+
15+
// notice that we're reading using our own key here
16+
baggage := ctx.Value("logctx-data-map-string-interface")
17+
18+
assert.Equal(t, map[string]interface{}{"key": "value"}, baggage)
19+
}

internal/baggage.go

Lines changed: 0 additions & 28 deletions
This file was deleted.

logtest/baggage.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ package logtest
66
import (
77
"context"
88

9-
"github.com/cabify/go-logging/internal"
9+
log "github.com/cabify/go-logging"
1010
)
1111

1212
// HasBaggageValue returns whether the context contains a baggage value.
1313
func HasBaggageValue(ctx context.Context, key, value string) bool {
14-
baggage, ok := ctx.Value(internal.BaggageContextKey).(internal.Baggage)
14+
baggage, ok := ctx.Value(log.BaggageContextKey).(map[string]interface{})
1515
if !ok {
1616
return false
1717
}

0 commit comments

Comments
 (0)