github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/pkg/logger/deferred.go (about) 1 package logger 2 3 import ( 4 "bytes" 5 "context" 6 "sync" 7 ) 8 9 // A logger that buffers its log lines until we have an output logger. 10 type DeferredLogger struct { 11 Logger 12 entries []logEntry 13 mu sync.Mutex 14 original Logger 15 output Logger 16 } 17 18 func NewDeferredLogger(ctx context.Context) *DeferredLogger { 19 original := Get(ctx) 20 dLogger := &DeferredLogger{original: original} 21 fLogger := NewFuncLogger(original.SupportsColor(), original.Level(), func(level Level, fields Fields, b []byte) error { 22 dLogger.mu.Lock() 23 defer dLogger.mu.Unlock() 24 if dLogger.output != nil { 25 dLogger.output.Write(level, b) 26 return nil 27 } 28 dLogger.entries = append(dLogger.entries, logEntry{level: level, b: append([]byte{}, b...)}) 29 return nil 30 }) 31 dLogger.Logger = fLogger 32 return dLogger 33 } 34 35 func (dl *DeferredLogger) CopyBuffered(lvl Level) *bytes.Buffer { 36 dl.mu.Lock() 37 defer dl.mu.Unlock() 38 39 buf := bytes.NewBuffer(nil) 40 logger := NewLogger(lvl, buf) 41 for _, entry := range dl.entries { 42 logger.Write(entry.level, entry.b) 43 } 44 return buf 45 } 46 47 // Set the output logger, and send all the buffered output to the new logger. 48 func (dl *DeferredLogger) SetOutput(l Logger) { 49 dl.mu.Lock() 50 defer dl.mu.Unlock() 51 dl.output = l 52 for _, entry := range dl.entries { 53 dl.output.Write(entry.level, entry.b) 54 } 55 dl.entries = nil 56 } 57 58 // The original logger that we're deferring output away from. 59 func (dl *DeferredLogger) Original() Logger { 60 return dl.original 61 } 62 63 type logEntry struct { 64 level Level 65 b []byte 66 }