Disassociate instance id from application
This moves the instance id out of the app so that it is associated with an instantiation of the runtime. The instance id is stored on the background context. This allows allow contexts using the main background context to include an instance id for log messages. It also simplifies the application slightly. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
37f600a498
commit
4d91e791c0
3 changed files with 42 additions and 36 deletions
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/Sirupsen/logrus/formatters/logstash"
|
"github.com/Sirupsen/logrus/formatters/logstash"
|
||||||
"github.com/bugsnag/bugsnag-go"
|
"github.com/bugsnag/bugsnag-go"
|
||||||
"github.com/docker/distribution/configuration"
|
"github.com/docker/distribution/configuration"
|
||||||
ctxu "github.com/docker/distribution/context"
|
"github.com/docker/distribution/context"
|
||||||
_ "github.com/docker/distribution/health"
|
_ "github.com/docker/distribution/health"
|
||||||
_ "github.com/docker/distribution/registry/auth/silly"
|
_ "github.com/docker/distribution/registry/auth/silly"
|
||||||
_ "github.com/docker/distribution/registry/auth/token"
|
_ "github.com/docker/distribution/registry/auth/token"
|
||||||
|
@ -28,7 +28,6 @@ import (
|
||||||
"github.com/docker/distribution/version"
|
"github.com/docker/distribution/version"
|
||||||
gorhandlers "github.com/gorilla/handlers"
|
gorhandlers "github.com/gorilla/handlers"
|
||||||
"github.com/yvasiyarov/gorelic"
|
"github.com/yvasiyarov/gorelic"
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var showVersion bool
|
var showVersion bool
|
||||||
|
@ -67,9 +66,9 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.HTTP.TLS.Certificate == "" {
|
if config.HTTP.TLS.Certificate == "" {
|
||||||
ctxu.GetLogger(app).Infof("listening on %v", config.HTTP.Addr)
|
context.GetLogger(app).Infof("listening on %v", config.HTTP.Addr)
|
||||||
if err := http.ListenAndServe(config.HTTP.Addr, handler); err != nil {
|
if err := http.ListenAndServe(config.HTTP.Addr, handler); err != nil {
|
||||||
ctxu.GetLogger(app).Fatalln(err)
|
context.GetLogger(app).Fatalln(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tlsConf := &tls.Config{
|
tlsConf := &tls.Config{
|
||||||
|
@ -82,23 +81,23 @@ func main() {
|
||||||
for _, ca := range config.HTTP.TLS.ClientCAs {
|
for _, ca := range config.HTTP.TLS.ClientCAs {
|
||||||
caPem, err := ioutil.ReadFile(ca)
|
caPem, err := ioutil.ReadFile(ca)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxu.GetLogger(app).Fatalln(err)
|
context.GetLogger(app).Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok := pool.AppendCertsFromPEM(caPem); !ok {
|
if ok := pool.AppendCertsFromPEM(caPem); !ok {
|
||||||
ctxu.GetLogger(app).Fatalln(fmt.Errorf("Could not add CA to pool"))
|
context.GetLogger(app).Fatalln(fmt.Errorf("Could not add CA to pool"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, subj := range pool.Subjects() {
|
for _, subj := range pool.Subjects() {
|
||||||
ctxu.GetLogger(app).Debugf("CA Subject: %s", string(subj))
|
context.GetLogger(app).Debugf("CA Subject: %s", string(subj))
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConf.ClientAuth = tls.RequireAndVerifyClientCert
|
tlsConf.ClientAuth = tls.RequireAndVerifyClientCert
|
||||||
tlsConf.ClientCAs = pool
|
tlsConf.ClientCAs = pool
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxu.GetLogger(app).Infof("listening on %v, tls", config.HTTP.Addr)
|
context.GetLogger(app).Infof("listening on %v, tls", config.HTTP.Addr)
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: config.HTTP.Addr,
|
Addr: config.HTTP.Addr,
|
||||||
Handler: handler,
|
Handler: handler,
|
||||||
|
@ -106,7 +105,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := server.ListenAndServeTLS(config.HTTP.TLS.Certificate, config.HTTP.TLS.Key); err != nil {
|
if err := server.ListenAndServeTLS(config.HTTP.TLS.Certificate, config.HTTP.TLS.Key); err != nil {
|
||||||
ctxu.GetLogger(app).Fatalln(err)
|
context.GetLogger(app).Fatalln(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +189,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 = ctxu.WithLogger(ctx, ctxu.GetLogger(ctx, "version"))
|
ctx = context.WithLogger(ctx, context.GetLogger(ctx, "version"))
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,8 +223,8 @@ func configureLogging(ctx context.Context, config *configuration.Configuration)
|
||||||
fields = append(fields, k)
|
fields = append(fields, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = ctxu.WithValues(ctx, config.Log.Fields)
|
ctx = context.WithValues(ctx, config.Log.Fields)
|
||||||
ctx = ctxu.WithLogger(ctx, ctxu.GetLogger(ctx, fields...))
|
ctx = context.WithLogger(ctx, context.GetLogger(ctx, fields...))
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.google.com/p/go-uuid/uuid"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,9 +10,31 @@ type Context interface {
|
||||||
context.Context
|
context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background returns a non-nil, empty Context.
|
// instanceContext is a context that provides only an instance id. It is
|
||||||
|
// provided as the main background context.
|
||||||
|
type instanceContext struct {
|
||||||
|
Context
|
||||||
|
id string // id of context, logged as "instance.id"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *instanceContext) Value(key interface{}) interface{} {
|
||||||
|
if key == "instance.id" {
|
||||||
|
return ic.id
|
||||||
|
}
|
||||||
|
|
||||||
|
return ic.Context.Value(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
var background = &instanceContext{
|
||||||
|
Context: context.Background(),
|
||||||
|
id: uuid.New(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background returns a non-nil, empty Context. The background context
|
||||||
|
// provides a single key, "instance.id" that is globally unique to the
|
||||||
|
// process.
|
||||||
func Background() Context {
|
func Background() Context {
|
||||||
return context.Background()
|
return background
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithValue returns a copy of parent in which the value associated with key is
|
// WithValue returns a copy of parent in which the value associated with key is
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.google.com/p/go-uuid/uuid"
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/configuration"
|
"github.com/docker/distribution/configuration"
|
||||||
ctxu "github.com/docker/distribution/context"
|
ctxu "github.com/docker/distribution/context"
|
||||||
|
@ -32,11 +31,8 @@ import (
|
||||||
// fields should be protected.
|
// fields should be protected.
|
||||||
type App struct {
|
type App struct {
|
||||||
context.Context
|
context.Context
|
||||||
Config configuration.Configuration
|
|
||||||
|
|
||||||
// InstanceID is a unique id assigned to the application on each creation.
|
Config configuration.Configuration
|
||||||
// Provides information in the logs and context to identify restarts.
|
|
||||||
InstanceID string
|
|
||||||
|
|
||||||
router *mux.Router // main application router, configured with dispatchers
|
router *mux.Router // main application router, configured with dispatchers
|
||||||
driver storagedriver.StorageDriver // driver maintains the app global storage driver instance.
|
driver storagedriver.StorageDriver // driver maintains the app global storage driver instance.
|
||||||
|
@ -52,29 +48,17 @@ type App struct {
|
||||||
redis *redis.Pool
|
redis *redis.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value intercepts calls context.Context.Value, returning the current app id,
|
|
||||||
// if requested.
|
|
||||||
func (app *App) Value(key interface{}) interface{} {
|
|
||||||
switch key {
|
|
||||||
case "app.id":
|
|
||||||
return app.InstanceID
|
|
||||||
}
|
|
||||||
|
|
||||||
return app.Context.Value(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewApp takes a configuration and returns a configured app, ready to serve
|
// NewApp takes a configuration and returns a configured app, ready to serve
|
||||||
// requests. The app only implements ServeHTTP and can be wrapped in other
|
// requests. The app only implements ServeHTTP and can be wrapped in other
|
||||||
// handlers accordingly.
|
// handlers accordingly.
|
||||||
func NewApp(ctx context.Context, configuration configuration.Configuration) *App {
|
func NewApp(ctx context.Context, configuration configuration.Configuration) *App {
|
||||||
app := &App{
|
app := &App{
|
||||||
Config: configuration,
|
Config: configuration,
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
InstanceID: uuid.New(),
|
router: v2.RouterWithPrefix(configuration.HTTP.Prefix),
|
||||||
router: v2.RouterWithPrefix(configuration.HTTP.Prefix),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Context = ctxu.WithLogger(app.Context, ctxu.GetLogger(app, "app.id"))
|
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 {
|
||||||
|
@ -200,7 +184,7 @@ func (app *App) configureEvents(configuration *configuration.Configuration) {
|
||||||
|
|
||||||
app.events.source = notifications.SourceRecord{
|
app.events.source = notifications.SourceRecord{
|
||||||
Addr: hostname,
|
Addr: hostname,
|
||||||
InstanceID: app.InstanceID,
|
InstanceID: ctxu.GetStringValue(app, "instance.id"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue