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), } } // Prometheus-Metrics 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"}, ) pingRTTAvg = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "ping_rtt_seconds_avg", Help: "Average ping round trip time in seconds (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, pingRTTAvg, 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) avg := t.addToHistoryAndAvg(sec) pingRTTAvg.With(lbl).Set(avg) } else { pingUp.With(lbl).Set(0) // RTT nicht ändern oder auf 0 setzen? pingRTT.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) }