Files
prom-ping/exporter.go
groot dc4fd47c5e
All checks were successful
build-binaries / build (, arm, 7, linux) (push) Has been skipped
build-binaries / build (, arm64, linux) (push) Has been skipped
build-binaries / build (.exe, amd64, windows) (push) Has been skipped
build-binaries / build (, amd64, linux) (push) Has been skipped
build-binaries / release (push) Has been skipped
build-binaries / publish-agent (push) Has been skipped
release-tag / release-image (push) Successful in 2m33s
exporter.go aktualisiert
2025-10-31 08:11:51 +00:00

158 lines
3.1 KiB
Go

package main
import (
"log"
"sync"
"time"
"github.com/prometheus/client_golang/prometheus"
)
type TargetRunner struct {
name string
host string
config TargetSettings
history []float64
hidx int
mu sync.Mutex
}
func NewTargetRunner(name, host string, cfg TargetSettings) *TargetRunner {
return &TargetRunner{
name: name,
host: host,
config: cfg,
history: make([]float64, cfg.HistorySize),
}
}
var (
pingUp = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ping_up",
Help: "Whether the last ping was successful (1) or not (0)",
},
[]string{"target"},
)
pingRTT = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ping_rtt_seconds",
Help: "Last ping round trip time in seconds",
},
[]string{"target"},
)
pingRTTMs = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ping_rtt_milliseconds",
Help: "Last ping round trip time in milliseconds",
},
[]string{"target"},
)
pingRTTAvg = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ping_rtt_seconds_avg",
Help: "Average ping round trip time in seconds (over history)",
},
[]string{"target"},
)
pingRTTAvgMs = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ping_rtt_milliseconds_avg",
Help: "Average ping round trip time in milliseconds (over history)",
},
[]string{"target"},
)
pingPacketsSent = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "ping_packets_sent_total",
Help: "Total number of ping packets sent",
},
[]string{"target"},
)
pingPacketsRecv = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "ping_packets_received_total",
Help: "Total number of ping packets received",
},
[]string{"target"},
)
)
func init() {
prometheus.MustRegister(
pingUp,
pingRTT,
pingRTTMs,
pingRTTAvg,
pingRTTAvgMs,
pingPacketsSent,
pingPacketsRecv,
)
}
func (t *TargetRunner) Run(stop <-chan struct{}) {
lbl := prometheus.Labels{"target": t.name}
ticker := time.NewTicker(t.config.Interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
pingPacketsSent.With(lbl).Inc()
res := doPing(t.host, PingOptions{
Timeout: t.config.Timeout,
Size: t.config.Size,
DisableIPv6: t.config.DisableIPv6,
DNSServer: t.config.DNSServer,
})
if res.Alive {
pingUp.With(lbl).Set(1)
pingPacketsRecv.With(lbl).Inc()
sec := res.RTT.Seconds()
pingRTT.With(lbl).Set(sec)
pingRTTMs.With(lbl).Set(sec * 1000)
avgSec := t.addToHistoryAndAvg(sec)
pingRTTAvg.With(lbl).Set(avgSec)
pingRTTAvgMs.With(lbl).Set(avgSec * 1000)
} else {
pingUp.With(lbl).Set(0)
pingRTT.With(lbl).Set(0)
pingRTTMs.With(lbl).Set(0)
log.Printf("ping to %s failed: %v", t.name, res.Err)
}
case <-stop:
return
}
}
}
func (t *TargetRunner) addToHistoryAndAvg(v float64) float64 {
t.mu.Lock()
defer t.mu.Unlock()
if len(t.history) == 0 {
return v
}
t.history[t.hidx] = v
t.hidx = (t.hidx + 1) % len(t.history)
var sum float64
var cnt int
for _, x := range t.history {
if x > 0 {
sum += x
cnt++
}
}
if cnt == 0 {
return 0
}
return sum / float64(cnt)
}