github.com/csfrancis/docker@v1.8.0-rc2/daemon/logs.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"strconv"
     7  	"time"
     8  
     9  	"github.com/Sirupsen/logrus"
    10  	"github.com/docker/docker/daemon/logger"
    11  	"github.com/docker/docker/pkg/stdcopy"
    12  )
    13  
    14  type ContainerLogsConfig struct {
    15  	Follow, Timestamps   bool
    16  	Tail                 string
    17  	Since                time.Time
    18  	UseStdout, UseStderr bool
    19  	OutStream            io.Writer
    20  	Stop                 <-chan bool
    21  }
    22  
    23  func (daemon *Daemon) ContainerLogs(container *Container, config *ContainerLogsConfig) error {
    24  	if !(config.UseStdout || config.UseStderr) {
    25  		return fmt.Errorf("You must choose at least one stream")
    26  	}
    27  
    28  	outStream := config.OutStream
    29  	errStream := outStream
    30  	if !container.Config.Tty {
    31  		errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
    32  		outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
    33  	}
    34  
    35  	cLog, err := container.getLogger()
    36  	if err != nil {
    37  		return err
    38  	}
    39  	logReader, ok := cLog.(logger.LogReader)
    40  	if !ok {
    41  		return logger.ErrReadLogsNotSupported
    42  	}
    43  
    44  	follow := config.Follow && container.IsRunning()
    45  	tailLines, err := strconv.Atoi(config.Tail)
    46  	if err != nil {
    47  		tailLines = -1
    48  	}
    49  
    50  	logrus.Debug("logs: begin stream")
    51  	readConfig := logger.ReadConfig{
    52  		Since:  config.Since,
    53  		Tail:   tailLines,
    54  		Follow: follow,
    55  	}
    56  	logs := logReader.ReadLogs(readConfig)
    57  
    58  	for {
    59  		select {
    60  		case err := <-logs.Err:
    61  			logrus.Errorf("Error streaming logs: %v", err)
    62  			return nil
    63  		case <-config.Stop:
    64  			logs.Close()
    65  			return nil
    66  		case msg, ok := <-logs.Msg:
    67  			if !ok {
    68  				logrus.Debugf("logs: end stream")
    69  				return nil
    70  			}
    71  			logLine := msg.Line
    72  			if config.Timestamps {
    73  				logLine = append([]byte(msg.Timestamp.Format(logger.TimeFormat)+" "), logLine...)
    74  			}
    75  			if msg.Source == "stdout" && config.UseStdout {
    76  				outStream.Write(logLine)
    77  			}
    78  			if msg.Source == "stderr" && config.UseStderr {
    79  				errStream.Write(logLine)
    80  			}
    81  		}
    82  	}
    83  }