Add SyncWriter utility type for non-thread-safe writers
This commit is contained in:
parent
5ebf00efab
commit
af9dd4ec23
8
log.go
8
log.go
|
@ -139,7 +139,13 @@ type Logger struct {
|
|||
counter *uint32
|
||||
}
|
||||
|
||||
// New creates a root logger with given output writer.
|
||||
// New creates a root logger with given output writer. If the output writer implements
|
||||
// the LevelWriter interface, the WriteLevel method will be called instead of the Write
|
||||
// one.
|
||||
//
|
||||
// Each logging operation makes a single call to the Writer's Write method. There is no
|
||||
// guaranty on access serialization to the Writer. If your Writer is not thread safe,
|
||||
// you may consider using sync wrapper.
|
||||
func New(w io.Writer) Logger {
|
||||
if w == nil {
|
||||
panic("w is nil")
|
||||
|
|
41
writer.go
41
writer.go
|
@ -1,6 +1,9 @@
|
|||
package zerolog
|
||||
|
||||
import "io"
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// LevelWriter defines as interface a writer may implement in order
|
||||
// to receive level information with payload.
|
||||
|
@ -13,10 +16,44 @@ type levelWriterAdapter struct {
|
|||
io.Writer
|
||||
}
|
||||
|
||||
func (lw levelWriterAdapter) WriteLevel(level Level, p []byte) (n int, err error) {
|
||||
func (lw levelWriterAdapter) WriteLevel(l Level, p []byte) (n int, err error) {
|
||||
return lw.Write(p)
|
||||
}
|
||||
|
||||
type syncWriter struct {
|
||||
mu sync.Mutex
|
||||
lw LevelWriter
|
||||
}
|
||||
|
||||
// SyncWriter wraps w so that each call to Write is synchronized with a mutex.
|
||||
// This syncer can be the call to writer's Write method is not thread safe.
|
||||
// Note that os.File Write operation is using write() syscall which is supposed
|
||||
// to be thread-safe on POSIX systems. So there is no need to use this with
|
||||
// os.File on such systems as zerolog guaranties to issue a single Write call
|
||||
// per log event.
|
||||
func SyncWriter(w io.Writer) io.Writer {
|
||||
if lw, ok := w.(LevelWriter); ok {
|
||||
return &syncWriter{lw: lw}
|
||||
}
|
||||
return &syncWriter{lw: levelWriterAdapter{w}}
|
||||
}
|
||||
|
||||
// Write implements the io.Writer interface.
|
||||
func (s *syncWriter) Write(p []byte) (n int, err error) {
|
||||
s.mu.Lock()
|
||||
n, err = s.lw.Write(p)
|
||||
s.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// WriteLevel implements the LevelWriter interface.
|
||||
func (s *syncWriter) WriteLevel(l Level, p []byte) (n int, err error) {
|
||||
s.mu.Lock()
|
||||
n, err = s.lw.WriteLevel(l, p)
|
||||
s.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
type multiLevelWriter struct {
|
||||
writers []LevelWriter
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue