github.com/keakon/golog@v0.0.0-20230330091222-cac71197c18d/handler.go (about)

     1  package golog
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  )
     7  
     8  // A Handler is a leveled log handler with a formatter and several writers.
     9  type Handler struct {
    10  	writers    []io.WriteCloser
    11  	formatter  *Formatter
    12  	level      Level
    13  	isInternal bool
    14  }
    15  
    16  // NewHandler creates a new Handler of the given level with the formatter.
    17  // Records with the lower level than the handler will be ignored.
    18  func NewHandler(level Level, formatter *Formatter) *Handler {
    19  	return &Handler{
    20  		level:     level,
    21  		formatter: formatter,
    22  	}
    23  }
    24  
    25  // AddWriter adds a writer to the Handler.
    26  // The Write() method of the writer should be thread-safe.
    27  func (h *Handler) AddWriter(w io.WriteCloser) {
    28  	h.writers = append(h.writers, w)
    29  }
    30  
    31  // Handle formats a record using its formatter, then writes the formatted result to all of its writers.
    32  // Returns true if it can handle the record.
    33  // The errors during writing will be logged by the internalLogger.
    34  // It's not thread-safe, concurrent record may be written in a random order through different writers.
    35  // But two records won't be mixed in a single line.
    36  func (h *Handler) Handle(r *Record) bool {
    37  	if r.level >= h.level {
    38  		buf := bufPool.Get().(*bytes.Buffer)
    39  		buf.Reset()
    40  		h.formatter.Format(r, buf)
    41  		content := buf.Bytes()
    42  		for _, w := range h.writers {
    43  			_, err := w.Write(content)
    44  			if err != nil && !h.isInternal {
    45  				logError(err)
    46  			}
    47  		}
    48  		bufPool.Put(buf)
    49  		return true
    50  	}
    51  	return false
    52  }
    53  
    54  // Close closes all its writers.
    55  // It's safe to call this method more than once,
    56  // but it's unsafe to call its writers' Close() more than once.
    57  func (h *Handler) Close() {
    58  	for _, w := range h.writers {
    59  		err := w.Close()
    60  		if err != nil {
    61  			logError(err)
    62  		}
    63  	}
    64  	h.writers = nil
    65  }