-
Notifications
You must be signed in to change notification settings - Fork 300
/
printer.go
74 lines (63 loc) · 1.71 KB
/
printer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package hud
import (
"io"
"time"
"github.com/tilt-dev/tilt/pkg/model/logstore"
)
var backoffInit = 5 * time.Second
var backoffMultiplier = time.Duration(2)
type Stdout io.Writer
type IncrementalPrinter struct {
progress map[progressKey]progressStatus
stdout Stdout
}
func NewIncrementalPrinter(stdout Stdout) *IncrementalPrinter {
return &IncrementalPrinter{
progress: make(map[progressKey]progressStatus),
stdout: stdout,
}
}
func (p *IncrementalPrinter) PrintNewline() {
_, _ = io.WriteString(p.stdout, "\n")
}
func (p *IncrementalPrinter) Print(lines []logstore.LogLine) {
for _, line := range lines {
// Naive progress implementation: skip lines that have already been printed
// recently. This works with any output stream.
//
// TODO(nick): Use ANSI codes to overwrite previous lines. It requires
// a little extra bookkeeping about where to find the progress line,
// and only works on terminals.
progressID := line.ProgressID
key := progressKey{spanID: line.SpanID, progressID: progressID}
if progressID != "" {
status, hasBeenPrinted := p.progress[key]
shouldPrint := line.ProgressMustPrint ||
!hasBeenPrinted ||
line.Time.Sub(status.lastPrinted) > status.printWait
if !shouldPrint {
continue
}
}
_, _ = io.WriteString(p.stdout, line.Text)
if progressID != "" {
status := p.progress[key]
newWait := backoffInit
if status.printWait > 0 {
newWait = backoffMultiplier * status.printWait
}
p.progress[key] = progressStatus{
lastPrinted: line.Time,
printWait: newWait,
}
}
}
}
type progressKey struct {
spanID logstore.SpanID
progressID string
}
type progressStatus struct {
lastPrinted time.Time
printWait time.Duration
}