72 lines
1.4 KiB
Go
72 lines
1.4 KiB
Go
// Copyright (C) 2020 Marius Schellenberger
|
|
|
|
package syspatch
|
|
|
|
import (
|
|
"bytes"
|
|
"github.com/go-kit/kit/log"
|
|
"github.com/go-kit/kit/log/level"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"os/exec"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
namespace = "syspatch"
|
|
syspatch = "/usr/sbin/syspatch"
|
|
|
|
errUpdateInterval = time.Second * 30
|
|
updateInterval = time.Hour * 2
|
|
)
|
|
|
|
type Collector struct {
|
|
sync.RWMutex
|
|
patches *prometheus.Desc
|
|
logger log.Logger
|
|
|
|
num float64
|
|
}
|
|
|
|
// NewCollector returns a new Collector exposing rcctl statistics.
|
|
func NewCollector(logger log.Logger) (*Collector, error) {
|
|
c := &Collector{
|
|
patches: prometheus.NewDesc(
|
|
prometheus.BuildFQName(namespace, "", "patches_available"),
|
|
"Number of syspatch patches available.",
|
|
nil, nil,
|
|
),
|
|
logger: logger,
|
|
}
|
|
go c.getPatches()
|
|
return c, nil
|
|
}
|
|
|
|
func (c *Collector) getPatches() {
|
|
for {
|
|
cmd := exec.Command(syspatch, "-c")
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
level.Debug(c.logger).Log("msg", "syspatch list patches", "error", err)
|
|
time.Sleep(errUpdateInterval)
|
|
continue
|
|
}
|
|
num := float64(bytes.Count(out, []byte("\n")))
|
|
c.Lock()
|
|
c.num = num
|
|
c.Unlock()
|
|
time.Sleep(updateInterval)
|
|
}
|
|
}
|
|
|
|
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
|
|
c.RLock()
|
|
num := c.num
|
|
c.RUnlock()
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.patches, prometheus.GaugeValue, num)
|
|
}
|
|
|
|
func (c *Collector) Describe(desc chan<- *prometheus.Desc) {
|
|
desc <- c.patches
|
|
}
|