I've used your example code to add 593 of our hosts to the monitor tool, since it basically should do what I need (I need a statistics every 60 seconds which I would want to log away).
It is certainly true that several of the hosts are currently "down" because behind Firewalls and I'm not testing in the same zone, but I'd expect it to report the loss at the "right" hosts ... and all 593 instead of just 255 ofc ;-).
package slaping
import (
"net"
"os"
"time"
"log"
"os/signal"
"syscall"
"github.com/digineo/go-ping"
"github.com/digineo/go-ping/monitor"
)
var (
pingInterval = 5 * time.Second
pingTimeout = 4 * time.Second
reportInterval = 60 * time.Second
size uint = 56
pinger *ping.Pinger
targets []string
)
func (p *SLAPing) PingHosts() {
// setup, we need to populate cache once before we start to actually have host and maint info
CMDBHosts, err := p.CMDB.GetSLAHosts()
if err != nil {
log.Println(err)
}
// Bind to sockets
if pi, err := ping.New("0.0.0.0", "::"); err != nil {
log.Printf("Unable to bind: %s\nRunning as root?\n", err)
os.Exit(2)
} else {
pinger = pi
}
pinger.SetPayloadSize(uint16(size))
defer pinger.Close()
// Create monitor
monitor := monitor.New(pinger, pingInterval, pingTimeout)
defer monitor.Stop()
// Add targets
targets := CMDBHosts
validtargets := 0
for i, target := range CMDBHosts {
ipAddr, err := net.ResolveIPAddr("", target)
if err != nil {
// currently irrelevant
continue
}
err = monitor.AddTarget(string([]byte{byte(i)}), *ipAddr)
//err = monitor.AddTargetDelayed(string([]byte{byte(i)}), *ipAddr, 10*time.Millisecond*time.Duration(i))
if err != nil {
// currently irrelevant
continue
}
validtargets = validtargets + 1
}
log.Printf("Total targets: %d, Valid targets: %d, Errors: %d\n", len(targets), validtargets, len(targets)-validtargets)
// Start report routine
ticker := time.NewTicker(reportInterval)
defer ticker.Stop()
go func() {
for range ticker.C {
for i, metrics := range monitor.ExportAndClear() {
log.Printf("%s: %+v\n", targets[[]byte(i)[0]], *metrics)
}
}
}()
// Handle SIGINT and SIGTERM.
// in other words we wait here until interrupted and let the ticker tick
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
log.Println("received", <-ch)
}