From 5288d8f9fe64984ded221bc088716263cbbdc6d3 Mon Sep 17 00:00:00 2001 From: Stephen J Day Date: Tue, 2 Aug 2016 16:41:49 -0700 Subject: [PATCH] log: improve module-oriented logging To improve the output of module logging, we now include a path that represents the modules that a context has passed through. This makes it easy to tell if a log line came from a particular module hierarchy. A helper function, `WithModule`, provides an easy way to mark a context with a module and inject that module into the logger. Signed-off-by: Stephen J Day --- log/context.go | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/log/context.go b/log/context.go index b919e35..4539e47 100644 --- a/log/context.go +++ b/log/context.go @@ -1,6 +1,8 @@ package log import ( + "path" + "github.com/Sirupsen/logrus" "golang.org/x/net/context" ) @@ -16,7 +18,10 @@ var ( L = logrus.NewEntry(logrus.StandardLogger()) ) -type loggerKey struct{} +type ( + loggerKey struct{} + moduleKey struct{} +) // WithLogger returns a new context with the provided logger. Use in // combination with logger.WithField(s) for great effect. @@ -35,3 +40,42 @@ func GetLogger(ctx context.Context) *logrus.Entry { 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) +}