From 510fa4ebc8271f929753275428ae2b6047ecc8c7 Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
Date: Wed, 12 Feb 2020 11:58:29 +0100
Subject: stats: add SystemUsage

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
---
 pkg/cgroups/cgroups.go | 15 ++++++++++-----
 pkg/cgroups/cpu.go     | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 5 deletions(-)

(limited to 'pkg/cgroups')

diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go
index 96786223d..6c5b7978c 100644
--- a/pkg/cgroups/cgroups.go
+++ b/pkg/cgroups/cgroups.go
@@ -536,15 +536,14 @@ func (c *CgroupControl) Stat() (*Metrics, error) {
 	return &m, nil
 }
 
-func readCgroup2MapFile(ctr *CgroupControl, name string) (map[string][]string, error) {
+func readCgroup2MapPath(path string) (map[string][]string, error) {
 	ret := map[string][]string{}
-	p := filepath.Join(cgroupRoot, ctr.path, name)
-	f, err := os.Open(p)
+	f, err := os.Open(path)
 	if err != nil {
 		if os.IsNotExist(err) {
 			return ret, nil
 		}
-		return nil, errors.Wrapf(err, "open file %s", p)
+		return nil, errors.Wrapf(err, "open file %s", path)
 	}
 	defer f.Close()
 	scanner := bufio.NewScanner(f)
@@ -557,7 +556,13 @@ func readCgroup2MapFile(ctr *CgroupControl, name string) (map[string][]string, e
 		ret[parts[0]] = parts[1:]
 	}
 	if err := scanner.Err(); err != nil {
-		return nil, errors.Wrapf(err, "parsing file %s", p)
+		return nil, errors.Wrapf(err, "parsing file %s", path)
 	}
 	return ret, nil
 }
+
+func readCgroup2MapFile(ctr *CgroupControl, name string) (map[string][]string, error) {
+	p := filepath.Join(cgroupRoot, ctr.path, name)
+
+	return readCgroup2MapPath(p)
+}
diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go
index a43a76b22..5f0a18031 100644
--- a/pkg/cgroups/cpu.go
+++ b/pkg/cgroups/cpu.go
@@ -121,3 +121,42 @@ func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error {
 	m.CPU = CPUMetrics{Usage: usage}
 	return nil
 }
+
+// GetSystemCPUUsage returns the system usage for all the cgroups
+func GetSystemCPUUsage() (uint64, error) {
+	cgroupv2, err := IsCgroup2UnifiedMode()
+	if err != nil {
+		return 0, err
+	}
+	if !cgroupv2 {
+		p := filepath.Join(cgroupRoot, CPUAcct, "cpuacct.usage")
+		return readFileAsUint64(p)
+	}
+
+	files, err := ioutil.ReadDir(cgroupRoot)
+	if err != nil {
+		return 0, errors.Wrapf(err, "read directory %q", cgroupRoot)
+	}
+	var total uint64
+	for _, file := range files {
+		if !file.IsDir() {
+			continue
+		}
+		p := filepath.Join(cgroupRoot, file.Name(), "cpu.stat")
+
+		values, err := readCgroup2MapPath(p)
+		if err != nil {
+			return 0, err
+		}
+
+		if val, found := values["usage_usec"]; found {
+			v, err := strconv.ParseUint(cleanString(val[0]), 10, 0)
+			if err != nil {
+				return 0, err
+			}
+			total += v * 1000
+		}
+
+	}
+	return total, nil
+}
-- 
cgit v1.2.3-54-g00ecf