qmp-testing-suite/golang-producer-consumer/vendor/gitlab-app.eng.qops.net/reporting-framework/ripsaw-logger-golang/logger-async.go

71 lines
1.2 KiB
Go
Executable File

package ripsawlogger
import (
"sync"
"time"
)
const (
bufferSize = 128
flushTimeoutMilliseconds = 2500
)
type asyncLogger struct {
channel chan LogEntry
logger Logger
m sync.Mutex
}
// Creates a logger that performs writes asynchronously and non-blocking-ly
func NewAsyncLogger(next Logger) Logger {
entries := make(chan LogEntry, bufferSize)
go func(logger Logger, entries chan LogEntry) {
for {
// wait for some data and forward it to the right place
logger.Log(<-entries)
}
}(next, entries)
return &asyncLogger{channel: entries, logger: next}
}
func (rl *asyncLogger) Flush() {
// prevent additional writes
rl.m.Lock()
defer rl.m.Unlock()
timeoutStart := time.Now()
// flush downstream logs when we finish
defer rl.logger.Flush()
// wait for the channel to clear out
for {
length := len(rl.channel)
// if the channel is empty, then we're done
if length == 0 {
return
}
// if we've exhausted our timeout, just finish
if time.Now().Sub(timeoutStart) >= flushTimeoutMilliseconds*time.Millisecond {
return
}
// wait a slight amount
time.Sleep(30 * time.Millisecond)
}
}
func (rl *asyncLogger) Log(data LogEntry) {
rl.m.Lock()
defer rl.m.Unlock()
rl.channel <- data
}