来自码头统计vs cgroup的cpuPercent度量
问题描述:
我是cgroups的新手,并试图使用cgroup获取容器统计信息。以前我使用的是docker stats
,但是也试图收集类似的指标,cgroups
也是如此。来自码头统计vs cgroup的cpuPercent度量
在泊坞窗统计,CPU统计部分是象下面这样:
"cpu_usage": {
"total_usage": 27120642519,
"percpu_usage": [27120642519],
"usage_in_kernelmode": 4550000000,
"usage_in_usermode": 19140000000
},
"system_cpu_usage": 42803030000000,
而且,CPU%度量使用下面的公式计算:
cpuDelta = float64(v.CpuStats.CpuUsage.TotalUsage - previousCPU)
systemDelta = float64(v.CpuStats.SystemUsage - previousSystem)
cpuPct = cpuDelta/systemDelta
我在看的cgroup收集systemUsage
和totalUsage
,但它似乎没有类似的指标:
cgroups有一个伪文件cpuacct.stats其中有user
和system
刻度,但这些仅与来自docker stats
输出的usage_in_user_mode
和usage_in_kernel_mode
相匹配。
和cpuacct.usage_per_cpu伪文件每个cpu有一个用法,它与上面docker stats输出中的total_usage
匹配。
$cat cpuacct.stat
user 1914
system 455
$cat cpuacct.usage_percpu
27120642519
但是,我找不到任何方法来弄清楚如何从cgroups收集“systemUsage”。
任何线索都会有很大的帮助!
谢谢!
答
您的问题的答案不在于cgroups。请参考下文提到的一点:
func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *types.StatsJSON) 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)
// calculate the change for the entire system between readings
systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem)
)
if systemDelta > 0.0 && cpuDelta > 0.0 {
cpuPercent = (cpuDelta/systemDelta) * float64(len(v.CPUStats.CPUUsage.PercpuUsage)) * 100.0
}
return cpuPercent
}
- 的“system_cpu_usage”的泊坞窗统计API指的是主机的CPU使用情况。
- Docker统计信息API的“cpu_usage”>“total_usage”指的是容器的每CPU使用情况。
- 因此,在计算(cpuDelta/systemDelta)之后,我们得到每个系统CPU的每CPU使用量。
- 现在我们需要将步骤3的结果和分配给docker容器的CPU总数相乘,以获得每个系统CPU的总CPU使用量。
- 步骤4乘以100后的结果为我们提供了百分比的CPU利用率。
返回到问题: 系统CPU如何由docker进行计算?
要计算系统CPU使用率,docker使用POSIX定义的“/ proc/stat”。它查找CPU统计数据行,然后总结提供的前七个字段。下面将介绍为执行所需步骤而编写的golang代码。
// getSystemCPUUsage returns the host system's cpu usage in
// nanoseconds. An error is returned if the format of the underlying
// file does not match.
//
// Uses /proc/stat defined by POSIX. Looks for the cpu
// statistics line and then sums up the first seven fields
// provided. See `man 5 proc` for details on specific field
// information.
func (s *statsCollector) getSystemCPUUsage() (uint64, error) {
var line string
f, err := os.Open("/proc/stat")
if err != nil {
return 0, err
}
defer func() {
s.bufReader.Reset(nil)
f.Close()
}()
s.bufReader.Reset(f)
err = nil
for err == nil {
line, err = s.bufReader.ReadString('\n')
if err != nil {
break
}
parts := strings.Fields(line)
switch parts[0] {
case "cpu":
if len(parts) < 8 {
return 0, derr.ErrorCodeBadCPUFields
}
var totalClockTicks uint64
for _, i := range parts[1:8] {
v, err := strconv.ParseUint(i, 10, 64)
if err != nil {
return 0, derr.ErrorCodeBadCPUInt.WithArgs(i, err)
}
totalClockTicks += v
}
return (totalClockTicks * nanoSecondsPerSecond)/
s.clockTicksPerSecond, nil
}
}
return 0, derr.ErrorCodeBadStatFormat
}
请匹配搬运工的 “system_cpu_usage” 统计API与下面提到命令的输出,以确认:
cat /proc/stat|grep -w cpu|awk '{split($0,a,\" \"); sum=0; for(i=2;i<8;i++)(sum+=a[i])} END{print sum }'