Skip to content

Commit 5cb5101

Browse files
committed
{From,With}Context for storing a logger in a context.Context
WithContext also supports additional arguments to set fields since this is a very common operation.
1 parent d2f17ae commit 5cb5101

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

context.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package hclog
2+
3+
import (
4+
"context"
5+
)
6+
7+
// WithContext inserts a logger into the context and is retrievable
8+
// with FromContext. The optional args can be set with the same syntax as
9+
// Logger.With to set fields on the inserted logger. This will not modify
10+
// the logger argument in-place.
11+
func WithContext(ctx context.Context, logger Logger, args ...interface{}) context.Context {
12+
// While we could call logger.With even with zero args, we have this
13+
// check to avoid unnecessary allocations around creating a copy of a
14+
// logger.
15+
if len(args) > 0 {
16+
logger = logger.With(args...)
17+
}
18+
19+
return context.WithValue(ctx, contextKey, logger)
20+
}
21+
22+
// FromContext returns a logger from the context. This will return nil
23+
// if there is no logger in the context.
24+
func FromContext(ctx context.Context) Logger {
25+
logger, _ := ctx.Value(contextKey).(Logger)
26+
return logger
27+
}
28+
29+
// Unexported new type so that our context key never collides with another.
30+
type contextKeyType struct{}
31+
32+
// contextKey is the key used for the context to store the logger.
33+
var contextKey = contextKeyType{}

context_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package hclog
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestContext_simpleLogger(t *testing.T) {
12+
l := L()
13+
ctx := WithContext(context.Background(), l)
14+
require.Equal(t, l, FromContext(ctx))
15+
}
16+
17+
func TestContext_fields(t *testing.T) {
18+
var buf bytes.Buffer
19+
l := New(&LoggerOptions{
20+
Level: Debug,
21+
Output: &buf,
22+
})
23+
24+
// Insert the logger with fields
25+
ctx := WithContext(context.Background(), l, "hello", "world")
26+
l = FromContext(ctx)
27+
require.NotNil(t, l)
28+
29+
// Log something so we can test the output that the field is there
30+
l.Debug("test")
31+
require.Contains(t, buf.String(), "hello")
32+
}

0 commit comments

Comments
 (0)