diff options
Diffstat (limited to '')
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/ping/prober.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/ping/prober.go b/src/go/collectors/go.d.plugin/modules/ping/prober.go new file mode 100644 index 000000000..e0d9925b4 --- /dev/null +++ b/src/go/collectors/go.d.plugin/modules/ping/prober.go @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package ping + +import ( + "errors" + "fmt" + "net" + "time" + + "github.com/netdata/netdata/go/go.d.plugin/logger" + + probing "github.com/prometheus-community/pro-bing" +) + +func newPingProber(conf pingProberConfig, log *logger.Logger) prober { + var source string + if conf.iface != "" { + if addr, err := getInterfaceIPAddress(conf.iface); err != nil { + log.Warningf("error getting interface '%s' IP address: %v", conf.iface, err) + } else { + log.Infof("interface '%s' IP address '%s', will use it as the source", conf.iface, addr) + source = addr + } + } + + return &pingProber{ + network: conf.network, + privileged: conf.privileged, + packets: conf.packets, + source: source, + interval: conf.interval, + deadline: conf.deadline, + Logger: log, + } +} + +type pingProberConfig struct { + network string + privileged bool + packets int + iface string + interval time.Duration + deadline time.Duration +} + +type pingProber struct { + *logger.Logger + + network string + privileged bool + packets int + source string + interval time.Duration + deadline time.Duration +} + +func (p *pingProber) ping(host string) (*probing.Statistics, error) { + pr := probing.New(host) + + pr.SetNetwork(p.network) + + if err := pr.Resolve(); err != nil { + return nil, fmt.Errorf("DNS lookup '%s' : %v", host, err) + } + + pr.Source = p.source + pr.RecordRtts = false + pr.Interval = p.interval + pr.Count = p.packets + pr.Timeout = p.deadline + pr.SetPrivileged(p.privileged) + pr.SetLogger(nil) + + if err := pr.Run(); err != nil { + return nil, fmt.Errorf("pinging host '%s' (ip %s): %v", pr.Addr(), pr.IPAddr(), err) + } + + stats := pr.Statistics() + + p.Debugf("ping stats for host '%s' (ip '%s'): %+v", pr.Addr(), pr.IPAddr(), stats) + + return stats, nil +} + +func getInterfaceIPAddress(ifaceName string) (ipaddr string, err error) { + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + return "", err + } + + addresses, err := iface.Addrs() + if err != nil { + return "", err + } + + // FIXME: add IPv6 support + var v4Addr string + for _, addr := range addresses { + if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.To4() != nil { + v4Addr = ipnet.IP.To4().String() + break + } + } + + if v4Addr == "" { + return "", errors.New("ipv4 addresses not found") + } + + return v4Addr, nil +} |