route/vendor/github.com/koding/logging/sink.go

82 lines
1.8 KiB
Go

package logging
import (
"fmt"
"os"
"sync"
)
/////////////////
// //
// SinkHandler //
// //
/////////////////
// SinkHandler sends log records to buffered channel, the logs are written in a dedicated routine consuming the channel.
type SinkHandler struct {
inner Handler
sinkCh chan *Record
bufSize int
wg sync.WaitGroup
}
// NewSinkHandler creates SinkHandler with sink channel buffer size bufSize that wraps inner handler for writing logs.
// When SinkHandler is created a go routine is started. When not used always call Close to terminate go routine.
func NewSinkHandler(inner Handler, bufSize int) *SinkHandler {
b := &SinkHandler{
inner: inner,
sinkCh: make(chan *Record, bufSize),
bufSize: bufSize,
}
b.wg.Add(1)
go b.process()
return b
}
// process reads log records from sinkCh and calls inner log handler to write it.
func (b *SinkHandler) process() {
for {
rec, ok := <-b.sinkCh
if !ok {
b.inner.Close()
break
}
b.inner.Handle(rec)
}
b.wg.Done()
}
// Status reports sink capacity and length.
func (b *SinkHandler) Status() (int, int) {
return b.bufSize, len(b.sinkCh)
}
// SetLevel sets logging level for handler
func (b *SinkHandler) SetLevel(l Level) {
b.inner.SetLevel(l)
}
// SetFormatter sets logging formatter for handler
func (b *SinkHandler) SetFormatter(f Formatter) {
b.inner.SetFormatter(f)
}
// Handle puts rec to the sink.
func (b *SinkHandler) Handle(rec *Record) {
select {
case b.sinkCh <- rec:
default:
fmt.Fprintf(os.Stderr, "SinkHandler buffer too small dropping record\n")
}
}
// Close closes the sink channel, inner handler will be closed when all pending logs are processed.
// Close blocks until all the logs are processed.
func (b *SinkHandler) Close() {
close(b.sinkCh)
b.wg.Wait()
}