Skip to content

Commit

Permalink
Buffer 'docker stats' text to avoid terminal flickering
Browse files Browse the repository at this point in the history
This change reduces the flickering of the terminal when
running `docker stats` by buffering the formatted stats
text and printing it in one write.

Should also consume less CPU as we now only have to issue
a single syscall to write the stats text to the terminal.

Signed-off-by: Giedrius Jonikas <[email protected]>
  • Loading branch information
Giedriusj1 committed Oct 31, 2024
1 parent aa331e9 commit 0b16070
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions cli/command/container/stats.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package container

import (
"bytes"
"context"
"fmt"
"io"
Expand Down Expand Up @@ -264,31 +265,40 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
// so we unlikely hit this code in practice.
daemonOSType = dockerCLI.ServerInfo().OSType
}

// Buffer to store formatted stats text.
// Once formatted, it will be printed in one write to avoid screen flickering.
var statsTextBuffer bytes.Buffer

statsCtx := formatter.Context{
Output: dockerCLI.Out(),
Output: &statsTextBuffer,
Format: NewStatsFormat(format, daemonOSType),
}
cleanScreen := func() {
if !options.NoStream {
_, _ = fmt.Fprint(dockerCLI.Out(), "\033[2J")
_, _ = fmt.Fprint(dockerCLI.Out(), "\033[H")
}
}

var err error
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for range ticker.C {
cleanScreen()
var ccStats []StatsEntry
cStats.mu.RLock()
for _, c := range cStats.cs {
ccStats = append(ccStats, c.GetStatistics())
}
cStats.mu.RUnlock()

if !options.NoStream {
// Start by clearing the screen and moving the cursor to the top-left
_, _ = fmt.Fprint(&statsTextBuffer, "\033[2J\033[H")
}

if err = statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil {
break
}

_, _ = fmt.Fprint(dockerCLI.Out(), statsTextBuffer.String())

statsTextBuffer.Reset()

if len(cStats.cs) == 0 && !showAll {
break
}
Expand Down

0 comments on commit 0b16070

Please sign in to comment.