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 }