package services import ( "encoding/json" "fmt" "log" "github.com/docker/docker/api/types" units "github.com/docker/go-units" ) type collectStatsTask struct { mem float64 memLimit float64 memPercent float64 cpuPercent float64 previousCPU uint64 previousSystem uint64 } func (c collectStatsTask) Run(i *Instance) error { reader, err := GetContainerStats(i.Name) if err != nil { log.Println("Error while trying to collect instance stats", err) return err } dec := json.NewDecoder(reader) var v *types.StatsJSON e := dec.Decode(&v) if e != nil { log.Println("Error while trying to collect instance stats", e) return err } // Memory if v.MemoryStats.Limit != 0 { c.memPercent = float64(v.MemoryStats.Usage) / float64(v.MemoryStats.Limit) * 100.0 } c.mem = float64(v.MemoryStats.Usage) c.memLimit = float64(v.MemoryStats.Limit) i.Mem = fmt.Sprintf("%.2f%% (%s / %s)", c.memPercent, units.BytesSize(c.mem), units.BytesSize(c.memLimit)) // cpu c.previousCPU = v.PreCPUStats.CPUUsage.TotalUsage c.previousSystem = v.PreCPUStats.SystemUsage c.cpuPercent = calculateCPUPercentUnix(c.previousCPU, c.previousSystem, v) i.Cpu = fmt.Sprintf("%.2f%%", c.cpuPercent) return nil } 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 }