Render the live status to the framebuffer in Atkinson Hyperlegible Mono
This commit is contained in:
@@ -156,38 +156,60 @@ var intervalCols = []colSpec{
|
||||
{title: "ERRORS", width: 11, right: true},
|
||||
}
|
||||
|
||||
func (d *direction) intervalRow(elapsed time.Duration, secs, target float64) []string {
|
||||
// One interval's numbers, shared by the console table and the framebuffer so
|
||||
// both always show the same figures.
|
||||
type view struct {
|
||||
txPPS, rxPPS float64
|
||||
txGbps, rxGbps float64
|
||||
txFrames, txSent uint64
|
||||
rxFrames, rxGot uint64
|
||||
lost, late uint64
|
||||
crc, badMagic uint64
|
||||
kdrop, errors uint64
|
||||
}
|
||||
|
||||
func (d *direction) view(secs float64) view {
|
||||
now := d.snapshot()
|
||||
p := d.prev
|
||||
d.prev = now
|
||||
d.sampleDrops()
|
||||
|
||||
txF := now.txFrames - p.txFrames
|
||||
txB := now.txBytes - p.txBytes
|
||||
rxF := now.rxFrames - p.rxFrames
|
||||
rxB := now.rxBytes - p.rxBytes
|
||||
|
||||
d.sampleDrops()
|
||||
b := d.errBase
|
||||
lost := now.lost - b.lost
|
||||
late := now.late - b.late
|
||||
crc := now.crcErr - b.crcErr
|
||||
badMagic := now.badMagic - b.badMagic
|
||||
badLen := now.badLen - b.badLen
|
||||
drops := d.drops - d.dropBase
|
||||
v := view{
|
||||
txPPS: float64(txF) / secs,
|
||||
rxPPS: float64(rxF) / secs,
|
||||
txGbps: gbps(now.txBytes-p.txBytes, txF, secs),
|
||||
rxGbps: gbps(now.rxBytes-p.rxBytes, rxF, secs),
|
||||
txFrames: now.txFrames,
|
||||
txSent: now.txBytes,
|
||||
rxFrames: now.rxFrames,
|
||||
rxGot: now.rxBytes,
|
||||
lost: now.lost - b.lost,
|
||||
late: now.late - b.late,
|
||||
crc: now.crcErr - b.crcErr,
|
||||
badMagic: now.badMagic - b.badMagic,
|
||||
kdrop: d.drops - d.dropBase,
|
||||
}
|
||||
v.errors = v.lost + v.crc + v.badMagic + (now.badLen - b.badLen) + v.kdrop
|
||||
return v
|
||||
}
|
||||
|
||||
func (d *direction) row(elapsed time.Duration, v view, target float64) []string {
|
||||
return []string{
|
||||
uptime(elapsed),
|
||||
paint(d.short, cCyan),
|
||||
commas(uint64(float64(txF) / secs)),
|
||||
rateCell(gbps(txB, txF, secs), target),
|
||||
commas(uint64(float64(rxF) / secs)),
|
||||
rateCell(gbps(rxB, rxF, secs), target),
|
||||
statusCell(lost),
|
||||
statusCell(late),
|
||||
statusCell(crc),
|
||||
statusCell(badMagic),
|
||||
statusCell(drops),
|
||||
statusCell(lost + crc + badMagic + badLen + drops),
|
||||
commas(uint64(v.txPPS)),
|
||||
rateCell(v.txGbps, target),
|
||||
commas(uint64(v.rxPPS)),
|
||||
rateCell(v.rxGbps, target),
|
||||
statusCell(v.lost),
|
||||
statusCell(v.late),
|
||||
statusCell(v.crc),
|
||||
statusCell(v.badMagic),
|
||||
statusCell(v.kdrop),
|
||||
statusCell(v.errors),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,6 +464,14 @@ func run(aName, bName, sizesArg, patArg string,
|
||||
space, restoreTerm := watchSpace()
|
||||
defer restoreTerm()
|
||||
|
||||
disp, err := newDisplay()
|
||||
if err != nil {
|
||||
return fmt.Errorf("display: %w", err)
|
||||
}
|
||||
defer disp.close()
|
||||
disp.config = fmt.Sprintf("%s sizes %s %d streams batch %d crc32c verify",
|
||||
patterns[patIdx].name, strings.Join(sizeStrs, ","), nStreams, batch)
|
||||
|
||||
start := time.Now()
|
||||
close(startTx)
|
||||
tick := time.NewTicker(reportInterval)
|
||||
@@ -466,8 +496,10 @@ func run(aName, bName, sizesArg, patArg string,
|
||||
secs := now.Sub(last).Seconds()
|
||||
last = now
|
||||
elapsed := now.Sub(start)
|
||||
for _, d := range dirs {
|
||||
for _, line := range stats.emit(d.intervalRow(elapsed, secs, target)) {
|
||||
views := make([]view, len(dirs))
|
||||
for i, d := range dirs {
|
||||
views[i] = d.view(secs)
|
||||
for _, line := range stats.emit(d.row(elapsed, views[i], target)) {
|
||||
fmt.Println(line)
|
||||
}
|
||||
for _, line := range d.reportNIC() {
|
||||
@@ -483,6 +515,7 @@ func run(aName, bName, sizesArg, patArg string,
|
||||
break
|
||||
}
|
||||
}
|
||||
disp.render(dirs, views, elapsed, target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user