github.com/apex/up@v1.7.1/internal/logs/writer/writer.go (about) 1 // Package writer provides an io.Writer for capturing 2 // process output as logs, so that stdout may become 3 // INFO, and stderr ERROR. 4 package writer 5 6 import ( 7 "bufio" 8 "bytes" 9 "encoding/json" 10 11 "github.com/apex/log" 12 "github.com/apex/up/internal/util" 13 ) 14 15 // Writer struct. 16 type Writer struct { 17 log log.Interface 18 level log.Level 19 } 20 21 // New writer with the given log level. 22 func New(l log.Level, ctx log.Interface) *Writer { 23 return &Writer{ 24 log: ctx, 25 level: l, 26 } 27 } 28 29 // Write implementation. 30 func (w *Writer) Write(b []byte) (int, error) { 31 s := bufio.NewScanner(bytes.NewReader(b)) 32 33 for s.Scan() { 34 if err := w.write(s.Text()); err != nil { 35 return 0, err 36 } 37 } 38 39 if err := s.Err(); err != nil { 40 return 0, err 41 } 42 43 return len(b), nil 44 } 45 46 // write the line. 47 func (w *Writer) write(s string) error { 48 if util.IsJSONLog(s) { 49 return w.writeJSON(s) 50 } 51 52 return w.writeText(s) 53 } 54 55 // writeJSON writes a json log, interpreting it as a log.Entry. 56 func (w *Writer) writeJSON(s string) error { 57 // TODO: make this less ugly in apex/log, 58 // you should be able to write an arbitrary Entry. 59 var e log.Entry 60 61 if err := json.Unmarshal([]byte(s), &e); err != nil { 62 return w.writeText(s) 63 } 64 65 switch e.Level { 66 case log.DebugLevel: 67 w.log.WithFields(e.Fields).Debug(e.Message) 68 case log.InfoLevel: 69 w.log.WithFields(e.Fields).Info(e.Message) 70 case log.WarnLevel: 71 w.log.WithFields(e.Fields).Warn(e.Message) 72 case log.ErrorLevel: 73 w.log.WithFields(e.Fields).Error(e.Message) 74 case log.FatalLevel: 75 // TODO: FATAL without exit... 76 w.log.WithFields(e.Fields).Error(e.Message) 77 } 78 79 return nil 80 } 81 82 // writeText writes plain text. 83 func (w *Writer) writeText(s string) error { 84 switch w.level { 85 case log.InfoLevel: 86 w.log.Info(s) 87 case log.ErrorLevel: 88 w.log.Error(s) 89 } 90 return nil 91 }