731e0b0066
You shouldn't have to import both: github.com/docker/distribution/context golang.org/x/net/context just to use the distribution tools and implement the distribution interfaces. By pulling the Context interface from golang.org/x/net/context into the context package within the distribution project, you no longer have to import both packages. Note: You do not have to change anything anywhere else yet! All current uses of both packages together will still work correctly because the Context interface from either package is identical. I've also made some other minor changes: - Added a RemoteIP function. It's like RemoteAddr but discards the port suffix - Added `.String()` to the response duration context value so that JSON log formatting shows human-parseable duration and not just number of nano-seconds - Added WithMapContext(...) to the context package. This is a useful function so I pulled it out of the main.go in cmd/registry so that it can be used elsewhere. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
package context
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
)
|
|
|
|
// Logger provides a leveled-logging interface.
|
|
type Logger interface {
|
|
// standard logger methods
|
|
Print(args ...interface{})
|
|
Printf(format string, args ...interface{})
|
|
Println(args ...interface{})
|
|
|
|
Fatal(args ...interface{})
|
|
Fatalf(format string, args ...interface{})
|
|
Fatalln(args ...interface{})
|
|
|
|
Panic(args ...interface{})
|
|
Panicf(format string, args ...interface{})
|
|
Panicln(args ...interface{})
|
|
|
|
// Leveled methods, from logrus
|
|
Debug(args ...interface{})
|
|
Debugf(format string, args ...interface{})
|
|
Debugln(args ...interface{})
|
|
|
|
Error(args ...interface{})
|
|
Errorf(format string, args ...interface{})
|
|
Errorln(args ...interface{})
|
|
|
|
Info(args ...interface{})
|
|
Infof(format string, args ...interface{})
|
|
Infoln(args ...interface{})
|
|
|
|
Warn(args ...interface{})
|
|
Warnf(format string, args ...interface{})
|
|
Warnln(args ...interface{})
|
|
}
|
|
|
|
// WithLogger creates a new context with provided logger.
|
|
func WithLogger(ctx Context, logger Logger) Context {
|
|
return WithValue(ctx, "logger", logger)
|
|
}
|
|
|
|
// GetLogger returns the logger from the current context, if present. If one
|
|
// or more keys are provided, they will be resolved on the context and
|
|
// included in the logger. While context.Value takes an interface, any key
|
|
// argument passed to GetLogger will be passed to fmt.Sprint when expanded as
|
|
// a logging key field. If context keys are integer constants, for example,
|
|
// its recommended that a String method is implemented.
|
|
func GetLogger(ctx Context, keys ...interface{}) Logger {
|
|
return getLogrusLogger(ctx, keys...)
|
|
}
|
|
|
|
// GetLogrusLogger returns the logrus logger for the context. If one more keys
|
|
// are provided, they will be resolved on the context and included in the
|
|
// logger. Only use this function if specific logrus functionality is
|
|
// required.
|
|
func getLogrusLogger(ctx Context, keys ...interface{}) *logrus.Entry {
|
|
var logger *logrus.Entry
|
|
|
|
// Get a logger, if it is present.
|
|
loggerInterface := ctx.Value("logger")
|
|
if loggerInterface != nil {
|
|
if lgr, ok := loggerInterface.(*logrus.Entry); ok {
|
|
logger = lgr
|
|
}
|
|
}
|
|
|
|
if logger == nil {
|
|
// If no logger is found, just return the standard logger.
|
|
logger = logrus.NewEntry(logrus.StandardLogger())
|
|
}
|
|
|
|
fields := logrus.Fields{}
|
|
|
|
for _, key := range keys {
|
|
v := ctx.Value(key)
|
|
if v != nil {
|
|
fields[fmt.Sprint(key)] = v
|
|
}
|
|
}
|
|
|
|
return logger.WithFields(fields)
|
|
}
|