package main import ( "encoding/json" "flag" "fmt" "github.com/prometheus-community/pro-bing" "math" "strconv" "time" ) var ( Waybar = flag.Bool("waybar", false, "output waybar json format") PingCount = flag.Int("count", 3, "how many pings to average") PingInterval = flag.Int("interval", 5, "ping interval") PingWarningLimit = flag.Int("warning", 50, "ping warn limit") PingCritLimit = flag.Int("crit", 100, "ping crit limit") PacketLossWarnLimit = flag.Int("pwarn", 10, "package loss warn limit") PacketLossCritLimit = flag.Int("pcrit", 25, "package loss crit limit") Host = flag.String("host", "google.com", "host to ping") ) type WaybarOut struct { Class string `json:"class"` PackageLoss string `json:"package_loss"` Ping string `json:"ping"` } 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("%s%dms %%{F-}| %s%d%%\n", rttColor, stats.AvgRtt.Milliseconds(), packetColor, int(math.Round(stats.PacketLoss))) } func formatLineWaybar(stats *probing.Statistics) { res := new(WaybarOut) res.PackageLoss = strconv.Itoa(int(math.Round(stats.PacketLoss))) res.Ping = strconv.Itoa(int(stats.AvgRtt.Milliseconds())) 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 { time.Sleep(time.Duration(*PingInterval) * time.Second) pinger, err := probing.NewPinger(*Host) if err != nil { fmt.Println(err) continue } pinger.Count = *PingCount if *Waybar { pinger.OnFinish = formatLineWaybar } else { pinger.OnFinish = formatLine } if pinger.Run() != nil { fmt.Println(err) continue } } }