diff --git a/cgroup_exporter.go b/cgroup_exporter.go index 2ee9687..ac561e8 100644 --- a/cgroup_exporter.go +++ b/cgroup_exporter.go @@ -20,7 +20,7 @@ import ( "strings" "github.com/alecthomas/kingpin/v2" - "github.com/containerd/cgroups" + "github.com/containerd/cgroups/v3" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" diff --git a/cgroup_exporter_test.go b/cgroup_exporter_test.go index 8fafd6e..cf3680e 100644 --- a/cgroup_exporter_test.go +++ b/cgroup_exporter_test.go @@ -91,7 +91,7 @@ func TestMetricsHandlerBadPath(t *testing.T) { t.Fatalf("Unexpected error GET /metrics: %s", err.Error()) } if !strings.Contains(body, "cgroup_exporter_collect_error{cgroup=\"/dne\"} 1") { - t.Errorf("Unexpected value for cgroup_memory_used_bytes") + t.Errorf("Unexpected value for cgroup_exporter_collect_error: %s", body) } } diff --git a/collector/cgroupv1.go b/collector/cgroupv1.go index 260dd7e..4c2923c 100644 --- a/collector/cgroupv1.go +++ b/collector/cgroupv1.go @@ -21,7 +21,7 @@ import ( "strings" "sync" - "github.com/containerd/cgroups" + "github.com/containerd/cgroups/v3/cgroup1" "github.com/go-kit/log" "github.com/go-kit/log/level" ) @@ -30,10 +30,10 @@ func NewCgroupV1Collector(paths []string, logger log.Logger) Collector { return NewExporter(paths, logger, false) } -func subsystem() ([]cgroups.Subsystem, error) { - s := []cgroups.Subsystem{ - cgroups.NewCpuacct(*CgroupRoot), - cgroups.NewMemory(*CgroupRoot), +func subsystem() ([]cgroup1.Subsystem, error) { + s := []cgroup1.Subsystem{ + cgroup1.NewCpuacct(*CgroupRoot), + cgroup1.NewMemory(*CgroupRoot), } return s, nil } @@ -75,7 +75,7 @@ func getInfov1(name string, metric *CgroupMetric, logger log.Logger) { } } -func getNamev1(p cgroups.Process, path string, logger log.Logger) (string, error) { +func getNamev1(p cgroup1.Process, logger log.Logger) (string, error) { cpuacctPath := filepath.Join(*CgroupRoot, "cpuacct") name := strings.TrimPrefix(p.Path, cpuacctPath) name = strings.TrimSuffix(name, "/") @@ -103,15 +103,13 @@ func getNamev1(p cgroups.Process, path string, logger log.Logger) (string, error func (e *Exporter) getMetricsv1(name string, pids map[string][]int) (CgroupMetric, error) { metric := CgroupMetric{name: name} level.Debug(e.logger).Log("msg", "Loading cgroup", "root", *CgroupRoot, "path", name) - ctrl, err := cgroups.Load(subsystem, func(subsystem cgroups.Name) (string, error) { - return name, nil - }) + ctrl, err := cgroup1.Load(cgroup1.StaticPath(name), cgroup1.WithHiearchy(subsystem)) if err != nil { level.Error(e.logger).Log("msg", "Failed to load cgroups", "path", name, "err", err) metric.err = true return metric, err } - stats, err := ctrl.Stat(cgroups.IgnoreNotExist) + stats, err := ctrl.Stat(cgroup1.IgnoreNotExist) if err != nil { level.Error(e.logger).Log("msg", "Failed to stat cgroups", "path", name, "err", err) metric.err = true @@ -166,14 +164,14 @@ func (e *Exporter) collectv1() ([]CgroupMetric, error) { var metrics []CgroupMetric for _, path := range e.paths { level.Debug(e.logger).Log("msg", "Loading cgroup", "root", *CgroupRoot, "path", path) - control, err := cgroups.Load(subsystem, cgroups.StaticPath(path)) + control, err := cgroup1.Load(cgroup1.StaticPath(path), cgroup1.WithHiearchy(subsystem)) if err != nil { level.Error(e.logger).Log("msg", "Error loading cgroup subsystem", "root", *CgroupRoot, "path", path, "err", err) metric := CgroupMetric{name: path, err: true} metrics = append(metrics, metric) continue } - processes, err := control.Processes(cgroups.Cpuacct, true) + processes, err := control.Processes(cgroup1.Cpuacct, true) if err != nil { level.Error(e.logger).Log("msg", "Error loading cgroup processes", "path", path, "err", err) metric := CgroupMetric{name: path, err: true} @@ -184,7 +182,7 @@ func (e *Exporter) collectv1() ([]CgroupMetric, error) { pids := make(map[string][]int) for _, p := range processes { level.Debug(e.logger).Log("msg", "Get Name", "process", p.Path, "pid", p.Pid, "path", path) - name, err := getNamev1(p, path, e.logger) + name, err := getNamev1(p, e.logger) if err != nil { level.Error(e.logger).Log("msg", "Error getting cgroup name for process", "process", p.Path, "path", path, "err", err) continue diff --git a/collector/cgroupv1_test.go b/collector/cgroupv1_test.go index 33397fb..88beb79 100644 --- a/collector/cgroupv1_test.go +++ b/collector/cgroupv1_test.go @@ -53,7 +53,7 @@ func TestCollectUserSlice(t *testing.T) { if val := metrics[0].memoryCache; val != 2322432 { t.Errorf("Unexpected value for memoryCache, got %v", val) } - if val := metrics[0].memoryUsed; val != 8081408 { + if val := metrics[0].memoryUsed; val != 27115520 { t.Errorf("Unexpected value for memoryUsed, got %v", val) } if val := metrics[0].memoryTotal; val != 68719476736 { diff --git a/collector/cgroupv2.go b/collector/cgroupv2.go index 61ede66..d784f5c 100644 --- a/collector/cgroupv2.go +++ b/collector/cgroupv2.go @@ -112,9 +112,9 @@ func getNamev2(pidPath string, path string, logger log.Logger) string { return name } -func getStatv2(name string, path string, logger log.Logger) (float64, error) { +func getStatv2(name string, path string) (float64, error) { if !fileExists(path) { - return 0, fmt.Errorf("Path %s does not exist", path) + return 0, fmt.Errorf("path %s does not exist", path) } f, err := os.Open(path) if err != nil { @@ -134,7 +134,7 @@ func getStatv2(name string, path string, logger log.Logger) (float64, error) { return float64(v), nil } } - return 0, fmt.Errorf("Unable to find stat key %s in %s", name, path) + return 0, fmt.Errorf("unable to find stat key %s in %s", name, path) } func (e *Exporter) getMetricsv2(name string, pids []int, opts cgroup2.InitOpts) (CgroupMetric, error) { @@ -164,7 +164,7 @@ func (e *Exporter) getMetricsv2(name string, pids []int, opts cgroup2.InitOpts) } // TODO: Move to https://github.com/containerd/cgroups/blob/d131035c7599c51ff4aed27903c45eb3b2cc29d0/cgroup2/manager.go#L593 memoryStatPath := filepath.Join(*CgroupRoot, name, "memory.stat") - swapcached, err := getStatv2("swapcached", memoryStatPath, e.logger) + swapcached, err := getStatv2("swapcached", memoryStatPath) if err != nil { level.Error(e.logger).Log("msg", "Unable to get swapcached", "path", name, "err", err) metric.err = true diff --git a/collector/cgroupv2_test.go b/collector/cgroupv2_test.go index cba295b..d4f4bdd 100644 --- a/collector/cgroupv2_test.go +++ b/collector/cgroupv2_test.go @@ -23,33 +23,31 @@ import ( ) func TestGetStatv2(t *testing.T) { - w := log.NewSyncWriter(os.Stderr) - logger := log.NewLogfmtLogger(w) - _, err := getStatv2("swapcached", "/dne", logger) + _, err := getStatv2("swapcached", "/dne") if err == nil { t.Errorf("Expected error with /dne but none given") } path := filepath.Join(*CgroupRoot, "system.slice") - _, err = getStatv2("swapcached", path, logger) + _, err = getStatv2("swapcached", path) if err == nil { t.Errorf("Expected error with /dne but none given") } path = filepath.Join(*CgroupRoot, "user.slice/user-20821.slice/memory.max") - _, err = getStatv2("swapcached", path, logger) + _, err = getStatv2("swapcached", path) if err == nil { t.Errorf("Expected error with single value file but none given") } path = filepath.Join(*CgroupRoot, "stat.invalid") - _, err = getStatv2("nan", path, logger) + _, err = getStatv2("nan", path) if err == nil { t.Errorf("Expected error with stat.invalid but none given") } path = filepath.Join(*CgroupRoot, "user.slice/user-20821.slice/memory.stat") - _, err = getStatv2("dne", path, logger) + _, err = getStatv2("dne", path) if err == nil { t.Errorf("Expected error when stat key missing but none given") } - stat, err := getStatv2("swapcached", path, logger) + stat, err := getStatv2("swapcached", path) if err != nil { t.Errorf("Unexpected error: %s", err) } diff --git a/fixtures.ttar b/fixtures.ttar index 7b00250..9ff6436 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -5124,7 +5124,7 @@ Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/memory/user.slice/user-20821.slice/memory.usage_in_bytes Lines: 1 -8081408 +27115520 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/memory/user.slice/user-20821.slice/memory.use_hierarchy diff --git a/go.mod b/go.mod index 04aaf72..7ca14a8 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.22 require ( github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/containerd/cgroups v1.1.0 github.com/containerd/cgroups/v3 v3.0.3 github.com/go-kit/log v0.2.1 github.com/prometheus/client_golang v1.19.1 @@ -21,7 +20,6 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect diff --git a/go.sum b/go.sum index 99b7f5d..1510e69 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk= github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -28,12 +26,8 @@ github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZs github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -61,40 +55,13 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=