Add WithVersion to context and other cleanup
By adding WithVersion to the context package, we can simplify context setup in the application. This avoids some odd bugs where instantiation order can lead to missing instance.id or version from log messages. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
360c24d975
commit
530afa5234
6 changed files with 62 additions and 11 deletions
|
@ -3,6 +3,19 @@
|
||||||
// logging relevent request information but this package is not limited to
|
// logging relevent request information but this package is not limited to
|
||||||
// that purpose.
|
// that purpose.
|
||||||
//
|
//
|
||||||
|
// The easiest way to get started is to get the background context:
|
||||||
|
//
|
||||||
|
// ctx := context.Background()
|
||||||
|
//
|
||||||
|
// The returned context should be passed around your application and be the
|
||||||
|
// root of all other context instances. If the application has a version, this
|
||||||
|
// line should be called before anything else:
|
||||||
|
//
|
||||||
|
// ctx := context.WithVersion(context.Background(), version)
|
||||||
|
//
|
||||||
|
// The above will store the version in the context and will be available to
|
||||||
|
// the logger.
|
||||||
|
//
|
||||||
// Logging
|
// Logging
|
||||||
//
|
//
|
||||||
// The most useful aspect of this package is GetLogger. This function takes
|
// The most useful aspect of this package is GetLogger. This function takes
|
||||||
|
|
|
@ -90,8 +90,16 @@ func getLogrusLogger(ctx Context, keys ...interface{}) *logrus.Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
if logger == nil {
|
if logger == nil {
|
||||||
|
fields := logrus.Fields{}
|
||||||
|
|
||||||
|
// Fill in the instance id, if we have it.
|
||||||
|
instanceID := ctx.Value("instance.id")
|
||||||
|
if instanceID != nil {
|
||||||
|
fields["instance.id"] = instanceID
|
||||||
|
}
|
||||||
|
|
||||||
// If no logger is found, just return the standard logger.
|
// If no logger is found, just return the standard logger.
|
||||||
logger = logrus.NewEntry(logrus.StandardLogger())
|
logger = logrus.StandardLogger().WithFields(fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
fields := logrus.Fields{}
|
fields := logrus.Fields{}
|
||||||
|
|
16
context/version.go
Normal file
16
context/version.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package context
|
||||||
|
|
||||||
|
// WithVersion stores the application version in the context. The new context
|
||||||
|
// gets a logger to ensure log messages are marked with the application
|
||||||
|
// version.
|
||||||
|
func WithVersion(ctx Context, version string) Context {
|
||||||
|
ctx = WithValue(ctx, "version", version)
|
||||||
|
// push a new logger onto the stack
|
||||||
|
return WithLogger(ctx, GetLogger(ctx, "version"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVersion returns the application version from the context. An empty
|
||||||
|
// string may returned if the version was not set on the context.
|
||||||
|
func GetVersion(ctx Context) string {
|
||||||
|
return GetStringValue(ctx, "version")
|
||||||
|
}
|
19
context/version_test.go
Normal file
19
context/version_test.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package context
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestVersionContext(t *testing.T) {
|
||||||
|
ctx := Background()
|
||||||
|
|
||||||
|
if GetVersion(ctx) != "" {
|
||||||
|
t.Fatalf("context should not yet have a version")
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := "2.1-whatever"
|
||||||
|
ctx = WithVersion(ctx, expected)
|
||||||
|
version := GetVersion(ctx)
|
||||||
|
|
||||||
|
if version != expected {
|
||||||
|
t.Fatalf("version was not set: %q != %q", version, expected)
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,8 +77,6 @@ func NewApp(ctx context.Context, configuration *configuration.Configuration) *Ap
|
||||||
isCache: configuration.Proxy.RemoteURL != "",
|
isCache: configuration.Proxy.RemoteURL != "",
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Context = ctxu.WithLogger(app.Context, ctxu.GetLogger(app, "instance.id"))
|
|
||||||
|
|
||||||
// Register the handler dispatchers.
|
// Register the handler dispatchers.
|
||||||
app.register(v2.RouteNameBase, func(ctx *Context, r *http.Request) http.Handler {
|
app.register(v2.RouteNameBase, func(ctx *Context, r *http.Request) http.Handler {
|
||||||
return http.HandlerFunc(apiBase)
|
return http.HandlerFunc(apiBase)
|
||||||
|
|
|
@ -35,6 +35,9 @@ var Cmd = &cobra.Command{
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup context
|
||||||
|
ctx := context.WithVersion(context.Background(), version.Version)
|
||||||
|
|
||||||
config, err := resolveConfiguration(args)
|
config, err := resolveConfiguration(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "configuration error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "configuration error: %v\n", err)
|
||||||
|
@ -51,7 +54,7 @@ var Cmd = &cobra.Command{
|
||||||
}(config.HTTP.Debug.Addr)
|
}(config.HTTP.Debug.Addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
registry, err := NewRegistry(context.Background(), config)
|
registry, err := NewRegistry(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
@ -78,9 +81,6 @@ type Registry struct {
|
||||||
|
|
||||||
// NewRegistry creates a new registry from a context and configuration struct.
|
// NewRegistry creates a new registry from a context and configuration struct.
|
||||||
func NewRegistry(ctx context.Context, config *configuration.Configuration) (*Registry, error) {
|
func NewRegistry(ctx context.Context, config *configuration.Configuration) (*Registry, error) {
|
||||||
// Note this
|
|
||||||
ctx = context.WithValue(ctx, "version", version.Version)
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
ctx, err = configureLogging(ctx, config)
|
ctx, err = configureLogging(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -218,7 +218,7 @@ func configureLogging(ctx context.Context, config *configuration.Configuration)
|
||||||
if config.Log.Level == "" && config.Log.Formatter == "" {
|
if config.Log.Level == "" && config.Log.Formatter == "" {
|
||||||
// If no config for logging is set, fallback to deprecated "Loglevel".
|
// If no config for logging is set, fallback to deprecated "Loglevel".
|
||||||
log.SetLevel(logLevel(config.Loglevel))
|
log.SetLevel(logLevel(config.Loglevel))
|
||||||
ctx = context.WithLogger(ctx, context.GetLogger(ctx, "version"))
|
ctx = context.WithLogger(ctx, context.GetLogger(ctx))
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,9 +253,6 @@ func configureLogging(ctx context.Context, config *configuration.Configuration)
|
||||||
log.Debugf("using %q logging formatter", config.Log.Formatter)
|
log.Debugf("using %q logging formatter", config.Log.Formatter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log the application version with messages
|
|
||||||
ctx = context.WithLogger(ctx, context.GetLogger(ctx, "version"))
|
|
||||||
|
|
||||||
if len(config.Log.Fields) > 0 {
|
if len(config.Log.Fields) > 0 {
|
||||||
// build up the static fields, if present.
|
// build up the static fields, if present.
|
||||||
var fields []interface{}
|
var fields []interface{}
|
||||||
|
|
Loading…
Reference in a new issue