mirror of https://github.com/docker/docs.git
Merge pull request #19794 from calavera/14358-disable-colors
[Carry 18621] Allow disabling of colored Docker logs via daemon flag.
This commit is contained in:
commit
85475f7dea
|
@ -748,6 +748,7 @@ _docker_daemon() {
|
||||||
--ip-masq=false
|
--ip-masq=false
|
||||||
--iptables=false
|
--iptables=false
|
||||||
--ipv6
|
--ipv6
|
||||||
|
--raw-logs
|
||||||
--selinux-enabled
|
--selinux-enabled
|
||||||
--userland-proxy=false
|
--userland-proxy=false
|
||||||
"
|
"
|
||||||
|
|
|
@ -666,6 +666,7 @@ __docker_subcommand() {
|
||||||
"($help)*--log-opt=[Log driver specific options]:log driver options:__docker_log_options" \
|
"($help)*--log-opt=[Log driver specific options]:log driver options:__docker_log_options" \
|
||||||
"($help)--mtu=[Set the containers network MTU]:mtu:(0 576 1420 1500 9000)" \
|
"($help)--mtu=[Set the containers network MTU]:mtu:(0 576 1420 1500 9000)" \
|
||||||
"($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \
|
"($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \
|
||||||
|
"($help)--raw-logs[Full timestamps without ANSI coloring]" \
|
||||||
"($help)*--registry-mirror=[Preferred Docker registry mirror]:registry mirror: " \
|
"($help)*--registry-mirror=[Preferred Docker registry mirror]:registry mirror: " \
|
||||||
"($help -s --storage-driver)"{-s=,--storage-driver=}"[Storage driver to use]:driver:(aufs devicemapper btrfs zfs overlay)" \
|
"($help -s --storage-driver)"{-s=,--storage-driver=}"[Storage driver to use]:driver:(aufs devicemapper btrfs zfs overlay)" \
|
||||||
"($help)--selinux-enabled[Enable selinux support]" \
|
"($help)--selinux-enabled[Enable selinux support]" \
|
||||||
|
|
|
@ -39,7 +39,7 @@ script
|
||||||
if [ -f /etc/default/$UPSTART_JOB ]; then
|
if [ -f /etc/default/$UPSTART_JOB ]; then
|
||||||
. /etc/default/$UPSTART_JOB
|
. /etc/default/$UPSTART_JOB
|
||||||
fi
|
fi
|
||||||
exec "$DOCKER" daemon $DOCKER_OPTS
|
exec "$DOCKER" daemon $DOCKER_OPTS --raw-logs
|
||||||
end script
|
end script
|
||||||
|
|
||||||
# Don't emit "started" event until docker.sock is ready.
|
# Don't emit "started" event until docker.sock is ready.
|
||||||
|
|
|
@ -57,6 +57,7 @@ type CommonConfig struct {
|
||||||
Labels []string `json:"labels,omitempty"`
|
Labels []string `json:"labels,omitempty"`
|
||||||
Mtu int `json:"mtu,omitempty"`
|
Mtu int `json:"mtu,omitempty"`
|
||||||
Pidfile string `json:"pidfile,omitempty"`
|
Pidfile string `json:"pidfile,omitempty"`
|
||||||
|
RawLogs bool `json:"raw-logs,omitempty"`
|
||||||
Root string `json:"graph,omitempty"`
|
Root string `json:"graph,omitempty"`
|
||||||
TrustKeyPath string `json:"-"`
|
TrustKeyPath string `json:"-"`
|
||||||
|
|
||||||
|
@ -104,6 +105,7 @@ func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string)
|
||||||
cmd.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, usageFn("--restart on the daemon has been deprecated in favor of --restart policies on docker run"))
|
cmd.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, usageFn("--restart on the daemon has been deprecated in favor of --restart policies on docker run"))
|
||||||
cmd.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", usageFn("Storage driver to use"))
|
cmd.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", usageFn("Storage driver to use"))
|
||||||
cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU"))
|
cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU"))
|
||||||
|
cmd.BoolVar(&config.RawLogs, []string{"-raw-logs"}, false, usageFn("Full timestamps without ANSI coloring"))
|
||||||
// FIXME: why the inconsistency between "hosts" and "sockets"?
|
// FIXME: why the inconsistency between "hosts" and "sockets"?
|
||||||
cmd.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use"))
|
cmd.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use"))
|
||||||
cmd.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), []string{"-dns-opt"}, usageFn("DNS options to use"))
|
cmd.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), []string{"-dns-opt"}, usageFn("DNS options to use"))
|
||||||
|
|
|
@ -168,7 +168,10 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
|
||||||
logrus.Warn("Running experimental build")
|
logrus.Warn("Running experimental build")
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.SetFormatter(&logrus.TextFormatter{TimestampFormat: jsonlog.RFC3339NanoFixed})
|
logrus.SetFormatter(&logrus.TextFormatter{
|
||||||
|
TimestampFormat: jsonlog.RFC3339NanoFixed,
|
||||||
|
DisableColors: cli.Config.RawLogs,
|
||||||
|
})
|
||||||
|
|
||||||
if err := setDefaultUmask(); err != nil {
|
if err := setDefaultUmask(); err != nil {
|
||||||
logrus.Fatalf("Failed to set umask: %v", err)
|
logrus.Fatalf("Failed to set umask: %v", err)
|
||||||
|
|
|
@ -54,6 +54,7 @@ weight = -1
|
||||||
--mtu=0 Set the containers network MTU
|
--mtu=0 Set the containers network MTU
|
||||||
--disable-legacy-registry Do not contact legacy registries
|
--disable-legacy-registry Do not contact legacy registries
|
||||||
-p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file
|
-p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file
|
||||||
|
--raw-logs Full timestamps without ANSI coloring
|
||||||
--registry-mirror=[] Preferred Docker registry mirror
|
--registry-mirror=[] Preferred Docker registry mirror
|
||||||
-s, --storage-driver="" Storage driver to use
|
-s, --storage-driver="" Storage driver to use
|
||||||
--selinux-enabled Enable selinux support
|
--selinux-enabled Enable selinux support
|
||||||
|
@ -872,7 +873,8 @@ This is a full example of the allowed configuration options in the file:
|
||||||
"fixed-cidr-v6": "",
|
"fixed-cidr-v6": "",
|
||||||
"default-gateway": "",
|
"default-gateway": "",
|
||||||
"default-gateway-v6": "",
|
"default-gateway-v6": "",
|
||||||
"icc": false
|
"icc": false,
|
||||||
|
"raw-logs": false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -22,6 +23,7 @@ import (
|
||||||
"github.com/docker/libnetwork/iptables"
|
"github.com/docker/libnetwork/iptables"
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
|
"github.com/kr/pty"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *DockerDaemonSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) {
|
func (s *DockerDaemonSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) {
|
||||||
|
@ -584,7 +586,7 @@ func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) {
|
||||||
c.Fatalf("Expected daemon not to start, got %v", err)
|
c.Fatalf("Expected daemon not to start, got %v", err)
|
||||||
}
|
}
|
||||||
// look in the log and make sure we got the message that daemon is shutting down
|
// look in the log and make sure we got the message that daemon is shutting down
|
||||||
runCmd := exec.Command("grep", "Error starting daemon", s.d.LogfileName())
|
runCmd := exec.Command("grep", "Error starting daemon", s.d.LogFileName())
|
||||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||||
c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err)
|
c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err)
|
||||||
}
|
}
|
||||||
|
@ -1759,7 +1761,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartLocalVolumes(c *check.C) {
|
||||||
func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) {
|
func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) {
|
||||||
c.Assert(s.d.Start("--log-driver=syslog", "--log-opt", "syslog-address=corrupted:42"), check.NotNil)
|
c.Assert(s.d.Start("--log-driver=syslog", "--log-opt", "syslog-address=corrupted:42"), check.NotNil)
|
||||||
expected := "Failed to set log opts: syslog-address should be in form proto://address"
|
expected := "Failed to set log opts: syslog-address should be in form proto://address"
|
||||||
runCmd := exec.Command("grep", expected, s.d.LogfileName())
|
runCmd := exec.Command("grep", expected, s.d.LogFileName())
|
||||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||||
c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err)
|
c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err)
|
||||||
}
|
}
|
||||||
|
@ -1768,7 +1770,7 @@ func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) {
|
||||||
func (s *DockerDaemonSuite) TestDaemonCorruptedFluentdAddress(c *check.C) {
|
func (s *DockerDaemonSuite) TestDaemonCorruptedFluentdAddress(c *check.C) {
|
||||||
c.Assert(s.d.Start("--log-driver=fluentd", "--log-opt", "fluentd-address=corrupted:c"), check.NotNil)
|
c.Assert(s.d.Start("--log-driver=fluentd", "--log-opt", "fluentd-address=corrupted:c"), check.NotNil)
|
||||||
expected := "Failed to set log opts: invalid fluentd-address corrupted:c: "
|
expected := "Failed to set log opts: invalid fluentd-address corrupted:c: "
|
||||||
runCmd := exec.Command("grep", expected, s.d.LogfileName())
|
runCmd := exec.Command("grep", expected, s.d.LogFileName())
|
||||||
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
||||||
c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err)
|
c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err)
|
||||||
}
|
}
|
||||||
|
@ -1922,7 +1924,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartContainerLinksRestart(c *check.C) {
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
// clear the log file -- we don't need any of it but may for the next part
|
// clear the log file -- we don't need any of it but may for the next part
|
||||||
// can ignore the error here, this is just a cleanup
|
// can ignore the error here, this is just a cleanup
|
||||||
os.Truncate(d.LogfileName(), 0)
|
os.Truncate(d.LogFileName(), 0)
|
||||||
err = d.Start()
|
err = d.Start()
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
@ -1930,7 +1932,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartContainerLinksRestart(c *check.C) {
|
||||||
out, err := d.Cmd("inspect", "-f", "{{ .State.Running }}", "parent"+num)
|
out, err := d.Cmd("inspect", "-f", "{{ .State.Running }}", "parent"+num)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
if strings.TrimSpace(out) != "true" {
|
if strings.TrimSpace(out) != "true" {
|
||||||
log, _ := ioutil.ReadFile(d.LogfileName())
|
log, _ := ioutil.ReadFile(d.LogFileName())
|
||||||
c.Fatalf("parent container is not running\n%s", string(log))
|
c.Fatalf("parent container is not running\n%s", string(log))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2064,3 +2066,32 @@ func (s *DockerDaemonSuite) TestRunLinksChanged(c *check.C) {
|
||||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||||
c.Assert(out, check.Not(checker.Contains), "1 packets transmitted, 1 packets received")
|
c.Assert(out, check.Not(checker.Contains), "1 packets transmitted, 1 packets received")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerDaemonSuite) TestDaemonStartWithoutColors(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsLinux)
|
||||||
|
newD := NewDaemon(c)
|
||||||
|
|
||||||
|
infoLog := "\x1b[34mINFO\x1b"
|
||||||
|
|
||||||
|
p, tty, err := pty.Open()
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
defer func() {
|
||||||
|
tty.Close()
|
||||||
|
p.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
b := bytes.NewBuffer(nil)
|
||||||
|
go io.Copy(b, p)
|
||||||
|
|
||||||
|
// Enable coloring explicitly
|
||||||
|
newD.StartWithLogFile(tty, "--raw-logs=false")
|
||||||
|
newD.Stop()
|
||||||
|
c.Assert(b.String(), checker.Contains, infoLog)
|
||||||
|
|
||||||
|
b.Reset()
|
||||||
|
|
||||||
|
// Disable coloring explicitly
|
||||||
|
newD.StartWithLogFile(tty, "--raw-logs=true")
|
||||||
|
newD.Stop()
|
||||||
|
c.Assert(b.String(), check.Not(checker.Contains), infoLog)
|
||||||
|
}
|
||||||
|
|
|
@ -299,7 +299,7 @@ func (s *DockerExternalGraphdriverSuite) TearDownSuite(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerExternalGraphdriverSuite) TestExternalGraphDriver(c *check.C) {
|
func (s *DockerExternalGraphdriverSuite) TestExternalGraphDriver(c *check.C) {
|
||||||
if err := s.d.StartWithBusybox("-s", "test-external-graph-driver"); err != nil {
|
if err := s.d.StartWithBusybox("-s", "test-external-graph-driver"); err != nil {
|
||||||
b, _ := ioutil.ReadFile(s.d.LogfileName())
|
b, _ := ioutil.ReadFile(s.d.LogFileName())
|
||||||
c.Assert(err, check.IsNil, check.Commentf("\n%s", string(b)))
|
c.Assert(err, check.IsNil, check.Commentf("\n%s", string(b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,15 @@ func (d *Daemon) getClientConfig() (*clientConfig, error) {
|
||||||
|
|
||||||
// Start will start the daemon and return once it is ready to receive requests.
|
// Start will start the daemon and return once it is ready to receive requests.
|
||||||
// You can specify additional daemon flags.
|
// You can specify additional daemon flags.
|
||||||
func (d *Daemon) Start(arg ...string) error {
|
func (d *Daemon) Start(args ...string) error {
|
||||||
|
logFile, err := os.OpenFile(filepath.Join(d.folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
|
||||||
|
d.c.Assert(err, check.IsNil, check.Commentf("[%s] Could not create %s/docker.log", d.id, d.folder))
|
||||||
|
|
||||||
|
return d.StartWithLogFile(logFile, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartWithLogFile will start the daemon and attach its streams to a given file.
|
||||||
|
func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
|
||||||
dockerBinary, err := exec.LookPath(dockerBinary)
|
dockerBinary, err := exec.LookPath(dockerBinary)
|
||||||
d.c.Assert(err, check.IsNil, check.Commentf("[%s] could not find docker binary in $PATH", d.id))
|
d.c.Assert(err, check.IsNil, check.Commentf("[%s] could not find docker binary in $PATH", d.id))
|
||||||
|
|
||||||
|
@ -226,7 +234,7 @@ func (d *Daemon) Start(arg ...string) error {
|
||||||
// turn on debug mode
|
// turn on debug mode
|
||||||
foundLog := false
|
foundLog := false
|
||||||
foundSd := false
|
foundSd := false
|
||||||
for _, a := range arg {
|
for _, a := range providedArgs {
|
||||||
if strings.Contains(a, "--log-level") || strings.Contains(a, "-D") || strings.Contains(a, "--debug") {
|
if strings.Contains(a, "--log-level") || strings.Contains(a, "-D") || strings.Contains(a, "--debug") {
|
||||||
foundLog = true
|
foundLog = true
|
||||||
}
|
}
|
||||||
|
@ -241,14 +249,12 @@ func (d *Daemon) Start(arg ...string) error {
|
||||||
args = append(args, "--storage-driver", d.storageDriver)
|
args = append(args, "--storage-driver", d.storageDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, arg...)
|
args = append(args, providedArgs...)
|
||||||
d.cmd = exec.Command(dockerBinary, args...)
|
d.cmd = exec.Command(dockerBinary, args...)
|
||||||
|
|
||||||
d.logFile, err = os.OpenFile(filepath.Join(d.folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
|
d.cmd.Stdout = out
|
||||||
d.c.Assert(err, check.IsNil, check.Commentf("[%s] Could not create %s/docker.log", d.id, d.folder))
|
d.cmd.Stderr = out
|
||||||
|
d.logFile = out
|
||||||
d.cmd.Stdout = d.logFile
|
|
||||||
d.cmd.Stderr = d.logFile
|
|
||||||
|
|
||||||
if err := d.cmd.Start(); err != nil {
|
if err := d.cmd.Start(); err != nil {
|
||||||
return fmt.Errorf("[%s] could not start daemon container: %v", d.id, err)
|
return fmt.Errorf("[%s] could not start daemon container: %v", d.id, err)
|
||||||
|
@ -472,8 +478,8 @@ func (d *Daemon) CmdWithArgs(daemonArgs []string, name string, arg ...string) (s
|
||||||
return string(b), err
|
return string(b), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogfileName returns the path the the daemon's log file
|
// LogFileName returns the path the the daemon's log file
|
||||||
func (d *Daemon) LogfileName() string {
|
func (d *Daemon) LogFileName() string {
|
||||||
return d.logFile.Name()
|
return d.logFile.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ docker-daemon - Enable daemon mode
|
||||||
[**--log-opt**[=*map[]*]]
|
[**--log-opt**[=*map[]*]]
|
||||||
[**--mtu**[=*0*]]
|
[**--mtu**[=*0*]]
|
||||||
[**-p**|**--pidfile**[=*/var/run/docker.pid*]]
|
[**-p**|**--pidfile**[=*/var/run/docker.pid*]]
|
||||||
|
[**--raw-logs**]
|
||||||
[**--registry-mirror**[=*[]*]]
|
[**--registry-mirror**[=*[]*]]
|
||||||
[**-s**|**--storage-driver**[=*STORAGE-DRIVER*]]
|
[**-s**|**--storage-driver**[=*STORAGE-DRIVER*]]
|
||||||
[**--selinux-enabled**]
|
[**--selinux-enabled**]
|
||||||
|
@ -197,6 +198,11 @@ unix://[/path/to/socket] to use.
|
||||||
**-p**, **--pidfile**=""
|
**-p**, **--pidfile**=""
|
||||||
Path to use for daemon PID file. Default is `/var/run/docker.pid`
|
Path to use for daemon PID file. Default is `/var/run/docker.pid`
|
||||||
|
|
||||||
|
**--raw-logs**
|
||||||
|
Output daemon logs in full timestamp format without ANSI coloring. If this flag is not set,
|
||||||
|
the daemon outputs condensed, colorized logs if a terminal is detected, or full ("raw")
|
||||||
|
output otherwise.
|
||||||
|
|
||||||
**--registry-mirror**=*<scheme>://<host>*
|
**--registry-mirror**=*<scheme>://<host>*
|
||||||
Prepend a registry mirror to be used for image pulls. May be specified multiple times.
|
Prepend a registry mirror to be used for image pulls. May be specified multiple times.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue