github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/daemon/logger/copier.go (about) 1 package logger 2 3 import ( 4 "bufio" 5 "bytes" 6 "io" 7 "sync" 8 "time" 9 10 "github.com/Sirupsen/logrus" 11 ) 12 13 // Copier can copy logs from specified sources to Logger and attach 14 // ContainerID and Timestamp. 15 // Writes are concurrent, so you need implement some sync in your logger 16 type Copier struct { 17 // cid is the container id for which we are copying logs 18 cid string 19 // srcs is map of name -> reader pairs, for example "stdout", "stderr" 20 srcs map[string]io.Reader 21 dst Logger 22 copyJobs sync.WaitGroup 23 closed chan struct{} 24 } 25 26 // NewCopier creates a new Copier 27 func NewCopier(cid string, srcs map[string]io.Reader, dst Logger) *Copier { 28 return &Copier{ 29 cid: cid, 30 srcs: srcs, 31 dst: dst, 32 closed: make(chan struct{}), 33 } 34 } 35 36 // Run starts logs copying 37 func (c *Copier) Run() { 38 for src, w := range c.srcs { 39 c.copyJobs.Add(1) 40 go c.copySrc(src, w) 41 } 42 } 43 44 func (c *Copier) copySrc(name string, src io.Reader) { 45 defer c.copyJobs.Done() 46 reader := bufio.NewReader(src) 47 48 for { 49 select { 50 case <-c.closed: 51 return 52 default: 53 line, err := reader.ReadBytes('\n') 54 line = bytes.TrimSuffix(line, []byte{'\n'}) 55 56 // ReadBytes can return full or partial output even when it failed. 57 // e.g. it can return a full entry and EOF. 58 if err == nil || len(line) > 0 { 59 if logErr := c.dst.Log(&Message{ContainerID: c.cid, Line: line, Source: name, Timestamp: time.Now().UTC()}); logErr != nil { 60 logrus.Errorf("Failed to log msg %q for logger %s: %s", line, c.dst.Name(), logErr) 61 } 62 } 63 64 if err != nil { 65 if err != io.EOF { 66 logrus.Errorf("Error scanning log stream: %s", err) 67 } 68 return 69 } 70 } 71 } 72 } 73 74 // Wait waits until all copying is done 75 func (c *Copier) Wait() { 76 c.copyJobs.Wait() 77 } 78 79 // Close closes the copier 80 func (c *Copier) Close() { 81 select { 82 case <-c.closed: 83 default: 84 close(c.closed) 85 } 86 }