Improve and fix logging

This commit is contained in:
Daniel 2019-10-09 16:22:51 +02:00
parent 09616a0c25
commit b0204f95ff
4 changed files with 57 additions and 44 deletions

View file

@ -75,15 +75,21 @@ func log(level Severity, msg string, tracer *ContextTracer) {
select {
case logBuffer <- log:
default:
forceEmptyingOfBuffer <- struct{}{}
logBuffer <- log
forceEmptyingLoop:
// force empty buffer until we can send to it
for {
select {
case forceEmptyingOfBuffer <- struct{}{}:
case logBuffer <- log:
break forceEmptyingLoop
}
}
}
// wake up writer if necessary
if logsWaitingFlag.SetToIf(false, true) {
logsWaiting <- struct{}{}
}
}
func fastcheck(level Severity) bool {

View file

@ -70,7 +70,7 @@ const (
var (
logBuffer chan *logLine
forceEmptyingOfBuffer chan struct{}
forceEmptyingOfBuffer = make(chan struct{})
logLevelInt = uint32(3)
logLevel = &logLevelInt
@ -79,7 +79,7 @@ var (
pkgLevels = make(map[string]Severity)
pkgLevelsLock sync.Mutex
logsWaiting = make(chan struct{}, 1)
logsWaiting = make(chan struct{}, 4)
logsWaitingFlag = abool.NewBool(false)
shutdownSignal = make(chan struct{})
@ -135,7 +135,6 @@ func Start() (err error) {
}
logBuffer = make(chan *logLine, 1024)
forceEmptyingOfBuffer = make(chan struct{}, 16)
initialLogLevel := ParseLevel(logLevelFlag)
if initialLogLevel > 0 {

View file

@ -45,31 +45,32 @@ func startWriter() {
}
func writer() {
var line *logLine
var lastLine *logLine
var currentLine *logLine
var nextLine *logLine
var duplicates uint64
defer shutdownWaitGroup.Done()
for {
// reset
line = nil
lastLine = nil //nolint:ineffassign // only ineffectual in first loop
currentLine = nil
nextLine = nil
duplicates = 0
// wait until logs need to be processed
select {
case <-logsWaiting:
case <-logsWaiting: // normal process
logsWaitingFlag.UnSet()
case <-shutdownSignal:
case <-forceEmptyingOfBuffer: // log buffer is full!
case <-shutdownSignal: // shutting down
finalizeWriting()
return
}
// wait for timeslot to log, or when buffer is full
// wait for timeslot to log
select {
case <-writeTrigger:
case <-forceEmptyingOfBuffer:
case <-shutdownSignal:
case <-writeTrigger: // normal process
case <-forceEmptyingOfBuffer: // log buffer is full!
case <-shutdownSignal: // shutting down
finalizeWriting()
return
}
@ -78,38 +79,39 @@ func writer() {
writeLoop:
for {
select {
case line = <-logBuffer:
// look-ahead for deduplication (best effort)
dedupLoop:
for {
// check if there is another line waiting
select {
case nextLine := <-logBuffer:
lastLine = line
line = nextLine
default:
break dedupLoop
}
// deduplication
if !line.Equal(lastLine) {
// no duplicate
break dedupLoop
}
// duplicate
duplicates++
case nextLine = <-logBuffer:
// first line we process, just assign to currentLine
if currentLine == nil {
currentLine = nextLine
continue writeLoop
}
// write actual line
writeLine(line, duplicates)
// we now have currentLine and nextLine
// if currentLine and nextLine are equal, do not print, just increase counter and continue
if nextLine.Equal(currentLine) {
duplicates++
continue writeLoop
}
// if currentLine and line are _not_ equal, output currentLine
writeLine(currentLine, duplicates)
// reset duplicate counter
duplicates = 0
// set new currentLine
currentLine = nextLine
default:
break writeLoop
}
}
// write final line
writeLine(currentLine, duplicates)
// reset state
currentLine = nil //nolint:ineffassign
nextLine = nil
duplicates = 0 //nolint:ineffassign
// back down a little
select {
case <-time.After(10 * time.Millisecond):

View file

@ -83,7 +83,7 @@ func Tracer(ctx context.Context) *ContextTracer {
// Submit collected logs on the context for further processing/outputting. Does nothing if called on a nil ContextTracer.
func (tracer *ContextTracer) Submit() {
if tracer != nil {
if tracer == nil {
return
}
@ -119,15 +119,21 @@ func (tracer *ContextTracer) Submit() {
select {
case logBuffer <- log:
default:
forceEmptyingOfBuffer <- struct{}{}
logBuffer <- log
forceEmptyingLoop:
// force empty buffer until we can send to it
for {
select {
case forceEmptyingOfBuffer <- struct{}{}:
case logBuffer <- log:
break forceEmptyingLoop
}
}
}
// wake up writer if necessary
if logsWaitingFlag.SetToIf(false, true) {
logsWaiting <- struct{}{}
}
}
func (tracer *ContextTracer) log(level Severity, msg string) {