Add background scanning for devices

Add a background routine to rescan in a specified interval for devices

Signed-off-by: Niklas Schwarz <schwarz.niklas@hotmail.de>
This commit is contained in:
Niklas Schwarz 2023-08-07 13:23:41 +02:00
parent 7af12a210f
commit 6f41855c36
2 changed files with 30 additions and 3 deletions

View file

@ -26,6 +26,9 @@ Flags:
--smartctl.path="/usr/sbin/smartctl" --smartctl.path="/usr/sbin/smartctl"
The path to the smartctl binary The path to the smartctl binary
--smartctl.interval=60s The interval between smartctl polls --smartctl.interval=60s The interval between smartctl polls
--smartctl.rescan=10m The interval between rescanning for new/disappeared devices. If the interval is smaller than 1s no
rescanning takes place. If any devices are configured with smartctl.device also no rescanning takes
place.
--smartctl.device=SMARTCTL.DEVICE ... --smartctl.device=SMARTCTL.DEVICE ...
The device to monitor (repeatable) The device to monitor (repeatable)
--smartctl.device-exclude="" --smartctl.device-exclude=""

30
main.go
View file

@ -16,6 +16,7 @@ package main
import ( import (
"net/http" "net/http"
"os" "os"
"sync"
"time" "time"
kingpin "github.com/alecthomas/kingpin/v2" kingpin "github.com/alecthomas/kingpin/v2"
@ -38,16 +39,18 @@ type SMARTctlManagerCollector struct {
Devices []string Devices []string
logger log.Logger logger log.Logger
mutex sync.Mutex
} }
// Describe sends the super-set of all possible descriptors of metrics // Describe sends the super-set of all possible descriptors of metrics
func (i SMARTctlManagerCollector) Describe(ch chan<- *prometheus.Desc) { func (i *SMARTctlManagerCollector) Describe(ch chan<- *prometheus.Desc) {
prometheus.DescribeByCollect(i, ch) prometheus.DescribeByCollect(i, ch)
} }
// Collect is called by the Prometheus registry when collecting metrics. // Collect is called by the Prometheus registry when collecting metrics.
func (i SMARTctlManagerCollector) Collect(ch chan<- prometheus.Metric) { func (i *SMARTctlManagerCollector) Collect(ch chan<- prometheus.Metric) {
info := NewSMARTctlInfo(ch) info := NewSMARTctlInfo(ch)
i.mutex.Lock()
for _, device := range i.Devices { for _, device := range i.Devices {
json := readData(i.logger, device) json := readData(i.logger, device)
if json.Exists() { if json.Exists() {
@ -57,6 +60,18 @@ func (i SMARTctlManagerCollector) Collect(ch chan<- prometheus.Metric) {
} }
} }
info.Collect() info.Collect()
i.mutex.Unlock()
}
func (i *SMARTctlManagerCollector) RescanForDevices() {
for {
time.Sleep(*smartctlRescanInterval)
level.Info(i.logger).Log("msg", "Rescanning for devices")
devices := scanDevices(i.logger)
i.mutex.Lock()
i.Devices = devices
i.mutex.Unlock()
}
} }
var ( var (
@ -66,6 +81,9 @@ var (
smartctlInterval = kingpin.Flag("smartctl.interval", smartctlInterval = kingpin.Flag("smartctl.interval",
"The interval between smartctl polls", "The interval between smartctl polls",
).Default("60s").Duration() ).Default("60s").Duration()
smartctlRescanInterval = kingpin.Flag("smartctl.rescan",
"The interval between rescanning for new/disappeared devices. If the interval is smaller than 1s no rescanning takes place. If any devices are configured with smartctl.device also no rescanning takes place.",
).Default("10m").Duration()
smartctlDevices = kingpin.Flag("smartctl.device", smartctlDevices = kingpin.Flag("smartctl.device",
"The device to monitor (repeatable)", "The device to monitor (repeatable)",
).Strings() ).Strings()
@ -135,13 +153,19 @@ func main() {
logger: logger, logger: logger,
} }
if *smartctlRescanInterval >= 1*time.Second && len(*smartctlDevices) == 0 {
level.Info(logger).Log("msg", "Start background scan process")
level.Info(logger).Log("msg", "Rescanning for devices every", "rescanInterval", *smartctlRescanInterval)
go collector.RescanForDevices()
}
reg := prometheus.NewPedanticRegistry() reg := prometheus.NewPedanticRegistry()
reg.MustRegister( reg.MustRegister(
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
collectors.NewGoCollector(), collectors.NewGoCollector(),
) )
prometheus.WrapRegistererWithPrefix("", reg).MustRegister(collector) prometheus.WrapRegistererWithPrefix("", reg).MustRegister(&collector)
http.Handle(*metricsPath, promhttp.HandlerFor(reg, promhttp.HandlerOpts{})) http.Handle(*metricsPath, promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))