diff --git a/cmd/containerd/command/main.go b/cmd/containerd/command/main.go index de5070423..dc8481daa 100644 --- a/cmd/containerd/command/main.go +++ b/cmd/containerd/command/main.go @@ -51,11 +51,6 @@ high performance container runtime ` func init() { - logrus.SetFormatter(&logrus.TextFormatter{ - TimestampFormat: log.RFC3339NanoFixed, - FullTimestamp: true, - }) - // Discard grpc logs so that they don't mess with our stdio grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard)) @@ -252,7 +247,10 @@ func serve(ctx gocontext.Context, l net.Listener, serveFunc func(net.Listener) e func applyFlags(context *cli.Context, config *srvconfig.Config) error { // the order for config vs flag values is that flags will always override // the config values if they are set - if err := setLevel(context, config); err != nil { + if err := setLogLevel(context, config); err != nil { + return err + } + if err := setLogFormat(config); err != nil { return err } for _, v := range []struct { @@ -282,7 +280,7 @@ func applyFlags(context *cli.Context, config *srvconfig.Config) error { return nil } -func setLevel(context *cli.Context, config *srvconfig.Config) error { +func setLogLevel(context *cli.Context, config *srvconfig.Config) error { l := context.GlobalString("log-level") if l == "" { l = config.Debug.Level @@ -297,6 +295,29 @@ func setLevel(context *cli.Context, config *srvconfig.Config) error { return nil } +func setLogFormat(config *srvconfig.Config) error { + f := config.Debug.Format + if f == "" { + f = log.TextFormat + } + + switch f { + case log.TextFormat: + logrus.SetFormatter(&logrus.TextFormatter{ + TimestampFormat: log.RFC3339NanoFixed, + FullTimestamp: true, + }) + case log.JSONFormat: + logrus.SetFormatter(&logrus.JSONFormatter{ + TimestampFormat: log.RFC3339NanoFixed, + }) + default: + return errors.Errorf("unknown log format: %s", f) + } + + return nil +} + func dumpStacks(writeToFile bool) { var ( buf []byte diff --git a/log/context.go b/log/context.go index 21599c4fd..37b6a7d1c 100644 --- a/log/context.go +++ b/log/context.go @@ -37,9 +37,17 @@ type ( loggerKey struct{} ) -// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to -// ensure the formatted time is always the same number of characters. -const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" +const ( + // RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to + // ensure the formatted time is always the same number of characters. + RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" + + // TextFormat represents the text logging format + TextFormat = "text" + + // JSONFormat represents the JSON logging format + JSONFormat = "json" +) // WithLogger returns a new context with the provided logger. Use in // combination with logger.WithField(s) for great effect. diff --git a/services/server/config/config.go b/services/server/config/config.go index dbe42128b..85c72f0d3 100644 --- a/services/server/config/config.go +++ b/services/server/config/config.go @@ -138,6 +138,8 @@ type Debug struct { UID int `toml:"uid"` GID int `toml:"gid"` Level string `toml:"level"` + // Format represents the logging format + Format string `toml:"format"` } // MetricsConfig provides metrics configuration