fix logger channel blocking
This commit is contained in:
parent
4d77b7face
commit
5c03adbded
@ -39,9 +39,8 @@ func (msg *logMessage) send(logger LogSystem) {
|
|||||||
|
|
||||||
var logMessages chan (*logMessage)
|
var logMessages chan (*logMessage)
|
||||||
var logSystems []LogSystem
|
var logSystems []LogSystem
|
||||||
var quit chan bool
|
var quit chan chan error
|
||||||
var drained chan bool
|
var drained chan bool
|
||||||
var shutdown chan bool
|
|
||||||
var mutex = sync.Mutex{}
|
var mutex = sync.Mutex{}
|
||||||
|
|
||||||
type LogLevel uint8
|
type LogLevel uint8
|
||||||
@ -55,44 +54,54 @@ const (
|
|||||||
DebugDetailLevel
|
DebugDetailLevel
|
||||||
)
|
)
|
||||||
|
|
||||||
// log messages are dispatched to log writers
|
func dispatch(msg *logMessage) {
|
||||||
func start() {
|
for _, logSystem := range logSystems {
|
||||||
out:
|
if logSystem.GetLogLevel() >= msg.LogLevel {
|
||||||
for {
|
msg.send(logSystem)
|
||||||
select {
|
|
||||||
case <-quit:
|
|
||||||
break out
|
|
||||||
case msg := <-logMessages:
|
|
||||||
for _, logSystem := range logSystems {
|
|
||||||
if logSystem.GetLogLevel() >= msg.LogLevel {
|
|
||||||
msg.send(logSystem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case drained <- true:
|
|
||||||
default:
|
|
||||||
drained <- true // this blocks until a message is sent to the queu
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(shutdown)
|
}
|
||||||
|
|
||||||
|
// log messages are dispatched to log writers
|
||||||
|
func start() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case status := <-quit:
|
||||||
|
status <- nil
|
||||||
|
return
|
||||||
|
case msg := <-logMessages:
|
||||||
|
dispatch(msg)
|
||||||
|
default:
|
||||||
|
drained <- true // this blocks until a message is sent to the queue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func send(msg *logMessage) {
|
||||||
|
logMessages <- msg
|
||||||
|
select {
|
||||||
|
case <-drained:
|
||||||
|
default:
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Reset() {
|
func Reset() {
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
if logSystems != nil {
|
if logSystems != nil {
|
||||||
quit <- true
|
status := make(chan error)
|
||||||
|
quit <- status
|
||||||
select {
|
select {
|
||||||
case <-drained:
|
case <-drained:
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
<-shutdown
|
<-status
|
||||||
}
|
}
|
||||||
logSystems = nil
|
logSystems = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// waits until log messages are drained (dispatched to log writers)
|
// waits until log messages are drained (dispatched to log writers)
|
||||||
func Flush() {
|
func Flush() {
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
if logSystems != nil {
|
if logSystems != nil {
|
||||||
<-drained
|
<-drained
|
||||||
}
|
}
|
||||||
@ -110,22 +119,14 @@ func AddLogSystem(logSystem LogSystem) {
|
|||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
if logSystems == nil {
|
if logSystems == nil {
|
||||||
logMessages = make(chan *logMessage)
|
logMessages = make(chan *logMessage, 5)
|
||||||
quit = make(chan bool)
|
quit = make(chan chan error, 1)
|
||||||
drained = make(chan bool, 1)
|
drained = make(chan bool, 1)
|
||||||
shutdown = make(chan bool, 1)
|
|
||||||
go start()
|
go start()
|
||||||
}
|
}
|
||||||
logSystems = append(logSystems, logSystem)
|
logSystems = append(logSystems, logSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
func send(msg *logMessage) {
|
|
||||||
select {
|
|
||||||
case <-drained:
|
|
||||||
}
|
|
||||||
logMessages <- msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) sendln(level LogLevel, v ...interface{}) {
|
func (logger *Logger) sendln(level LogLevel, v ...interface{}) {
|
||||||
if logSystems != nil {
|
if logSystems != nil {
|
||||||
send(newPrintlnLogMessage(level, logger.tag, v...))
|
send(newPrintlnLogMessage(level, logger.tag, v...))
|
||||||
|
@ -28,6 +28,21 @@ func (t *TestLogSystem) GetLogLevel() LogLevel {
|
|||||||
return t.level
|
return t.level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoggerFlush(t *testing.T) {
|
||||||
|
logger := NewLogger("TEST")
|
||||||
|
testLogSystem := &TestLogSystem{level: WarnLevel}
|
||||||
|
AddLogSystem(testLogSystem)
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
logger.Errorf(".")
|
||||||
|
}
|
||||||
|
Flush()
|
||||||
|
Reset()
|
||||||
|
output := testLogSystem.Output
|
||||||
|
if output != "[TEST] .[TEST] .[TEST] .[TEST] .[TEST] ." {
|
||||||
|
t.Error("Expected complete logger output '[TEST] .[TEST] .[TEST] .[TEST] .[TEST] .', got ", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoggerPrintln(t *testing.T) {
|
func TestLoggerPrintln(t *testing.T) {
|
||||||
logger := NewLogger("TEST")
|
logger := NewLogger("TEST")
|
||||||
testLogSystem := &TestLogSystem{level: WarnLevel}
|
testLogSystem := &TestLogSystem{level: WarnLevel}
|
||||||
|
Loading…
Reference in New Issue
Block a user