From aa25a3ca32dc750f786320c6bb3d5e334c6ca114 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 8 Dec 2019 12:52:01 -0300 Subject: [PATCH] Fix for when ncpu <= 0 --- c_api/api_aix.go | 70 -------------------------------------------- collector/cpu_aix.go | 68 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 75 deletions(-) delete mode 100644 c_api/api_aix.go diff --git a/c_api/api_aix.go b/c_api/api_aix.go deleted file mode 100644 index b317aee..0000000 --- a/c_api/api_aix.go +++ /dev/null @@ -1,70 +0,0 @@ -package c_api - -/* -#cgo LDFLAGS: -lperfstat -#include -#include -#include -#include -#include - -u_longlong_t **ref; - -int getCPUTicks(uint64_t **cputicks, size_t *cpu_ticks_len) { - int i, ncpus, cputotal; - perfstat_id_t firstcpu; - perfstat_cpu_t *statp; - - cputotal = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); - if (cputotal <= 0){ - return -1; - } - - statp = calloc(cputotal, sizeof(perfstat_cpu_t)); - if(statp==NULL){ - return -1; - } - ncpus = perfstat_cpu(&firstcpu, statp, sizeof(perfstat_cpu_t), cputotal); - *cpu_ticks_len = ncpus*4; - - *cputicks = (uint64_t *) malloc(sizeof(uint64_t)*(*cpu_ticks_len)); - for (i = 0; i < ncpus; i++) { - int offset = 4 * i; - (*cputicks)[offset] = statp[i].user; - (*cputicks)[offset+1] = statp[i].sys; - (*cputicks)[offset+2] = statp[i].wait; - (*cputicks)[offset+3] = statp[i].idle; - printf("%d", statp[i].user); - } - return 0; -} -*/ -import "C" - -import ( - "errors" - "unsafe" -) - -const ClocksPerSec = float64(C.CLK_TCK) -const maxCPUTimesLen = 1024 * 4 - -func GetAIXCPUTimes() ([]float64, error) { - var ( - cpuTimesC *C.uint64_t - cpuTimesLength C.size_t - ) - - if C.getCPUTicks(&cpuTimesC, &cpuTimesLength) == -1 { - return nil, errors.New("could not retrieve CPU times") - } - defer C.free(unsafe.Pointer(cpuTimesC)) - cput := (*[maxCPUTimesLen]C.u_longlong_t)(unsafe.Pointer(cpuTimesC))[:cpuTimesLength:cpuTimesLength] - - cpuTicks := make([]float64, cpuTimesLength) - for i, value := range cput { - cpuTicks[i] = float64(value) / ClocksPerSec - } - return cpuTicks, nil - -} diff --git a/collector/cpu_aix.go b/collector/cpu_aix.go index 95a3ab1..f6d4bc0 100644 --- a/collector/cpu_aix.go +++ b/collector/cpu_aix.go @@ -1,11 +1,58 @@ package collector +/* +#cgo LDFLAGS: -lperfstat +#include +#include +#include +#include +#include + +u_longlong_t **ref; + +int getCPUTicks(uint64_t **cputicks, size_t *cpu_ticks_len) { + int i, ncpus, cputotal; + perfstat_id_t firstcpu; + perfstat_cpu_t *statp; + + cputotal = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); + if (cputotal <= 0){ + return -1; + } + + statp = calloc(cputotal, sizeof(perfstat_cpu_t)); + if(statp==NULL){ + return -1; + } + ncpus = perfstat_cpu(&firstcpu, statp, sizeof(perfstat_cpu_t), cputotal); + if (ncpus <= 0) { + ncpus = cputotal; + } + + *cpu_ticks_len = ncpus*4; + *cputicks = (uint64_t *) malloc(sizeof(uint64_t)*(*cpu_ticks_len)); + for (i = 0; i < ncpus; i++) { + int offset = 4 * i; + (*cputicks)[offset] = statp[i].user; + (*cputicks)[offset+1] = statp[i].sys; + (*cputicks)[offset+2] = statp[i].wait; + (*cputicks)[offset+3] = statp[i].idle; + } + return 0; +} +*/ +import "C" + import ( + "errors" "fmt" - "github.com/dlopes7/aix-prometheus-exporter/c_api" "github.com/prometheus/client_golang/prometheus" + "unsafe" ) +const ClocksPerSec = float64(C.CLK_TCK) +const maxCPUTimesLen = 1024 * 4 + type statCollector struct { cpu *prometheus.Desc } @@ -24,12 +71,23 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) error { var fieldsCount = 4 cpuFields := []string{"user", "sys", "wait", "idle"} - cpuTimes, err := c_api.GetAIXCPUTimes() - if err != nil { - return err + var ( + cpuTimesC *C.uint64_t + cpuTimesLength C.size_t + ) + + if C.getCPUTicks(&cpuTimesC, &cpuTimesLength) == -1 { + return errors.New("could not retrieve CPU times") + } + defer C.free(unsafe.Pointer(cpuTimesC)) + cput := (*[maxCPUTimesLen]C.u_longlong_t)(unsafe.Pointer(cpuTimesC))[:cpuTimesLength:cpuTimesLength] + + cpuTicks := make([]float64, cpuTimesLength) + for i, value := range cput { + cpuTicks[i] = float64(value) / ClocksPerSec } - for i, value := range cpuTimes { + for i, value := range cpuTicks { cpux := fmt.Sprintf("CPU %d", i/fieldsCount) ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, value, cpux, cpuFields[i%fieldsCount]) }