1
0
mirror of https://github.com/docker/cli.git synced 2026-01-13 18:22:35 +03:00

Merge pull request #6583 from thaJeztah/stats_cleanups

cli/command/container: cleanup stats code
This commit is contained in:
Sebastiaan van Stijn
2025-10-28 15:17:20 +01:00
committed by GitHub

View File

@@ -50,15 +50,10 @@ func (s *stats) isKnownContainer(cid string) (int, bool) {
}
func collect(ctx context.Context, s *Stats, cli client.ContainerAPIClient, streamStats bool, waitFirst *sync.WaitGroup) { //nolint:gocyclo
var (
getFirst bool
previousCPU uint64
previousSystem uint64
u = make(chan error, 1)
)
var getFirst bool
defer func() {
// if error happens and we get nothing of stats, release wait group whatever
// if error happens, and we get nothing of stats, release wait group whatever
if !getFirst {
getFirst = true
waitFirst.Done()
@@ -71,6 +66,7 @@ func collect(ctx context.Context, s *Stats, cli client.ContainerAPIClient, strea
return
}
u := make(chan error, 1)
go func() {
defer response.Body.Close()
dec := json.NewDecoder(response.Body)
@@ -78,14 +74,7 @@ func collect(ctx context.Context, s *Stats, cli client.ContainerAPIClient, strea
if ctx.Err() != nil {
return
}
var (
v *container.StatsResponse
memPercent, cpuPercent float64
blkRead, blkWrite uint64 // Only used on Linux
mem, memLimit float64
pidsStatsCurrent uint64
)
var v container.StatsResponse
if err := dec.Decode(&v); err != nil {
dec = json.NewDecoder(io.MultiReader(dec.Buffered(), response.Body))
u <- err
@@ -96,35 +85,36 @@ func collect(ctx context.Context, s *Stats, cli client.ContainerAPIClient, strea
continue
}
if daemonOSType != "windows" {
previousCPU = v.PreCPUStats.CPUUsage.TotalUsage
previousSystem = v.PreCPUStats.SystemUsage
cpuPercent = calculateCPUPercentUnix(previousCPU, previousSystem, v)
blkRead, blkWrite = calculateBlockIO(v.BlkioStats)
mem = calculateMemUsageUnixNoCache(v.MemoryStats)
memLimit = float64(v.MemoryStats.Limit)
memPercent = calculateMemPercentUnixNoCache(memLimit, mem)
pidsStatsCurrent = v.PidsStats.Current
if daemonOSType == "windows" {
netRx, netTx := calculateNetwork(v.Networks)
s.SetStatistics(StatsEntry{
Name: v.Name,
ID: v.ID,
CPUPercentage: calculateCPUPercentWindows(&v),
Memory: float64(v.MemoryStats.PrivateWorkingSet),
NetworkRx: netRx,
NetworkTx: netTx,
BlockRead: float64(v.StorageStats.ReadSizeBytes),
BlockWrite: float64(v.StorageStats.WriteSizeBytes),
})
} else {
cpuPercent = calculateCPUPercentWindows(v)
blkRead = v.StorageStats.ReadSizeBytes
blkWrite = v.StorageStats.WriteSizeBytes
mem = float64(v.MemoryStats.PrivateWorkingSet)
memUsage := calculateMemUsageUnixNoCache(v.MemoryStats)
netRx, netTx := calculateNetwork(v.Networks)
blkRead, blkWrite := calculateBlockIO(v.BlkioStats)
s.SetStatistics(StatsEntry{
Name: v.Name,
ID: v.ID,
CPUPercentage: calculateCPUPercentUnix(v.PreCPUStats, v.CPUStats),
Memory: memUsage,
MemoryPercentage: calculateMemPercentUnixNoCache(float64(v.MemoryStats.Limit), memUsage),
MemoryLimit: float64(v.MemoryStats.Limit),
NetworkRx: netRx,
NetworkTx: netTx,
BlockRead: float64(blkRead),
BlockWrite: float64(blkWrite),
PidsCurrent: v.PidsStats.Current,
})
}
netRx, netTx := calculateNetwork(v.Networks)
s.SetStatistics(StatsEntry{
Name: v.Name,
ID: v.ID,
CPUPercentage: cpuPercent,
Memory: mem,
MemoryPercentage: memPercent,
MemoryLimit: memLimit,
NetworkRx: netRx,
NetworkTx: netTx,
BlockRead: float64(blkRead),
BlockWrite: float64(blkWrite),
PidsCurrent: pidsStatsCurrent,
})
u <- nil
if !streamStats {
return
@@ -165,18 +155,18 @@ func collect(ctx context.Context, s *Stats, cli client.ContainerAPIClient, strea
}
}
func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *container.StatsResponse) float64 {
func calculateCPUPercentUnix(previousCPU container.CPUStats, curCPUStats container.CPUStats) float64 {
var (
cpuPercent = 0.0
// calculate the change for the cpu usage of the container in between readings
cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU)
cpuDelta = float64(curCPUStats.CPUUsage.TotalUsage) - float64(previousCPU.CPUUsage.TotalUsage)
// calculate the change for the entire system between readings
systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem)
onlineCPUs = float64(v.CPUStats.OnlineCPUs)
systemDelta = float64(curCPUStats.SystemUsage) - float64(previousCPU.SystemUsage)
onlineCPUs = float64(curCPUStats.OnlineCPUs)
)
if onlineCPUs == 0.0 {
onlineCPUs = float64(len(v.CPUStats.CPUUsage.PercpuUsage))
onlineCPUs = float64(len(curCPUStats.CPUUsage.PercpuUsage))
}
if systemDelta > 0.0 && cpuDelta > 0.0 {
cpuPercent = (cpuDelta / systemDelta) * onlineCPUs * 100.0
@@ -188,13 +178,11 @@ func calculateCPUPercentWindows(v *container.StatsResponse) float64 {
// Max number of 100ns intervals between the previous time read and now
possIntervals := uint64(v.Read.Sub(v.PreRead).Nanoseconds()) // Start with number of ns intervals
possIntervals /= 100 // Convert to number of 100ns intervals
possIntervals *= uint64(v.NumProcs) // Multiple by the number of processors
// Intervals used
intervalsUsed := v.CPUStats.CPUUsage.TotalUsage - v.PreCPUStats.CPUUsage.TotalUsage
possIntervals *= uint64(v.NumProcs) // Multiply by the number of processors
// Percentage avoiding divide-by-zero
if possIntervals > 0 {
intervalsUsed := v.CPUStats.CPUUsage.TotalUsage - v.PreCPUStats.CPUUsage.TotalUsage
return float64(intervalsUsed) / float64(possIntervals) * 100.0
}
return 0.00