Skip to content

Commit

Permalink
Merge pull request #42 from hashicorp/f-context
Browse files Browse the repository at this point in the history
{From,With}Context for storing a logger in a context.Context
  • Loading branch information
mitchellh authored May 10, 2019
2 parents d2f17ae + ea9db1c commit 2f1b231
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
38 changes: 38 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package hclog

import (
"context"
)

// WithContext inserts a logger into the context and is retrievable
// with FromContext. The optional args can be set with the same syntax as
// Logger.With to set fields on the inserted logger. This will not modify
// the logger argument in-place.
func WithContext(ctx context.Context, logger Logger, args ...interface{}) context.Context {
// While we could call logger.With even with zero args, we have this
// check to avoid unnecessary allocations around creating a copy of a
// logger.
if len(args) > 0 {
logger = logger.With(args...)
}

return context.WithValue(ctx, contextKey, logger)
}

// FromContext returns a logger from the context. This will return L()
// (the default logger) if no logger is found in the context. Therefore,
// this will never return a nil value.
func FromContext(ctx context.Context) Logger {
logger, _ := ctx.Value(contextKey).(Logger)
if logger == nil {
return L()
}

return logger
}

// Unexported new type so that our context key never collides with another.
type contextKeyType struct{}

// contextKey is the key used for the context to store the logger.
var contextKey = contextKeyType{}
36 changes: 36 additions & 0 deletions context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package hclog

import (
"bytes"
"context"
"testing"

"github.com/stretchr/testify/require"
)

func TestContext_simpleLogger(t *testing.T) {
l := L()
ctx := WithContext(context.Background(), l)
require.Equal(t, l, FromContext(ctx))
}

func TestContext_empty(t *testing.T) {
require.Equal(t, L(), FromContext(context.Background()))
}

func TestContext_fields(t *testing.T) {
var buf bytes.Buffer
l := New(&LoggerOptions{
Level: Debug,
Output: &buf,
})

// Insert the logger with fields
ctx := WithContext(context.Background(), l, "hello", "world")
l = FromContext(ctx)
require.NotNil(t, l)

// Log something so we can test the output that the field is there
l.Debug("test")
require.Contains(t, buf.String(), "hello")
}

0 comments on commit 2f1b231

Please sign in to comment.