Skip to content

Commit

Permalink
Podman Stats additional features
Browse files Browse the repository at this point in the history
added Avg Cpu calculation and CPU up time to podman stats. Adding different feature sets in different PRs, CPU first.

resolves containers#9258

Signed-off-by: cdoern <cbdoer23@g.holycross.edu>
  • Loading branch information
cdoern committed Jun 16, 2021
1 parent 2970e35 commit cb58da4
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
16 changes: 15 additions & 1 deletion cmd/podman/containers/stats.go
Expand Up @@ -146,7 +146,9 @@ func stats(cmd *cobra.Command, args []string) error {
func outputStats(reports []define.ContainerStats) error {
headers := report.Headers(define.ContainerStats{}, map[string]string{
"ID": "ID",
"UpTime": "CPU TIME (S)",
"CPUPerc": "CPU %",
"AVGCPU": "Avg CPU %",
"MemUsage": "MEM USAGE / LIMIT",
"MemUsageBytes": "MEM USAGE / LIMIT",
"MemPerc": "MEM %",
Expand All @@ -166,7 +168,7 @@ func outputStats(reports []define.ContainerStats) error {
if report.IsJSON(statsOptions.Format) {
return outputJSON(stats)
}
format := "{{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\n"
format := "{{.ID}}\t{{.Name}}\t{{.UpTime}}\t{{.CPUPerc}}\t{{.AVGCPU}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\n"
if len(statsOptions.Format) > 0 {
format = report.NormalizeFormat(statsOptions.Format)
}
Expand Down Expand Up @@ -202,6 +204,14 @@ func (s *containerStats) CPUPerc() string {
return floatToPercentString(s.CPU)
}

func (s *containerStats) AVGCPU() string {
return floatToPercentString(s.AvgCPU)
}

func (s *containerStats) Up() string {
return fmt.Sprint(s.UpTime)
}

func (s *containerStats) MemPerc() string {
return floatToPercentString(s.ContainerStats.MemPerc)
}
Expand Down Expand Up @@ -257,7 +267,9 @@ func outputJSON(stats []containerStats) error {
type jstat struct {
Id string `json:"id"` // nolint
Name string `json:"name"`
CPUTime string `json:"cpu_time"`
CpuPercent string `json:"cpu_percent"` // nolint
AverageCPU string `json:"avg_cpu"`
MemUsage string `json:"mem_usage"`
MemPerc string `json:"mem_percent"`
NetIO string `json:"net_io"`
Expand All @@ -269,7 +281,9 @@ func outputJSON(stats []containerStats) error {
jstats = append(jstats, jstat{
Id: j.ID(),
Name: j.Name,
CPUTime: j.Up(),
CpuPercent: j.CPUPerc(),
AverageCPU: j.AVGCPU(),
MemUsage: j.MemUsage(),
MemPerc: j.MemPerc(),
NetIO: j.NetIO(),
Expand Down
10 changes: 9 additions & 1 deletion libpod/define/containerstate.go
@@ -1,6 +1,10 @@
package define

import "github.com/pkg/errors"
import (
"time"

"github.com/pkg/errors"
)

// ContainerStatus represents the current state of a container
type ContainerStatus int
Expand Down Expand Up @@ -120,7 +124,9 @@ func (s ContainerExecStatus) String() string {

// ContainerStats contains the statistics information for a running container
type ContainerStats struct {
AvgCPU float64
ContainerID string
CPUTrack []float64
Name string
PerCPU []uint64
CPU float64
Expand All @@ -135,4 +141,6 @@ type ContainerStats struct {
BlockInput uint64
BlockOutput uint64
PIDs uint64
UpTime time.Duration
Start time.Time
}
21 changes: 21 additions & 0 deletions libpod/stats.go
Expand Up @@ -56,7 +56,16 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de

previousCPU := previousStats.CPUNano
now := uint64(time.Now().UnixNano())
if previousStats.Start.IsZero() {
stats.Start = time.Now()
stats.UpTime = time.Since(stats.Start)
} else {
stats.Start = previousStats.Start
stats.UpTime = time.Since(previousStats.Start)
}
stats.CPU = calculateCPUPercent(cgroupStats, previousCPU, now, previousStats.SystemNano)
stats.AvgCPU = calculateAvgCPU(cgroupStats, previousStats.CPUTrack, now, previousStats.SystemNano)
stats.CPUTrack = append(previousStats.CPUTrack, float64(cgroupStats.CPU.Usage.Total))
stats.MemUsage = cgroupStats.Memory.Usage.Usage
stats.MemLimit = getMemLimit(cgroupStats.Memory.Usage.Limit)
stats.MemPerc = (float64(stats.MemUsage) / float64(stats.MemLimit)) * 100
Expand Down Expand Up @@ -127,3 +136,15 @@ func calculateBlockIO(stats *cgroups.Metrics) (read uint64, write uint64) {
}
return
}

// calculateAvgCPU calculates the avg CPU percentage given an array of previous CPU percentage stats.
func calculateAvgCPU(stats *cgroups.Metrics, CPUTrack []float64, now, previousSystem uint64) float64 {
var total float64
total = 0
for _, data := range CPUTrack {
total += data
}
total += float64(stats.CPU.Usage.Total)
avgPer := ((total / float64(len(CPUTrack)+1)) * 100)
return float64(avgPer)
}

0 comments on commit cb58da4

Please sign in to comment.