Browse code

Configure log-format earlier, and small refactor

Some messages are logged before the logrus format was set,
therefore resulting in inconsistent log-message formatting
during startup;

Before this patch;

```
dockerd --experimental
WARN[0000] Running experimental build
INFO[2018-11-24T11:24:05.615249610Z] libcontainerd: started new containerd process pid=132
INFO[2018-11-24T11:24:05.615348322Z] parsed scheme: "unix" module=grpc
...
```

With this patch applied;

```
dockerd --experimental
WARN[2018-11-24T13:41:51.199057259Z] Running experimental build
INFO[2018-11-24T13:41:51.200412645Z] libcontainerd: started new containerd process pid=293
INFO[2018-11-24T13:41:51.200523051Z] parsed scheme: "unix" module=grpc
```

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2018/11/24 22:39:08
Showing 4 changed files
... ...
@@ -83,6 +83,11 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
83 83
 	if cli.Config, err = loadDaemonCliConfig(opts); err != nil {
84 84
 		return err
85 85
 	}
86
+
87
+	if err := configureDaemonLogs(cli.Config); err != nil {
88
+		return err
89
+	}
90
+
86 91
 	cli.configFile = &opts.configFile
87 92
 	cli.flags = opts.flags
88 93
 
... ...
@@ -94,12 +99,6 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
94 94
 		logrus.Warn("Running experimental build")
95 95
 	}
96 96
 
97
-	logrus.SetFormatter(&logrus.TextFormatter{
98
-		TimestampFormat: jsonmessage.RFC3339NanoFixed,
99
-		DisableColors:   cli.Config.RawLogs,
100
-		FullTimestamp:   true,
101
-	})
102
-
103 97
 	system.InitLCOW(cli.Config.Experimental)
104 98
 
105 99
 	if err := setDefaultUmask(); err != nil {
... ...
@@ -471,9 +470,6 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
471 471
 		conf.TLS = true
472 472
 	}
473 473
 
474
-	// ensure that the log level is the one set after merging configurations
475
-	setLogLevel(conf.LogLevel)
476
-
477 474
 	return conf, nil
478 475
 }
479 476
 
... ...
@@ -670,3 +666,22 @@ func systemContainerdRunning() bool {
670 670
 	_, err := os.Lstat(containerddefaults.DefaultAddress)
671 671
 	return err == nil
672 672
 }
673
+
674
+// configureDaemonLogs sets the logrus logging level and formatting
675
+func configureDaemonLogs(conf *config.Config) error {
676
+	if conf.LogLevel != "" {
677
+		lvl, err := logrus.ParseLevel(conf.LogLevel)
678
+		if err != nil {
679
+			return fmt.Errorf("unable to parse logging level: %s", conf.LogLevel)
680
+		}
681
+		logrus.SetLevel(lvl)
682
+	} else {
683
+		logrus.SetLevel(logrus.InfoLevel)
684
+	}
685
+	logrus.SetFormatter(&logrus.TextFormatter{
686
+		TimestampFormat: jsonmessage.RFC3339NanoFixed,
687
+		DisableColors:   conf.RawLogs,
688
+		FullTimestamp:   true,
689
+	})
690
+	return nil
691
+}
... ...
@@ -146,7 +146,6 @@ func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
146 146
 	assert.NilError(t, err)
147 147
 	assert.Assert(t, loadedConfig != nil)
148 148
 	assert.Check(t, is.Equal("warn", loadedConfig.LogLevel))
149
-	assert.Check(t, is.Equal(logrus.WarnLevel, logrus.GetLevel()))
150 149
 }
151 150
 
152 151
 func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
... ...
@@ -180,3 +179,22 @@ func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
180 180
 	assert.Check(t, is.Len(loadedConfig.Mirrors, 1))
181 181
 	assert.Check(t, is.Len(loadedConfig.InsecureRegistries, 1))
182 182
 }
183
+
184
+func TestConfigureDaemonLogs(t *testing.T) {
185
+	conf := &config.Config{}
186
+	err := configureDaemonLogs(conf)
187
+	assert.NilError(t, err)
188
+	assert.Check(t, is.Equal(logrus.InfoLevel, logrus.GetLevel()))
189
+
190
+	conf.LogLevel = "warn"
191
+	err = configureDaemonLogs(conf)
192
+	assert.NilError(t, err)
193
+	assert.Check(t, is.Equal(logrus.WarnLevel, logrus.GetLevel()))
194
+
195
+	conf.LogLevel = "foobar"
196
+	err = configureDaemonLogs(conf)
197
+	assert.Error(t, err, "unable to parse logging level: foobar")
198
+
199
+	// log level should not be changed after a failure
200
+	assert.Check(t, is.Equal(logrus.WarnLevel, logrus.GetLevel()))
201
+}
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"github.com/docker/docker/cli"
9 9
 	"github.com/docker/docker/daemon/config"
10 10
 	"github.com/docker/docker/dockerversion"
11
+	"github.com/docker/docker/pkg/jsonmessage"
11 12
 	"github.com/docker/docker/pkg/reexec"
12 13
 	"github.com/docker/docker/pkg/term"
13 14
 	"github.com/moby/buildkit/util/apicaps"
... ...
@@ -54,6 +55,12 @@ func main() {
54 54
 		return
55 55
 	}
56 56
 
57
+	// initial log formatting; this setting is updated after the daemon configuration is loaded.
58
+	logrus.SetFormatter(&logrus.TextFormatter{
59
+		TimestampFormat: jsonmessage.RFC3339NanoFixed,
60
+		FullTimestamp:   true,
61
+	})
62
+
57 63
 	// Set terminal emulation based on platform as required.
58 64
 	_, stdout, stderr := term.StdStreams()
59 65
 
... ...
@@ -1,7 +1,6 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"fmt"
5 4
 	"os"
6 5
 	"path/filepath"
7 6
 
... ...
@@ -9,7 +8,6 @@ import (
9 9
 	"github.com/docker/docker/daemon/config"
10 10
 	"github.com/docker/docker/opts"
11 11
 	"github.com/docker/go-connections/tlsconfig"
12
-	"github.com/sirupsen/logrus"
13 12
 	"github.com/spf13/pflag"
14 13
 )
15 14
 
... ...
@@ -106,17 +104,3 @@ func (o *daemonOptions) SetDefaultOptions(flags *pflag.FlagSet) {
106 106
 		}
107 107
 	}
108 108
 }
109
-
110
-// setLogLevel sets the logrus logging level
111
-func setLogLevel(logLevel string) {
112
-	if logLevel != "" {
113
-		lvl, err := logrus.ParseLevel(logLevel)
114
-		if err != nil {
115
-			fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", logLevel)
116
-			os.Exit(1)
117
-		}
118
-		logrus.SetLevel(lvl)
119
-	} else {
120
-		logrus.SetLevel(logrus.InfoLevel)
121
-	}
122
-}