Files
rtt-polybar-waybar/ping-package.go

108 lines
2.7 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")
)
//goland:noinspection ALL
const (
CritColor = "ff5050"
WarnColor = "ffbf00"
ResetColor = "{F-}"
)
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.Printf("%%{F#%s}🚫\n", CritColor)
return
}
rttColor := ResetColor
packetColor := ResetColor
switch {
case int(stats.AvgRtt.Milliseconds()) >= *PingWarningLimit:
rttColor = fmt.Sprintf("%%{F#%s}", WarnColor)
case int(stats.AvgRtt.Milliseconds()) >= *PingCritLimit:
rttColor = fmt.Sprintf("%%{F#%s}", CritColor)
}
switch {
case int(math.Round(stats.PacketLoss)) >= *PacketLossWarnLimit:
packetColor = fmt.Sprintf("%%{F#%s}", WarnColor)
case int(math.Round(stats.PacketLoss)) >= *PacketLossCritLimit:
packetColor = fmt.Sprintf("%%{F#%s}", CritColor)
}
fmt.Printf("%s\uE4E2 %dms %%%s\uF1B2 %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)
}
}