Add log line deduplication

This commit is contained in:
Daniel 2019-05-06 10:37:22 +02:00
parent 207844cb12
commit ab61b623f6
3 changed files with 66 additions and 10 deletions

View file

@ -27,7 +27,7 @@ func (s severity) String() string {
} }
} }
func formatLine(line *logLine, useColor bool) string { func formatLine(line *logLine, duplicates uint64, useColor bool) string {
colorStart := "" colorStart := ""
colorEnd := "" colorEnd := ""
@ -40,14 +40,14 @@ func formatLine(line *logLine, useColor bool) string {
var fLine string var fLine string
if line.line == 0 { if line.line == 0 {
fLine = fmt.Sprintf("%s%s ? %s %s %03d%s %s", colorStart, line.time.Format("060102 15:04:05.000"), rightArrow, line.level.String(), counter, colorEnd, line.msg) fLine = fmt.Sprintf("%s%s ? %s %s %03d%s%s %s", colorStart, line.time.Format("060102 15:04:05.000"), rightArrow, line.level.String(), counter, formatDuplicates(duplicates), colorEnd, line.msg)
} else { } else {
fLen := len(line.file) fLen := len(line.file)
fPartStart := fLen - 10 fPartStart := fLen - 10
if fPartStart < 0 { if fPartStart < 0 {
fPartStart = 0 fPartStart = 0
} }
fLine = fmt.Sprintf("%s%s %s:%03d %s %s %03d%s %s", colorStart, line.time.Format("060102 15:04:05.000"), line.file[fPartStart:], line.line, rightArrow, line.level.String(), counter, colorEnd, line.msg) fLine = fmt.Sprintf("%s%s %s:%03d %s %s %03d%s%s %s", colorStart, line.time.Format("060102 15:04:05.000"), line.file[fPartStart:], line.line, rightArrow, line.level.String(), counter, formatDuplicates(duplicates), colorEnd, line.msg)
} }
if counter >= maxCount { if counter >= maxCount {
@ -56,3 +56,10 @@ func formatLine(line *logLine, useColor bool) string {
return fLine return fLine
} }
func formatDuplicates(duplicates uint64) string {
if duplicates == 0 {
return ""
}
return fmt.Sprintf(" [%dx]", duplicates+1)
}

View file

@ -42,6 +42,20 @@ type logLine struct {
line int line int
} }
func (ll *logLine) Equal(ol *logLine) bool {
switch {
case ll.msg != ol.msg:
return false
case ll.file != ol.file:
return false
case ll.line != ol.line:
return false
case ll.level != ol.level:
return false
}
return true
}
const ( const (
TraceLevel severity = 1 TraceLevel severity = 1
DebugLevel severity = 2 DebugLevel severity = 2

View file

@ -9,13 +9,10 @@ import (
"github.com/Safing/portbase/taskmanager" "github.com/Safing/portbase/taskmanager"
) )
func writeLine(line *logLine) { func writeLine(line *logLine, duplicates uint64) {
fmt.Println(formatLine(line, duplicates, true))
fmt.Println(formatLine(line, true))
// TODO: implement file logging and setting console/file logging // TODO: implement file logging and setting console/file logging
// TODO: use https://github.com/natefinch/lumberjack // TODO: use https://github.com/natefinch/lumberjack
} }
func startWriter() { func startWriter() {
@ -26,10 +23,16 @@ func startWriter() {
func writer() { func writer() {
var line *logLine var line *logLine
var lastLine *logLine
var duplicates uint64
startedTask := false startedTask := false
defer shutdownWaitGroup.Done() defer shutdownWaitGroup.Done()
for { for {
// reset
line = nil
lastLine = nil
duplicates = 0
// wait until logs need to be processed // wait until logs need to be processed
select { select {
@ -47,7 +50,7 @@ func writer() {
for { for {
select { select {
case line = <-logBuffer: case line = <-logBuffer:
writeLine(line) writeLine(line, duplicates)
case <-time.After(10 * time.Millisecond): case <-time.After(10 * time.Millisecond):
fmt.Println(fmt.Sprintf("%s%s %s EOF%s", InfoLevel.color(), time.Now().Format("060102 15:04:05.000"), leftArrow, endColor())) fmt.Println(fmt.Sprintf("%s%s %s EOF%s", InfoLevel.color(), time.Now().Format("060102 15:04:05.000"), leftArrow, endColor()))
return return
@ -60,7 +63,33 @@ func writer() {
for { for {
select { select {
case line = <-logBuffer: case line = <-logBuffer:
writeLine(line)
// 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
writeLine(lastLine, duplicates)
duplicates = 0
} else {
// duplicate
duplicates++
}
}
// write actual line
writeLine(line, duplicates)
duplicates = 0
default: default:
if startedTask { if startedTask {
taskmanager.EndMicroTask() taskmanager.EndMicroTask()
@ -70,5 +99,11 @@ func writer() {
} }
} }
// back down a little
select {
case <-time.After(10 * time.Millisecond):
case <-shutdownSignal:
}
} }
} }