sys-exporter/collector/loadavg/loadavg.go

86 lines
2.2 KiB
Go

package loadavg
import (
"context"
"fmt"
"os"
"strconv"
"strings"
"time"
"git.faercol.me/monitoring/sys-exporter/registry"
"github.com/prometheus/client_golang/prometheus"
)
const loadAvgFileLocation = "/proc/loadavg"
type LoadAvgCollector struct {
loadAvgFileLocation string
promExporter *prometheus.SummaryVec
updateFreq time.Duration
}
func (c *LoadAvgCollector) Collect() interface{} {
return nil
}
func (c *LoadAvgCollector) update() error {
fileContent, err := os.ReadFile(c.loadAvgFileLocation)
if err != nil {
return fmt.Errorf("failed to read loadavg file: %w", err)
}
vals := strings.Split(string(fileContent), " ")
if len(vals) != 5 {
return fmt.Errorf("invalid format %q for loadavg file", string(fileContent))
}
var load1Min, load5Min, load15Min float64
if load1Min, err = strconv.ParseFloat(vals[0], 64); err != nil {
return fmt.Errorf("invalid value %q for load 1min: %w", vals[0], err)
}
if load5Min, err = strconv.ParseFloat(vals[1], 64); err != nil {
return fmt.Errorf("invalid value %q for load 5mins: %w", vals[1], err)
}
if load15Min, err = strconv.ParseFloat(vals[2], 64); err != nil {
return fmt.Errorf("invalid value %q for load 15min: %w", vals[2], err)
}
c.promExporter.WithLabelValues("1min").Observe(load1Min)
c.promExporter.WithLabelValues("5mins").Observe(load5Min)
c.promExporter.WithLabelValues("15mins").Observe(load15Min)
return nil
}
func (c *LoadAvgCollector) Run(ctx context.Context) {
if err := c.update(); err != nil {
fmt.Printf("Failed to init loadavg collector: %s\n", err)
}
for {
select {
case <-ctx.Done():
return
case <-time.After(c.updateFreq):
if err := c.update(); err != nil {
fmt.Printf("Failed to update loadavg collector: %s\n", err)
}
}
}
}
func (c *LoadAvgCollector) PromCollector() prometheus.Collector {
return c.promExporter
}
func New() *LoadAvgCollector {
return &LoadAvgCollector{
updateFreq: 1 * time.Second,
loadAvgFileLocation: loadAvgFileLocation,
promExporter: prometheus.NewSummaryVec(prometheus.SummaryOpts{Namespace: "system", Name: "loadavg", Help: "Load average of the system"}, []string{"period"}),
}
}
func init() {
registry.R.MustRegisterCollector("system.loadavg", New())
}