Merge branch 'swarmkit-master' into merge-log-swarmkit
This commit is contained in:
commit
29004dc3b4
3 changed files with 135 additions and 0 deletions
81
log/context.go
Normal file
81
log/context.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"path"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
// G is an alias for GetLogger.
|
||||
//
|
||||
// We may want to define this locally to a package to get package tagged log
|
||||
// messages.
|
||||
G = GetLogger
|
||||
|
||||
// L is an alias for the the standard logger.
|
||||
L = logrus.NewEntry(logrus.StandardLogger())
|
||||
)
|
||||
|
||||
type (
|
||||
loggerKey struct{}
|
||||
moduleKey struct{}
|
||||
)
|
||||
|
||||
// WithLogger returns a new context with the provided logger. Use in
|
||||
// combination with logger.WithField(s) for great effect.
|
||||
func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context {
|
||||
return context.WithValue(ctx, loggerKey{}, logger)
|
||||
}
|
||||
|
||||
// GetLogger retrieves the current logger from the context. If no logger is
|
||||
// available, the default logger is returned.
|
||||
func GetLogger(ctx context.Context) *logrus.Entry {
|
||||
logger := ctx.Value(loggerKey{})
|
||||
|
||||
if logger == nil {
|
||||
return L
|
||||
}
|
||||
|
||||
return logger.(*logrus.Entry)
|
||||
}
|
||||
|
||||
// WithModule adds the module to the context, appending it with a slash if a
|
||||
// module already exists. A module is just an roughly correlated defined by the
|
||||
// call tree for a given context.
|
||||
//
|
||||
// As an example, we might have a "node" module already part of a context. If
|
||||
// this function is called with "tls", the new value of module will be
|
||||
// "node/tls".
|
||||
//
|
||||
// Modules represent the call path. If the new module and last module are the
|
||||
// same, a new module entry will not be created. If the new module and old
|
||||
// older module are the same but separated by other modules, the cycle will be
|
||||
// represented by the module path.
|
||||
func WithModule(ctx context.Context, module string) context.Context {
|
||||
parent := GetModulePath(ctx)
|
||||
|
||||
if parent != "" {
|
||||
// don't re-append module when module is the same.
|
||||
if path.Base(parent) == module {
|
||||
return ctx
|
||||
}
|
||||
|
||||
module = path.Join(parent, module)
|
||||
}
|
||||
|
||||
ctx = WithLogger(ctx, GetLogger(ctx).WithField("module", module))
|
||||
return context.WithValue(ctx, moduleKey{}, module)
|
||||
}
|
||||
|
||||
// GetModulePath returns the module path for the provided context. If no module
|
||||
// is set, an empty string is returned.
|
||||
func GetModulePath(ctx context.Context) string {
|
||||
module := ctx.Value(moduleKey{})
|
||||
if module == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return module.(string)
|
||||
}
|
41
log/context_test.go
Normal file
41
log/context_test.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func TestLoggerContext(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
assert.Equal(t, GetLogger(ctx), L) // should be same as L variable
|
||||
assert.Equal(t, G(ctx), GetLogger(ctx)) // these should be the same.
|
||||
|
||||
ctx = WithLogger(ctx, G(ctx).WithField("test", "one"))
|
||||
assert.Equal(t, GetLogger(ctx).Data["test"], "one")
|
||||
assert.Equal(t, G(ctx), GetLogger(ctx)) // these should be the same.
|
||||
}
|
||||
|
||||
func TestModuleContext(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
assert.Equal(t, GetModulePath(ctx), "")
|
||||
|
||||
ctx = WithModule(ctx, "a") // basic behavior
|
||||
assert.Equal(t, GetModulePath(ctx), "a")
|
||||
logger := GetLogger(ctx)
|
||||
assert.Equal(t, logger.Data["module"], "a")
|
||||
|
||||
parent, ctx := ctx, WithModule(ctx, "a")
|
||||
assert.Equal(t, ctx, parent) // should be a no-op
|
||||
assert.Equal(t, GetModulePath(ctx), "a")
|
||||
assert.Equal(t, GetLogger(ctx).Data["module"], "a")
|
||||
|
||||
ctx = WithModule(ctx, "b") // new module
|
||||
assert.Equal(t, GetModulePath(ctx), "a/b")
|
||||
assert.Equal(t, GetLogger(ctx).Data["module"], "a/b")
|
||||
|
||||
ctx = WithModule(ctx, "c") // new module
|
||||
assert.Equal(t, GetModulePath(ctx), "a/b/c")
|
||||
assert.Equal(t, GetLogger(ctx).Data["module"], "a/b/c")
|
||||
}
|
13
log/grpc.go
Normal file
13
log/grpc.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ctx := WithModule(context.Background(), "grpc")
|
||||
|
||||
// completely replace the grpc logger with the logrus logger.
|
||||
grpclog.SetLogger(G(ctx))
|
||||
}
|
Loading…
Reference in a new issue