Merge pull request #31579 from ijc25/cpuacct
Correct CPU usage calculation in presence of offline CPUs and newer Linux
This commit is contained in:
commit
2c6a1e1878
7 changed files with 39 additions and 1 deletions
|
@ -3470,6 +3470,10 @@ paths:
|
|||
The `precpu_stats` is the CPU statistic of last read, which is used
|
||||
for calculating the CPU usage percentage. It is not the same as the
|
||||
`cpu_stats` field.
|
||||
|
||||
If either `precpu_stats.online_cpus` or `cpu_stats.online_cpus` is
|
||||
nil then for compatibility with older daemons the length of the
|
||||
corresponding `cpu_usage.percpu_usage` array should be used.
|
||||
operationId: "ContainerStats"
|
||||
produces: ["application/json"]
|
||||
responses:
|
||||
|
@ -3548,6 +3552,7 @@ paths:
|
|||
total_usage: 100215355
|
||||
usage_in_kernelmode: 30000000
|
||||
system_cpu_usage: 739306590000000
|
||||
online_cpus: 4
|
||||
throttling_data:
|
||||
periods: 0
|
||||
throttled_periods: 0
|
||||
|
@ -3563,6 +3568,7 @@ paths:
|
|||
total_usage: 100093996
|
||||
usage_in_kernelmode: 30000000
|
||||
system_cpu_usage: 9492140000000
|
||||
online_cpus: 4
|
||||
throttling_data:
|
||||
periods: 0
|
||||
throttled_periods: 0
|
||||
|
|
|
@ -47,6 +47,9 @@ type CPUStats struct {
|
|||
// System Usage. Linux only.
|
||||
SystemUsage uint64 `json:"system_cpu_usage,omitempty"`
|
||||
|
||||
// Online CPUs. Linux only.
|
||||
OnlineCPUs uint32 `json:"online_cpus,omitempty"`
|
||||
|
||||
// Throttling Data. Linux only.
|
||||
ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
|
||||
}
|
||||
|
|
|
@ -178,10 +178,14 @@ func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *types.StatsJ
|
|||
cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU)
|
||||
// calculate the change for the entire system between readings
|
||||
systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem)
|
||||
onlineCPUs = float64(v.CPUStats.OnlineCPUs)
|
||||
)
|
||||
|
||||
if onlineCPUs == 0.0 {
|
||||
onlineCPUs = float64(len(v.CPUStats.CPUUsage.PercpuUsage))
|
||||
}
|
||||
if systemDelta > 0.0 && cpuDelta > 0.0 {
|
||||
cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CPUStats.CPUUsage.PercpuUsage)) * 100.0
|
||||
cpuPercent = (cpuDelta / systemDelta) * onlineCPUs * 100.0
|
||||
}
|
||||
return cpuPercent
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@ func (s *Collector) Run() {
|
|||
continue
|
||||
}
|
||||
|
||||
onlineCPUs, err := s.getNumberOnlineCPUs()
|
||||
if err != nil {
|
||||
logrus.Errorf("collecting system online cpu count: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, pair := range pairs {
|
||||
stats, err := s.supervisor.GetContainerStats(pair.container)
|
||||
if err != nil {
|
||||
|
@ -97,6 +103,7 @@ func (s *Collector) Run() {
|
|||
}
|
||||
// FIXME: move to containerd on Linux (not Windows)
|
||||
stats.CPUStats.SystemUsage = systemUsage
|
||||
stats.CPUStats.OnlineCPUs = onlineCPUs
|
||||
|
||||
pair.publisher.Publish(*stats)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,11 @@ import (
|
|||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
)
|
||||
|
||||
/*
|
||||
#include <unistd.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// platformNewStatsCollector performs platform specific initialisation of the
|
||||
// Collector structure.
|
||||
func platformNewStatsCollector(s *Collector) {
|
||||
|
@ -64,3 +69,11 @@ func (s *Collector) getSystemCPUUsage() (uint64, error) {
|
|||
}
|
||||
return 0, fmt.Errorf("invalid stat format. Error trying to parse the '/proc/stat' file")
|
||||
}
|
||||
|
||||
func (s *Collector) getNumberOnlineCPUs() (uint32, error) {
|
||||
i, err := C.sysconf(C._SC_NPROCESSORS_ONLN)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(i), nil
|
||||
}
|
||||
|
|
|
@ -13,3 +13,7 @@ func platformNewStatsCollector(s *Collector) {
|
|||
func (s *Collector) getSystemCPUUsage() (uint64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (s *Collector) getNumberOnlineCPUs() (uint32, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
* `POST /build` now accepts `extrahosts` parameter to specify a host to ip mapping to use during the build.
|
||||
* `POST /services/create` and `POST /services/(id or name)/update` now accept a `rollback` value for `FailureAction`.
|
||||
* `POST /services/create` and `POST /services/(id or name)/update` now accept an optional `RollbackConfig` object which specifies rollback options.
|
||||
* `GET /containers/(id or name)/stats` now includes an `online_cpus` field in both `precpu_stats` and `cpu_stats`. If this field is `nil` then for compatibility with older daemons the length of the corresponding `cpu_usage.percpu_usage` array should be used.
|
||||
|
||||
## v1.26 API changes
|
||||
|
||||
|
|
Loading…
Reference in a new issue