1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #31579 from ijc25/cpuacct

Correct CPU usage calculation in presence of offline CPUs and newer Linux
This commit is contained in:
Justin Cormack 2017-03-13 16:32:18 +00:00 committed by GitHub
commit 2c6a1e1878
7 changed files with 39 additions and 1 deletions

View file

@ -3470,6 +3470,10 @@ paths:
The `precpu_stats` is the CPU statistic of last read, which is used 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 for calculating the CPU usage percentage. It is not the same as the
`cpu_stats` field. `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" operationId: "ContainerStats"
produces: ["application/json"] produces: ["application/json"]
responses: responses:
@ -3548,6 +3552,7 @@ paths:
total_usage: 100215355 total_usage: 100215355
usage_in_kernelmode: 30000000 usage_in_kernelmode: 30000000
system_cpu_usage: 739306590000000 system_cpu_usage: 739306590000000
online_cpus: 4
throttling_data: throttling_data:
periods: 0 periods: 0
throttled_periods: 0 throttled_periods: 0
@ -3563,6 +3568,7 @@ paths:
total_usage: 100093996 total_usage: 100093996
usage_in_kernelmode: 30000000 usage_in_kernelmode: 30000000
system_cpu_usage: 9492140000000 system_cpu_usage: 9492140000000
online_cpus: 4
throttling_data: throttling_data:
periods: 0 periods: 0
throttled_periods: 0 throttled_periods: 0

View file

@ -47,6 +47,9 @@ type CPUStats struct {
// System Usage. Linux only. // System Usage. Linux only.
SystemUsage uint64 `json:"system_cpu_usage,omitempty"` SystemUsage uint64 `json:"system_cpu_usage,omitempty"`
// Online CPUs. Linux only.
OnlineCPUs uint32 `json:"online_cpus,omitempty"`
// Throttling Data. Linux only. // Throttling Data. Linux only.
ThrottlingData ThrottlingData `json:"throttling_data,omitempty"` ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
} }

View file

@ -178,10 +178,14 @@ func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *types.StatsJ
cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU) cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU)
// calculate the change for the entire system between readings // calculate the change for the entire system between readings
systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem) 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 { 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 return cpuPercent
} }

View file

@ -80,6 +80,12 @@ func (s *Collector) Run() {
continue continue
} }
onlineCPUs, err := s.getNumberOnlineCPUs()
if err != nil {
logrus.Errorf("collecting system online cpu count: %v", err)
continue
}
for _, pair := range pairs { for _, pair := range pairs {
stats, err := s.supervisor.GetContainerStats(pair.container) stats, err := s.supervisor.GetContainerStats(pair.container)
if err != nil { if err != nil {
@ -97,6 +103,7 @@ func (s *Collector) Run() {
} }
// FIXME: move to containerd on Linux (not Windows) // FIXME: move to containerd on Linux (not Windows)
stats.CPUStats.SystemUsage = systemUsage stats.CPUStats.SystemUsage = systemUsage
stats.CPUStats.OnlineCPUs = onlineCPUs
pair.publisher.Publish(*stats) pair.publisher.Publish(*stats)
} }

View file

@ -11,6 +11,11 @@ import (
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
) )
/*
#include <unistd.h>
*/
import "C"
// platformNewStatsCollector performs platform specific initialisation of the // platformNewStatsCollector performs platform specific initialisation of the
// Collector structure. // Collector structure.
func platformNewStatsCollector(s *Collector) { 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") 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
}

View file

@ -13,3 +13,7 @@ func platformNewStatsCollector(s *Collector) {
func (s *Collector) getSystemCPUUsage() (uint64, error) { func (s *Collector) getSystemCPUUsage() (uint64, error) {
return 0, nil return 0, nil
} }
func (s *Collector) getNumberOnlineCPUs() (uint32, error) {
return 0, nil
}

View file

@ -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 /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 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. * `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 ## v1.26 API changes