Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions cmd/dockerd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
//
Expand Down Expand Up @@ -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) {
Expand Down
21 changes: 21 additions & 0 deletions cmd/dockerd/daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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))
Expand Down
5 changes: 5 additions & 0 deletions cmd/dockerd/options.go
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -72,6 +74,7 @@ type daemonOptions struct {
Debug bool
Hosts []string
LogLevel string
LogFormat string
TLS bool
TLSVerify bool
TLSOptions *tlsconfig.Options
Expand Down Expand Up @@ -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")

Expand Down
11 changes: 11 additions & 0 deletions daemon/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`

Expand Down Expand Up @@ -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 {
Expand Down
9 changes: 9 additions & 0 deletions libcontainerd/supervisor/remote_daemon_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down