main.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // pinghealth takes hosts from the command line, pings each of them a number of times.
  2. //
  3. // timout, number of pings and retries can be configured with flags.
  4. //
  5. // ping construction is done by https://github.com/erikh/ping
  6. package main
  7. import (
  8. "flag"
  9. "net"
  10. "os"
  11. "sync"
  12. "time"
  13. "github.com/cryptix/go/backoff"
  14. "github.com/cryptix/go/logging"
  15. "github.com/erikh/ping"
  16. "github.com/sethgrid/multibar"
  17. )
  18. var (
  19. // flags
  20. cnt = flag.Int("c", 10, "how much pings to send to each host")
  21. retry = flag.Int("r", 10, "number of retries before aborting")
  22. timeout = flag.Duration("t", 100*time.Millisecond, "what timeout to use for each ping")
  23. // globals
  24. bars *multibar.BarContainer
  25. barMap map[string]func(int)
  26. log = logging.Logger("pinghealth")
  27. )
  28. func main() {
  29. flag.Parse()
  30. if len(flag.Args()) == 0 {
  31. log.Warning("No hosts to ping. quiting.")
  32. os.Exit(1)
  33. }
  34. // construct multibars
  35. var err error
  36. bars, err = multibar.New()
  37. logging.CheckFatal(err)
  38. // need to bars.MakeBar() before bars.Listen()...
  39. barMap = make(map[string]func(int))
  40. for _, h := range flag.Args() {
  41. barMap[h] = bars.MakeBar(*cnt, h)
  42. }
  43. bars.Println()
  44. go bars.Listen()
  45. // start the pingers
  46. var wg sync.WaitGroup
  47. wg.Add(len(flag.Args()))
  48. for _, h := range flag.Args() {
  49. go tryPings(&wg, h)
  50. }
  51. wg.Wait()
  52. }
  53. func tryPings(wg *sync.WaitGroup, host string) {
  54. var (
  55. err error
  56. attempt int
  57. ip *net.IPAddr
  58. )
  59. defer wg.Done()
  60. ip, err = net.ResolveIPAddr("ip6", host)
  61. if err != nil {
  62. ip, err = net.ResolveIPAddr("ip4", host)
  63. if err != nil {
  64. bars.Printf("%15s - ResolveIPAddr() failed", host)
  65. return
  66. }
  67. }
  68. for i := 0; i < *cnt; i++ {
  69. barMap[host](i)
  70. time.Sleep(500 * time.Millisecond)
  71. if attempt > *retry {
  72. bars.Printf("%15s %2d - attempts exceeded", ip, i)
  73. return
  74. }
  75. start := time.Now()
  76. err := ping.Pinger(ip, *timeout+backoff.Default.Duration(attempt))
  77. if err != nil { // retry
  78. attempt++
  79. i--
  80. bars.Printf("%15s %2d - %50s (attempt %d | took %v)",
  81. host,
  82. i,
  83. err,
  84. attempt,
  85. time.Since(start))
  86. continue
  87. }
  88. attempt = 0
  89. }
  90. barMap[host](*cnt)
  91. }