107 lines
2.5 KiB
Go
107 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"github.com/prometheus-community/pro-bing"
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
Waybar = flag.Bool("waybar", false, "output waybar json format")
|
|
PingCount = flag.Int("count", 3, "how many pings to average")
|
|
PingInterval = flag.Int("i", 5, "ping interval")
|
|
PingWarningLimit = flag.Int("warn", 50, "ping warning limit")
|
|
PingCritLimit = flag.Int("crit", 100, "ping critical limit")
|
|
PacketLossWarnLimit = flag.Int("pwarn", 10, "package-loss warning limit")
|
|
PacketLossCritLimit = flag.Int("pcrit", 25, "package-loss critical limit")
|
|
Host = flag.String("host", "google.com", "host to ping")
|
|
)
|
|
|
|
type WaybarOut struct {
|
|
Class string `json:"class"`
|
|
Text string `json:"text"`
|
|
}
|
|
|
|
func formatLine(stats *probing.Statistics) {
|
|
if stats.PacketLoss >= 100.0 {
|
|
// fontawesome/forkawesome doesn't have the fitting icon...
|
|
// so this is the utf-8 icon/emoji
|
|
fmt.Println("%{F#ff7070}🚫")
|
|
return
|
|
}
|
|
|
|
var rttColor string
|
|
var packetColor string
|
|
|
|
switch {
|
|
case stats.AvgRtt.Milliseconds() < 50:
|
|
rttColor = "%{F-}"
|
|
case stats.AvgRtt.Milliseconds() < 100:
|
|
rttColor = "%{F#e87205}"
|
|
default:
|
|
rttColor = "%{F#d60606}"
|
|
}
|
|
|
|
switch {
|
|
case stats.PacketLoss == 0:
|
|
packetColor = "%{F-}"
|
|
case stats.PacketLoss < 10:
|
|
packetColor = "%{F#f9dd04}"
|
|
case stats.PacketLoss < 25:
|
|
packetColor = "%{F#e87205}"
|
|
default:
|
|
packetColor = "%{F#d60606}"
|
|
}
|
|
|
|
fmt.Printf("%%{F-}\uE4E2 %s%dms %%{F-}\uF1B2 %s%d%%\n", rttColor, stats.AvgRtt.Milliseconds(), packetColor, int(math.Round(stats.PacketLoss)))
|
|
}
|
|
|
|
func formatLineWaybar(stats *probing.Statistics) {
|
|
res := new(WaybarOut)
|
|
|
|
res.Text = fmt.Sprintf("\uE4E2 %dms \uF1B2 %d%%", int(stats.AvgRtt.Milliseconds()), int(math.Round(stats.PacketLoss)))
|
|
res.Class = "good"
|
|
|
|
switch {
|
|
case int(math.Round(stats.PacketLoss)) >= *PacketLossWarnLimit || int(stats.AvgRtt.Milliseconds()) >= *PingWarningLimit:
|
|
res.Class = "warning"
|
|
case int(math.Round(stats.PacketLoss)) >= *PacketLossCritLimit || int(stats.AvgRtt.Milliseconds()) >= *PingCritLimit:
|
|
res.Class = "critical"
|
|
}
|
|
|
|
jOut, err := json.Marshal(res)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
fmt.Println(string(jOut))
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
for {
|
|
pinger, err := probing.NewPinger(*Host)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
goto sleep
|
|
}
|
|
pinger.Count = *PingCount
|
|
if *Waybar {
|
|
pinger.OnFinish = formatLineWaybar
|
|
} else {
|
|
pinger.OnFinish = formatLine
|
|
}
|
|
|
|
if pinger.Run() != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
sleep:
|
|
time.Sleep(time.Duration(*PingInterval) * time.Second)
|
|
}
|
|
}
|