Skip to content

Commit

Permalink
Support cgroup v2 (#28)
Browse files Browse the repository at this point in the history
Fixes #27
  • Loading branch information
treydock authored Jan 24, 2024
1 parent 74271ef commit f60e0b3
Show file tree
Hide file tree
Showing 11 changed files with 7,023 additions and 697 deletions.
456 changes: 8 additions & 448 deletions cgroup_exporter.go

Large diffs are not rendered by default.

247 changes: 3 additions & 244 deletions cgroup_exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import (
"net/http"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"testing"
"time"

kingpin "github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
"github.com/treydock/cgroup_exporter/collector"
)

const (
Expand All @@ -40,12 +40,11 @@ func TestMain(m *testing.M) {
_, filename, _, _ := runtime.Caller(0)
dir := filepath.Dir(filename)
fixture := filepath.Join(dir, "fixtures")
cgroupRoot = &fixture
collector.CgroupRoot = &fixture
procFixture := filepath.Join(fixture, "proc")
procRoot = &procFixture
collector.ProcRoot = &procFixture
varTrue := true
disableExporterMetrics = &varTrue
collectProc = &varTrue
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
go func() {
Expand All @@ -62,246 +61,6 @@ func TestMain(m *testing.M) {
os.Exit(exitVal)
}

func TestParseCpuSet(t *testing.T) {
expected := []string{"0", "1", "2"}
if cpus, err := parseCpuSet("0-2"); err != nil {
t.Errorf("Unexpected error: %s", err.Error())
} else if !reflect.DeepEqual(cpus, expected) {
t.Errorf("Unexpected cpus, expected %v got %v", expected, cpus)
}
expected = []string{"0", "1", "4", "5", "8", "9"}
if cpus, err := parseCpuSet("0-1,4-5,8-9"); err != nil {
t.Errorf("Unexpected error: %s", err.Error())
} else if !reflect.DeepEqual(cpus, expected) {
t.Errorf("Unexpected cpus, expected %v got %v", expected, cpus)
}
expected = []string{"1", "3", "5", "7"}
if cpus, err := parseCpuSet("1,3,5,7"); err != nil {
t.Errorf("Unexpected error: %s", err.Error())
} else if !reflect.DeepEqual(cpus, expected) {
t.Errorf("Unexpected cpus, expected %v got %v", expected, cpus)
}
}

func TestGetProcInfo(t *testing.T) {
metric := CgroupMetric{}
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
getProcInfo([]int{95521, 95525}, &metric, logger)
if val, ok := metric.processExec["/bin/bash"]; !ok {
t.Errorf("Process /bin/bash not in metrics")
return
} else {
if val != 2 {
t.Errorf("Expected 2 /bin/bash processes, got %v", val)
}
}
varLen := 6
collectProcMaxExec = &varLen
getProcInfo([]int{95521, 95525}, &metric, logger)
if val, ok := metric.processExec["/bi...ash"]; !ok {
t.Errorf("Process /bin/bash not in metrics, found: %v", metric.processExec)
return
} else {
if val != 2 {
t.Errorf("Expected 2 /b...sh processes, got %v", val)
}
}
}

func TestCollectUserSlice(t *testing.T) {
varFalse := false
collectProc = &varFalse
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
exporter := NewExporter([]string{"/user.slice"}, logger)
metrics, err := exporter.collect()
if err != nil {
t.Errorf("Unexpected error: %s", err.Error())
return
}
if val := len(metrics); val != 1 {
t.Errorf("Unexpected number of metrics, got %d expected 1", val)
return
}
if val := metrics[0].cpuUser; val != 0.41 {
t.Errorf("Unexpected value for cpuUser, got %v", val)
}
if val := metrics[0].cpuSystem; val != 0.39 {
t.Errorf("Unexpected value for cpuSystem, got %v", val)
}
if val := metrics[0].cpuTotal; val != 0.831825022 {
t.Errorf("Unexpected value for cpuTotal, got %v", val)
}
if val := metrics[0].cpus; val != 0 {
t.Errorf("Unexpected value for cpus, got %v", val)
}
if val := metrics[0].memoryRSS; val != 5378048 {
t.Errorf("Unexpected value for memoryRSS, got %v", val)
}
if val := metrics[0].memoryCache; val != 2322432 {
t.Errorf("Unexpected value for memoryCache, got %v", val)
}
if val := metrics[0].memoryUsed; val != 8081408 {
t.Errorf("Unexpected value for memoryUsed, got %v", val)
}
if val := metrics[0].memoryTotal; val != 68719476736 {
t.Errorf("Unexpected value for memoryTotal, got %v", val)
}
if val := metrics[0].memoryFailCount; val != 0 {
t.Errorf("Unexpected value for memoryFailCount, got %v", val)
}
if val := metrics[0].memswUsed; val != 8081408 {
t.Errorf("Unexpected value for swapUsed, got %v", val)
}
if val := metrics[0].memswTotal; val != 9.223372036854772e+18 {
t.Errorf("Unexpected value for swapTotal, got %v", val)
}
if val := metrics[0].memswFailCount; val != 0 {
t.Errorf("Unexpected value for swapFailCount, got %v", val)
}
if val := metrics[0].uid; val != "20821" {
t.Errorf("Unexpected value for uid, got %v", val)
}
}

func TestCollectSLURM(t *testing.T) {
varTrue := true
collectProc = &varTrue
varLen := 100
collectProcMaxExec = &varLen
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
exporter := NewExporter([]string{"/slurm"}, logger)
metrics, err := exporter.collect()
if err != nil {
t.Errorf("Unexpected error: %s", err.Error())
return
}
if val := len(metrics); val != 2 {
t.Errorf("Unexpected number of metrics, got %d expected 2", val)
return
}
var m CgroupMetric
for _, metric := range metrics {
if metric.jobid == "10" {
m = metric
}
}
if m.jobid == "" {
t.Errorf("Metrics with jobid=10 not found")
return
}
if val := m.cpuUser; val != 0 {
t.Errorf("Unexpected value for cpuUser, got %v", val)
}
if val := m.cpuSystem; val != 0 {
t.Errorf("Unexpected value for cpuSystem, got %v", val)
}
if val := m.cpuTotal; val != 0.007710215 {
t.Errorf("Unexpected value for cpuTotal, got %v", val)
}
if val := m.cpus; val != 2 {
t.Errorf("Unexpected value for cpus, got %v", val)
}
if val := m.memoryRSS; val != 311296 {
t.Errorf("Unexpected value for memoryRSS, got %v", val)
}
if val := m.memoryCache; val != 4096 {
t.Errorf("Unexpected value for memoryCache, got %v", val)
}
if val := m.memoryUsed; val != 356352 {
t.Errorf("Unexpected value for memoryUsed, got %v", val)
}
if val := m.memoryTotal; val != 2147483648 {
t.Errorf("Unexpected value for memoryTotal, got %v", val)
}
if val := m.memoryFailCount; val != 0 {
t.Errorf("Unexpected value for memoryFailCount, got %v", val)
}
if val := m.memswUsed; val != 356352 {
t.Errorf("Unexpected value for swapUsed, got %v", val)
}
if val := m.memswTotal; val != 2147483648 {
t.Errorf("Unexpected value for swapTotal, got %v", val)
}
if val := m.memswFailCount; val != 0 {
t.Errorf("Unexpected value for swapFailCount, got %v", val)
}
if val := m.uid; val != "20821" {
t.Errorf("Unexpected value for uid, got %v", val)
}
if val := m.jobid; val != "10" {
t.Errorf("Unexpected value for jobid, got %v", val)
}
if val, ok := m.processExec["/bin/bash"]; !ok {
t.Errorf("processExec does not contain /bin/bash")
} else {
if val != 2 {
t.Errorf("Unexpected 2 values for processExec /bin/bash, got %v", val)
}
}
}

func TestCollectTorque(t *testing.T) {
varFalse := false
collectProc = &varFalse
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
exporter := NewExporter([]string{"/torque"}, logger)
metrics, err := exporter.collect()
if err != nil {
t.Errorf("Unexpected error: %s", err.Error())
return
}
if val := len(metrics); val != 1 {
t.Errorf("Unexpected number of metrics, got %d expected 1", val)
return
}
if val := metrics[0].cpuUser; val != 153146.31 {
t.Errorf("Unexpected value for cpuUser, got %v", val)
}
if val := metrics[0].cpuSystem; val != 260.77 {
t.Errorf("Unexpected value for cpuSystem, got %v", val)
}
if val := metrics[0].cpuTotal; val != 152995.785583781 {
t.Errorf("Unexpected value for cpuTotal, got %v", val)
}
if val := metrics[0].cpus; val != 40 {
t.Errorf("Unexpected value for cpus, got %v", val)
}
if val := metrics[0].memoryRSS; val != 82444320768 {
t.Errorf("Unexpected value for memoryRSS, got %v", val)
}
if val := metrics[0].memoryCache; val != 109678592 {
t.Errorf("Unexpected value for memoryCache, got %v", val)
}
if val := metrics[0].memoryUsed; val != 82553999360 {
t.Errorf("Unexpected value for memoryUsed, got %v", val)
}
if val := metrics[0].memoryTotal; val != 196755132416 {
t.Errorf("Unexpected value for memoryTotal, got %v", val)
}
if val := metrics[0].memoryFailCount; val != 0 {
t.Errorf("Unexpected value for memoryFailCount, got %v", val)
}
if val := metrics[0].memswUsed; val != 82553999360 {
t.Errorf("Unexpected value for swapUsed, got %v", val)
}
if val := metrics[0].memswTotal; val != 196755132416 {
t.Errorf("Unexpected value for swapTotal, got %v", val)
}
if val := metrics[0].memswFailCount; val != 0 {
t.Errorf("Unexpected value for swapFailCount, got %v", val)
}
if val := metrics[0].uid; val != "" {
t.Errorf("Unexpected value for uid, got %v", val)
}
if val := metrics[0].jobid; val != "1182724" {
t.Errorf("Unexpected value for jobid, got %v", val)
}
}

func TestMetricsHandler(t *testing.T) {
body, err := queryExporter()
if err != nil {
Expand Down
Loading

0 comments on commit f60e0b3

Please sign in to comment.