sys-exporter/collector/loadavg/loadavg.go

94 lines
2.4 KiB
Go
Raw Permalink Normal View History

2024-12-01 17:12:19 +00:00
package loadavg
import (
"context"
"fmt"
"os"
"strconv"
"strings"
"time"
"git.faercol.me/monitoring/sys-exporter/registry"
"github.com/prometheus/client_golang/prometheus"
2024-12-02 17:37:19 +00:00
"go.uber.org/zap"
2024-12-01 17:12:19 +00:00
)
const loadAvgFileLocation = "/proc/loadavg"
type LoadAvgCollector struct {
loadAvgFileLocation string
promExporter *prometheus.SummaryVec
updateFreq time.Duration
2024-12-02 17:37:19 +00:00
l *zap.SugaredLogger
2024-12-01 17:12:19 +00:00
}
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
}
2024-12-02 17:37:19 +00:00
func (c *LoadAvgCollector) Run(ctx context.Context, l *zap.SugaredLogger) {
c.l = l
c.l.Debug("Initializing collector")
2024-12-01 17:12:19 +00:00
if err := c.update(); err != nil {
2024-12-02 17:37:19 +00:00
c.l.Errorf("Failed to init collector: %s\n", err)
2024-12-01 17:12:19 +00:00
}
for {
select {
case <-ctx.Done():
2024-12-02 17:37:19 +00:00
c.l.Debug("Stopping collector")
2024-12-01 17:12:19 +00:00
return
case <-time.After(c.updateFreq):
2024-12-02 17:37:19 +00:00
c.l.Debug("Updating collector")
2024-12-01 17:12:19 +00:00
if err := c.update(); err != nil {
2024-12-02 17:37:19 +00:00
c.l.Errorf("Failed to update collector: %s\n", err)
2024-12-01 17:12:19 +00:00
}
}
}
}
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())
}