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>
| ... | ... |
@@ -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 |
-} |