Files
rtt-polybar-waybar/ping-package.go
2023-04-14 22:35:09 +02:00

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)
}
}