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  }