github.com/lmars/docker@v1.6.0-rc2/daemon/logger/copier.go (about)

     1  package logger
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/Sirupsen/logrus"
    10  )
    11  
    12  // Copier can copy logs from specified sources to Logger and attach
    13  // ContainerID and Timestamp.
    14  // Writes are concurrent, so you need implement some sync in your logger
    15  type Copier struct {
    16  	// cid is container id for which we copying logs
    17  	cid string
    18  	// srcs is map of name -> reader pairs, for example "stdout", "stderr"
    19  	srcs     map[string]io.Reader
    20  	dst      Logger
    21  	copyJobs sync.WaitGroup
    22  }
    23  
    24  // NewCopier creates new Copier
    25  func NewCopier(cid string, srcs map[string]io.Reader, dst Logger) (*Copier, error) {
    26  	return &Copier{
    27  		cid:  cid,
    28  		srcs: srcs,
    29  		dst:  dst,
    30  	}, nil
    31  }
    32  
    33  // Run starts logs copying
    34  func (c *Copier) Run() {
    35  	for src, w := range c.srcs {
    36  		c.copyJobs.Add(1)
    37  		go c.copySrc(src, w)
    38  	}
    39  }
    40  
    41  func (c *Copier) copySrc(name string, src io.Reader) {
    42  	defer c.copyJobs.Done()
    43  	scanner := bufio.NewScanner(src)
    44  	for scanner.Scan() {
    45  		if err := c.dst.Log(&Message{ContainerID: c.cid, Line: scanner.Bytes(), Source: name, Timestamp: time.Now().UTC()}); err != nil {
    46  			logrus.Errorf("Failed to log msg %q for logger %s: %s", scanner.Bytes(), c.dst.Name(), err)
    47  		}
    48  	}
    49  	if err := scanner.Err(); err != nil {
    50  		logrus.Errorf("Error scanning log stream: %s", err)
    51  	}
    52  }
    53  
    54  // Wait waits until all copying is done
    55  func (c *Copier) Wait() {
    56  	c.copyJobs.Wait()
    57  }