Skip to content

Commit

Permalink
Merge pull request #581 from CMGS/master
Browse files Browse the repository at this point in the history
get docker container cpu usage from cpuacct.usage
  • Loading branch information
shirou authored Sep 27, 2018
2 parents 77e5abb + 80b3769 commit a11c78b
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 16 deletions.
24 changes: 12 additions & 12 deletions cpu/cpu_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/shirou/gopsutil/internal/common"
)

var cpu_tick = float64(100)
var CPUTick = float64(100)

func init() {
getconf, err := exec.LookPath("/usr/bin/getconf")
Expand All @@ -25,7 +25,7 @@ func init() {
if err == nil {
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
if err == nil {
cpu_tick = float64(i)
CPUTick = i
}
}
}
Expand Down Expand Up @@ -250,34 +250,34 @@ func parseStatLine(line string) (*TimesStat, error) {

ct := &TimesStat{
CPU: cpu,
User: float64(user) / cpu_tick,
Nice: float64(nice) / cpu_tick,
System: float64(system) / cpu_tick,
Idle: float64(idle) / cpu_tick,
Iowait: float64(iowait) / cpu_tick,
Irq: float64(irq) / cpu_tick,
Softirq: float64(softirq) / cpu_tick,
User: user / CPUTick,
Nice: nice / CPUTick,
System: system / CPUTick,
Idle: idle / CPUTick,
Iowait: iowait / CPUTick,
Irq: irq / CPUTick,
Softirq: softirq / CPUTick,
}
if len(fields) > 8 { // Linux >= 2.6.11
steal, err := strconv.ParseFloat(fields[8], 64)
if err != nil {
return nil, err
}
ct.Steal = float64(steal) / cpu_tick
ct.Steal = steal / CPUTick
}
if len(fields) > 9 { // Linux >= 2.6.24
guest, err := strconv.ParseFloat(fields[9], 64)
if err != nil {
return nil, err
}
ct.Guest = float64(guest) / cpu_tick
ct.Guest = guest / CPUTick
}
if len(fields) > 10 { // Linux >= 3.2.0
guestNice, err := strconv.ParseFloat(fields[10], 64)
if err != nil {
return nil, err
}
ct.GuestNice = float64(guestNice) / cpu_tick
ct.GuestNice = guestNice / CPUTick
}

return ct, nil
Expand Down
8 changes: 8 additions & 0 deletions docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"

"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
)

Expand All @@ -12,6 +13,13 @@ var ErrCgroupNotAvailable = errors.New("cgroup not available")

var invoke common.Invoker = common.Invoke{}

const nanoseconds = 1e9

type CgroupCPUStat struct {
cpu.TimesStat
Usage float64
}

type CgroupMemStat struct {
ContainerID string `json:"containerID"`
Cache uint64 `json:"cache"`
Expand Down
32 changes: 29 additions & 3 deletions docker/docker_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ func CgroupCPU(containerID string, base string) (*cpu.TimesStat, error) {
return CgroupCPUWithContext(context.Background(), containerID, base)
}

// CgroupCPUUsage returnes specified cgroup id CPU usage.
// containerID is same as docker id if you use docker.
// If you use container via systemd.slice, you could use
// containerID = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
func CgroupCPUUsage(containerID string, base string) (float64, error) {
return CgroupCPUUsageWithContext(context.Background(), containerID, base)
}

func CgroupCPUWithContext(ctx context.Context, containerID string, base string) (*cpu.TimesStat, error) {
statfile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.stat")
lines, err := common.ReadLines(statfile)
Expand All @@ -109,20 +117,34 @@ func CgroupCPUWithContext(ctx context.Context, containerID string, base string)
if fields[0] == "user" {
user, err := strconv.ParseFloat(fields[1], 64)
if err == nil {
ret.User = float64(user)
ret.User = user / cpu.CPUTick
}
}
if fields[0] == "system" {
system, err := strconv.ParseFloat(fields[1], 64)
if err == nil {
ret.System = float64(system)
ret.System = system / cpu.CPUTick
}
}
}

return ret, nil
}

func CgroupCPUUsageWithContext(ctx context.Context, containerID, base string) (float64, error) {
usagefile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.usage")
lines, err := common.ReadLinesOffsetN(usagefile, 0, 1)
if err != nil {
return 0.0, err
}

ns, err := strconv.ParseFloat(lines[0], 64)
if err != nil {
return 0.0, err
}

return ns / nanoseconds, nil
}

func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) {
return CgroupCPUDockerWithContext(context.Background(), containerid)
}
Expand All @@ -131,6 +153,10 @@ func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*cpu.T
return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
}

func CgroupCPUDockerUsageWithContext(ctx context.Context, containerid string) (float64, error) {
return CgroupCPUUsage(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
}

func CgroupMem(containerID string, base string) (*CgroupMemStat, error) {
return CgroupMemWithContext(context.Background(), containerID, base)
}
Expand Down
3 changes: 2 additions & 1 deletion docker/docker_notlinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ package docker

import (
"context"
"github.com/shirou/gopsutil/cpu"

cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
)

Expand Down

0 comments on commit a11c78b

Please sign in to comment.