1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Close logger only after StartLogger call

Signed-off-by: Jim Minter <jminter@redhat.com>
This commit is contained in:
Jim Minter 2017-04-20 11:17:06 +01:00
parent 32ca1214fa
commit 68e71aa3e6
2 changed files with 29 additions and 23 deletions

View file

@ -102,15 +102,23 @@ func (daemon *Daemon) ContainerAttachRaw(prefixOrName string, stdin io.ReadClose
func (daemon *Daemon) containerAttach(c *container.Container, cfg *stream.AttachConfig, logs, doStream bool) error {
if logs {
logDriver, err := daemon.getLogger(c)
logDriver, logCreated, err := daemon.getLogger(c)
if err != nil {
return err
}
if logCreated {
defer func() {
if err = logDriver.Close(); err != nil {
logrus.Errorf("Error closing logger: %v", err)
}
}()
}
cLog, ok := logDriver.(logger.LogReader)
if !ok {
return logger.ErrReadLogsNotSupported
}
logs := cLog.ReadLogs(logger.ReadConfig{Tail: -1})
defer logs.Close()
LogLoop:
for {

View file

@ -45,10 +45,17 @@ func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, c
return nil, logger.ErrReadLogsNotSupported
}
cLog, err := daemon.getLogger(container)
cLog, cLogCreated, err := daemon.getLogger(container)
if err != nil {
return nil, err
}
if cLogCreated {
defer func() {
if err = cLog.Close(); err != nil {
logrus.Errorf("Error closing logger: %v", err)
}
}()
}
logReader, ok := cLog.(logger.LogReader)
if !ok {
@ -85,23 +92,8 @@ func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, c
messageChan := make(chan *backend.LogMessage, 1)
go func() {
// set up some defers
defer func() {
// ok so this function, originally, was placed right after that
// logger.ReadLogs call above. I THINK that means it sets off the
// chain of events that results in the logger needing to be closed.
// i do not know if an error in time parsing above causing an early
// return will result in leaking the logger. if that is the case,
// it would also have been a bug in the original code
logs.Close()
if cLog != container.LogDriver {
// Since the logger isn't cached in the container, which
// occurs if it is running, it must get explicitly closed
// here to avoid leaking it and any file handles it has.
if err := cLog.Close(); err != nil {
logrus.Errorf("Error closing logger: %v", err)
}
}
}()
defer logs.Close()
// close the messages channel. closing is the only way to signal above
// that we're doing with logs (other than context cancel i guess).
defer close(messageChan)
@ -148,11 +140,17 @@ func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, c
return messageChan, nil
}
func (daemon *Daemon) getLogger(container *container.Container) (logger.Logger, error) {
if container.LogDriver != nil && container.IsRunning() {
return container.LogDriver, nil
func (daemon *Daemon) getLogger(container *container.Container) (l logger.Logger, created bool, err error) {
container.Lock()
if container.State.Running {
l = container.LogDriver
}
return container.StartLogger()
container.Unlock()
if l == nil {
created = true
l, err = container.StartLogger()
}
return
}
// mergeLogConfig merges the daemon log config to the container's log config if the container's log driver is not specified.