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("%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.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 { 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 } } }