diff --git a/daemon/attach.go b/daemon/attach.go index 64a1223a4d..047828b17d 100644 --- a/daemon/attach.go +++ b/daemon/attach.go @@ -68,7 +68,7 @@ func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *Containe func (daemon *Daemon) attachWithLogs(container *Container, stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error { if logs { - logDriver, err := container.getLogger() + logDriver, err := daemon.getLogger(container) if err != nil { return err } diff --git a/daemon/container.go b/daemon/container.go index 87b0e009da..f4c6b84d85 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -281,7 +281,7 @@ func (container *Container) exposes(p nat.Port) bool { return exists } -func (container *Container) getLogConfig() runconfig.LogConfig { +func (container *Container) getLogConfig(defaultConfig runconfig.LogConfig) runconfig.LogConfig { cfg := container.hostConfig.LogConfig if cfg.Type != "" || len(cfg.Config) > 0 { // container has log driver configured if cfg.Type == "" { @@ -290,17 +290,11 @@ func (container *Container) getLogConfig() runconfig.LogConfig { return cfg } // Use daemon's default log config for containers - return container.daemon.defaultLogConfig + return defaultConfig } -func (container *Container) getLogger() (logger.Logger, error) { - if container.logDriver != nil && container.IsRunning() { - return container.logDriver, nil - } - cfg := container.getLogConfig() - if err := logger.ValidateLogOpts(cfg.Type, cfg.Config); err != nil { - return nil, err - } +// StartLogger starts a new logger driver for the container. +func (container *Container) StartLogger(cfg runconfig.LogConfig) (logger.Logger, error) { c, err := logger.GetLogDriver(cfg.Type) if err != nil { return nil, derr.ErrorCodeLoggingFactory.WithArgs(err) @@ -328,30 +322,6 @@ func (container *Container) getLogger() (logger.Logger, error) { return c(ctx) } -func (container *Container) startLogging() error { - cfg := container.getLogConfig() - if cfg.Type == "none" { - return nil // do not start logging routines - } - - l, err := container.getLogger() - if err != nil { - return derr.ErrorCodeInitLogger.WithArgs(err) - } - - copier := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l) - container.logCopier = copier - copier.Run() - container.logDriver = l - - // set LogPath field only for json-file logdriver - if jl, ok := l.(*jsonfilelog.JSONFileLogger); ok { - container.LogPath = jl.LogPath() - } - - return nil -} - func (container *Container) getProcessLabel() string { // even if we have a process label return "" if we are running // in privileged mode diff --git a/daemon/logs.go b/daemon/logs.go index e4a4853c39..f3fa866a63 100644 --- a/daemon/logs.go +++ b/daemon/logs.go @@ -7,6 +7,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/logger" + "github.com/docker/docker/daemon/logger/jsonfilelog" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/stdcopy" ) @@ -48,7 +49,7 @@ func (daemon *Daemon) ContainerLogs(containerName string, config *ContainerLogsC } config.OutStream = outStream - cLog, err := container.getLogger() + cLog, err := daemon.getLogger(container) if err != nil { return err } @@ -97,3 +98,42 @@ func (daemon *Daemon) ContainerLogs(containerName string, config *ContainerLogsC } } } + +func (daemon *Daemon) getLogger(container *Container) (logger.Logger, error) { + if container.logDriver != nil && container.IsRunning() { + return container.logDriver, nil + } + cfg := container.getLogConfig(daemon.defaultLogConfig) + if err := logger.ValidateLogOpts(cfg.Type, cfg.Config); err != nil { + return nil, err + } + return container.StartLogger(cfg) +} + +// StartLogging initializes and starts the container logging stream. +func (daemon *Daemon) StartLogging(container *Container) error { + cfg := container.getLogConfig(daemon.defaultLogConfig) + if cfg.Type == "none" { + return nil // do not start logging routines + } + + if err := logger.ValidateLogOpts(cfg.Type, cfg.Config); err != nil { + return err + } + l, err := container.StartLogger(cfg) + if err != nil { + return derr.ErrorCodeInitLogger.WithArgs(err) + } + + copier := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l) + container.logCopier = copier + copier.Run() + container.logDriver = l + + // set LogPath field only for json-file logdriver + if jl, ok := l.(*jsonfilelog.JSONFileLogger); ok { + container.LogPath = jl.LogPath() + } + + return nil +} diff --git a/daemon/monitor.go b/daemon/monitor.go index 3512cbd1cd..4f37d0ef12 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -23,6 +23,8 @@ type containerSupervisor interface { LogContainerEvent(*Container, string) // Cleanup ensures that the container is properly unmounted Cleanup(*Container) + // StartLogging starts the logging driver for the container + StartLogging(*Container) error } // containerMonitor monitors the execution of a container's main process. @@ -142,7 +144,7 @@ func (m *containerMonitor) Start() error { for { m.container.RestartCount++ - if err := m.container.startLogging(); err != nil { + if err := m.supervisor.StartLogging(m.container); err != nil { m.resetContainer(false) return err