Update dockerd to support JSON logging format
Update docker to support a '--log-format' option, which accepts either 'text' (default) or 'json'. Propagate the log format to containerd as well, to ensure that everything will be logged consistently. Signed-off-by: Philip K. Warren <pkwarren@gmail.com>
This commit is contained in:
parent
d2452c2102
commit
a08abec9f8
5 changed files with 71 additions and 5 deletions
|
@ -478,6 +478,7 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
|
|||
conf.Debug = opts.Debug
|
||||
conf.Hosts = opts.Hosts
|
||||
conf.LogLevel = opts.LogLevel
|
||||
conf.LogFormat = opts.LogFormat
|
||||
|
||||
if flags.Changed(FlagTLS) {
|
||||
conf.TLS = &opts.TLS
|
||||
|
@ -657,6 +658,10 @@ func (cli *DaemonCli) getContainerdDaemonOpts() ([]supervisor.DaemonOpt, error)
|
|||
opts = append(opts, supervisor.WithLogLevel(cli.LogLevel))
|
||||
}
|
||||
|
||||
if logFormat := cli.Config.LogFormat; logFormat != "" {
|
||||
opts = append(opts, supervisor.WithLogFormat(logFormat))
|
||||
}
|
||||
|
||||
if !cli.CriContainerd {
|
||||
// CRI support in the managed daemon is currently opt-in.
|
||||
//
|
||||
|
@ -867,11 +872,26 @@ func configureDaemonLogs(conf *config.Config) {
|
|||
} else {
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
logrus.SetFormatter(&logrus.TextFormatter{
|
||||
TimestampFormat: jsonmessage.RFC3339NanoFixed,
|
||||
DisableColors: conf.RawLogs,
|
||||
FullTimestamp: true,
|
||||
})
|
||||
logFormat := conf.LogFormat
|
||||
if logFormat == "" {
|
||||
logFormat = log.TextFormat
|
||||
}
|
||||
var formatter logrus.Formatter
|
||||
switch logFormat {
|
||||
case log.JSONFormat:
|
||||
formatter = &logrus.JSONFormatter{
|
||||
TimestampFormat: jsonmessage.RFC3339NanoFixed,
|
||||
}
|
||||
case log.TextFormat:
|
||||
formatter = &logrus.TextFormatter{
|
||||
TimestampFormat: jsonmessage.RFC3339NanoFixed,
|
||||
DisableColors: conf.RawLogs,
|
||||
FullTimestamp: true,
|
||||
}
|
||||
default:
|
||||
panic("unsupported log format " + logFormat)
|
||||
}
|
||||
logrus.SetFormatter(formatter)
|
||||
}
|
||||
|
||||
func configureProxyEnv(conf *config.Config) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -155,6 +156,26 @@ func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
|
|||
assert.Check(t, is.Equal("warn", loadedConfig.LogLevel))
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliConfigWithLogFormat(t *testing.T) {
|
||||
tempFile := fs.NewFile(t, "config", fs.WithContent(`{"log-format": "json"}`))
|
||||
defer tempFile.Remove()
|
||||
|
||||
opts := defaultOptions(t, tempFile.Path())
|
||||
loadedConfig, err := loadDaemonCliConfig(opts)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, loadedConfig != nil)
|
||||
assert.Check(t, is.Equal(log.JSONFormat, loadedConfig.LogFormat))
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliConfigWithInvalidLogFormat(t *testing.T) {
|
||||
tempFile := fs.NewFile(t, "config", fs.WithContent(`{"log-format": "foo"}`))
|
||||
defer tempFile.Remove()
|
||||
|
||||
opts := defaultOptions(t, tempFile.Path())
|
||||
_, err := loadDaemonCliConfig(opts)
|
||||
assert.Check(t, is.ErrorContains(err, "invalid log format: foo"))
|
||||
}
|
||||
|
||||
func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
|
||||
content := `{"tlscacert": "/etc/certs/ca.pem", "log-driver": "syslog"}`
|
||||
tempFile := fs.NewFile(t, "config", fs.WithContent(content))
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/docker/docker/opts"
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
|
@ -72,6 +74,7 @@ type daemonOptions struct {
|
|||
Debug bool
|
||||
Hosts []string
|
||||
LogLevel string
|
||||
LogFormat string
|
||||
TLS bool
|
||||
TLSVerify bool
|
||||
TLSOptions *tlsconfig.Options
|
||||
|
@ -104,6 +107,8 @@ func (o *daemonOptions) installFlags(flags *pflag.FlagSet) {
|
|||
flags.BoolVarP(&o.Debug, "debug", "D", false, "Enable debug mode")
|
||||
flags.BoolVar(&o.Validate, "validate", false, "Validate daemon configuration and exit")
|
||||
flags.StringVarP(&o.LogLevel, "log-level", "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`)
|
||||
flags.StringVar(&o.LogFormat, "log-format", log.TextFormat,
|
||||
fmt.Sprintf(`Set the logging format ("%s"|"%s")`, log.TextFormat, log.JSONFormat))
|
||||
flags.BoolVar(&o.TLS, FlagTLS, DefaultTLSValue, "Use TLS; implied by --tlsverify")
|
||||
flags.BoolVar(&o.TLSVerify, FlagTLSVerify, dockerTLSVerify || DefaultTLSValue, "Use TLS and verify the remote")
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ type CommonConfig struct {
|
|||
Debug bool `json:"debug,omitempty"`
|
||||
Hosts []string `json:"hosts,omitempty"`
|
||||
LogLevel string `json:"log-level,omitempty"`
|
||||
LogFormat string `json:"log-format,omitempty"`
|
||||
TLS *bool `json:"tls,omitempty"`
|
||||
TLSVerify *bool `json:"tlsverify,omitempty"`
|
||||
|
||||
|
@ -594,6 +595,16 @@ func Validate(config *Config) error {
|
|||
}
|
||||
}
|
||||
|
||||
// validate log-format
|
||||
if logFormat := config.LogFormat; logFormat != "" {
|
||||
switch logFormat {
|
||||
case log.TextFormat, log.JSONFormat:
|
||||
// These are valid
|
||||
default:
|
||||
return errors.Errorf("invalid log format: %s", logFormat)
|
||||
}
|
||||
}
|
||||
|
||||
// validate DNS
|
||||
for _, dns := range config.DNS {
|
||||
if _, err := opts.ValidateIPAddress(dns); err != nil {
|
||||
|
|
|
@ -13,6 +13,15 @@ func WithLogLevel(lvl string) DaemonOpt {
|
|||
}
|
||||
}
|
||||
|
||||
// WithLogFormat defines the containerd log format.
|
||||
// This only makes sense if WithStartDaemon() was set to true.
|
||||
func WithLogFormat(format string) DaemonOpt {
|
||||
return func(r *remote) error {
|
||||
r.Debug.Format = format
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCRIDisabled disables the CRI plugin.
|
||||
func WithCRIDisabled() DaemonOpt {
|
||||
return func(r *remote) error {
|
||||
|
|
Loading…
Reference in a new issue