Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
feat: add ping collector
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyam8 committed Oct 28, 2022
1 parent 71b5b6a commit 3ce5e65
Show file tree
Hide file tree
Showing 13 changed files with 720 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Go.d.plugin is shipped with Netdata.
| [phpfpm](https://github.com/netdata/go.d.plugin/tree/master/modules/phpfpm) | PHP-FPM |
| [pihole](https://github.com/netdata/go.d.plugin/tree/master/modules/pihole) | Pi-hole |
| [pika](https://github.com/netdata/go.d.plugin/tree/master/modules/pika) | Pika |
| [ping](https://github.com/netdata/go.d.plugin/tree/master/modules/ping) | Any network host |
| [prometheus](https://github.com/netdata/go.d.plugin/tree/master/modules/prometheus) | Any Prometheus Endpoint |
| [portcheck](https://github.com/netdata/go.d.plugin/tree/master/modules/portcheck) | Any TCP Endpoint |
| [postgres](https://github.com/netdata/go.d.plugin/tree/master/modules/postgres) | PostgreSQL |
Expand Down
1 change: 1 addition & 0 deletions config/go.d.conf
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ modules:
# nvidia_smi: no
# openvpn: no
# openvpn_status_log: yes
# ping: yes
# pgbouncer: yes
# phpdaemon: yes
# phpfpm: yes
Expand Down
105 changes: 105 additions & 0 deletions config/go.d/ping.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# netdata go.d.plugin configuration for ping
#
# This file is in YAML format. Generally the format is:
#
# name: value
#
# There are 2 sections:
# - GLOBAL
# - JOBS
#
#
# [ GLOBAL ]
# These variables set the defaults for all JOBs, however each JOB may define its own, overriding the defaults.
#
# The GLOBAL section format:
# param1: value1
# param2: value2
#
# Currently supported global parameters:
# - update_every
# Data collection frequency in seconds. Default: 1.
#
# - autodetection_retry
# Re-check interval in seconds. Attempts to start the job are made once every interval.
# Zero means not to schedule re-check. Default: 0.
#
# - priority
# Priority is the relative priority of the charts as rendered on the web page,
# lower numbers make the charts appear before the ones with higher numbers. Default: 70000.
#
#
# [ JOBS ]
# JOBS allow you to collect values from multiple sources.
# Each source will have its own set of charts.
#
# IMPORTANT:
# - Parameter 'name' is mandatory.
# - Jobs with the same name are mutually exclusive. Only one of them will be allowed running at any time.
#
# This allows autodetection to try several alternatives and pick the one that works.
# Any number of jobs is supported.
#
# The JOBS section format:
#
# jobs:
# - name: job1
# param1: value1
# param2: value2
#
# - name: job2
# param1: value1
# param2: value2
#
# - name: job2
# param1: value1
#
#
# [ List of JOB specific parameters ]:
# - hosts
# A list of hosts to send ping packets to.
# Syntax:
# hosts:
# - 192.0.2.0
# - 192.0.2.1
# - example.com
#
# - privileged
# Sets the type of ping packets.
# "no" means send an "unprivileged" UDP ping. "yes" means send a "privileged" raw ICMP ping.
# Syntax:
# privileged: yes/no
#
# - packets
# Number of ping packets to send.
# Syntax:
# packets: 3
#
# - interval
# Time to wait between sending ping packets.
# Syntax:
# interval: 100ms
#
#
# [ JOB defaults ]:
# privileged: yes
# packets: 5
# interval: 200ms
#
#
# [ JOB mandatory parameters ]:
# No parameters
#
# ------------------------------------------------MODULE-CONFIGURATION--------------------------------------------------

# update_every: 5
# autodetection_retry: 0
# priority: 70000

## Uncomment the following lines to create a data collection config:

# jobs:
# - name: example
# hosts:
# - 192.0.2.0
# - 192.0.2.1
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ require (
github.com/mattn/go-xmlrpc v0.0.3
github.com/miekg/dns v1.1.50
github.com/mitchellh/go-homedir v1.1.0
github.com/prometheus-community/pro-bing v0.1.0
github.com/prometheus/prometheus v0.36.2
github.com/stretchr/testify v1.8.1
github.com/tomasen/fcgi_client v0.0.0-20180423082037-2bb3d819fd19
Expand Down Expand Up @@ -85,7 +86,7 @@ require (
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/grafana/regexp v0.0.0-20220304095617-2e8d9baf4ac2 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,9 @@ github.com/google/uuid v0.0.0-20170306145142-6a5e28554805/go.mod h1:TIyPZe4Mgqvf
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s=
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
Expand Down Expand Up @@ -810,6 +811,8 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus-community/pro-bing v0.1.0 h1:zjzLGhfNPP0bP1OlzGB+SJcguOViw7df12LPg2vUJh8=
github.com/prometheus-community/pro-bing v0.1.0/go.mod h1:BpWlHurD9flHtzq8wrh8QGWYz9ka9z9ZJAyOel8ej58=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
Expand Down
1 change: 1 addition & 0 deletions modules/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import (
_ "github.com/netdata/go.d.plugin/modules/phpfpm"
_ "github.com/netdata/go.d.plugin/modules/pihole"
_ "github.com/netdata/go.d.plugin/modules/pika"
_ "github.com/netdata/go.d.plugin/modules/ping"
_ "github.com/netdata/go.d.plugin/modules/portcheck"
_ "github.com/netdata/go.d.plugin/modules/postgres"
_ "github.com/netdata/go.d.plugin/modules/powerdns"
Expand Down
89 changes: 89 additions & 0 deletions modules/ping/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!--
title: "Pi-hole monitoring with Netdata"
description: "Monitor round-trip time and packet loss to network hosts with zero configuration, per-second metric granularity, and interactive visualizations."
custom_edit_url: https://github.com/netdata/go.d.plugin/edit/master/modules/ping/README.md
sidebar_label: "Ping"
-->

# Ping monitoring with Netdata

This module measures round-tripe time and packet loss by sending ping messages to network hosts.

## Requirements

There are two operational modes:

- privileged (send UDP ping, default). Requires
CAP_NET_RAW [capability](https://man7.org/linux/man-pages/man7/capabilities.7.html) or root privileges:
> **Note**: set automatically during Netdata installation.
```bash
sudo setcap CAP_NET_RAW=eip <INSTALL_PREFIX>/usr/libexec/netdata/plugins.d/go.d.plugin
```

- unprivileged (send raw ICMP ping, Linux only).
Requires configuring [ping_group_range](https://www.man7.org/linux/man-pages/man7/icmp.7.html):

```bash
sudo sysctl -w net.ipv4.ping_group_range="0 2147483647"
```
To persist the change add `net.ipv4.ping_group_range="0 2147483647"` to `/etc/sysctl.conf` and
execute `sudo sysctl -p`.

The mode can be changed in the module [configuration file](#Configuration).

## Metrics

All metrics have "ping." prefix.

| Metric | Scope | Dimensions | Units |
|------------------|:-----:|:--------------:|:----------:|
| host_rtt | host | min, max, avg | seconds |
| host_packet_loss | host | loss | percentage |
| host_packets | host | received, sent | packets |

## Configuration

Edit the `go.d/ping.conf` configuration file using `edit-config` from the
Netdata [config directory](https://learn.netdata.cloud/docs/configure/nodes), which is typically at `/etc/netdata`.

```bash
cd /etc/netdata # Replace this path with your Netdata config directory
sudo ./edit-config go.d/ping.conf
```

Here is an example configuration:

```yaml
jobs:
- name: example
hosts:
- 192.0.2.0
- 192.0.2.1
- example.com
packets: 5 # number of ping packets to send.
interval: 200ms # time to wait between sending ping packets.
```
For all available options please see
module [configuration file](https://github.com/netdata/go.d.plugin/blob/master/config/go.d/ping.conf).
## Troubleshooting
To troubleshoot issues with the `ping` collector, run the `go.d.plugin` with the debug option enabled. The output
should give you clues as to why the collector isn't working.

First, navigate to your plugins' directory, usually at `/usr/libexec/netdata/plugins.d/`. If that's not the case on your
system, open `netdata.conf` and look for the setting `plugins directory`. Once you're in the plugin's directory, switch
to the `netdata` user.

```bash
cd /usr/libexec/netdata/plugins.d/
sudo -u netdata -s
```

You can now run the `go.d.plugin` to debug the collector:

```bash
./go.d.plugin -d -m ping
```
86 changes: 86 additions & 0 deletions modules/ping/charts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-3.0-or-later

package ping

import (
"fmt"
"strings"

"github.com/netdata/go.d.plugin/agent/module"
)

const (
prioHostRTTLatency = module.Priority + iota
prioHostPingPacketLoss
prioHostPingPackets
)

var hostChartsTmpl = module.Charts{
hostRTTChartTmpl.Copy(),
hostPacketLossChartTmpl.Copy(),
hostPacketsChartTmpl.Copy(),
}

var hostRTTChartTmpl = module.Chart{
ID: "ping_host_%s_rtt",
Title: "Ping round-trip time",
Units: "seconds",
Fam: "latency",
Ctx: "ping.host_rtt",
Priority: prioHostRTTLatency,
Type: module.Area,
Dims: module.Dims{
{ID: "host_%s_min_rtt", Name: "min", Div: 1e6},
{ID: "host_%s_max_rtt", Name: "max", Div: 1e6},
{ID: "host_%s_avg_rtt", Name: "avg", Div: 1e6},
},
}

var hostPacketLossChartTmpl = module.Chart{
ID: "host_host_%s_packet_loss",
Title: "Ping packet loss",
Units: "percentage",
Fam: "packet loss",
Ctx: "ping.host_packet_loss",
Priority: prioHostPingPacketLoss,
Dims: module.Dims{
{ID: "host_%s_packet_loss", Name: "loss", Div: 1000},
},
}

var hostPacketsChartTmpl = module.Chart{
ID: "host_host_%s_packets",
Title: "Ping packets transferred",
Units: "packets",
Fam: "packets",
Ctx: "ping.host_packets",
Priority: prioHostPingPackets,
Dims: module.Dims{
{ID: "host_%s_packets_recv", Name: "received"},
{ID: "host_%s_packets_sent", Name: "sent"},
},
}

func newHostCharts(host string) *module.Charts {
charts := hostChartsTmpl.Copy()

for _, chart := range *charts {
chart.ID = fmt.Sprintf(chart.ID, strings.ReplaceAll(host, ".", "_"))
chart.Labels = []module.Label{
{Key: "host", Value: host},
}
for _, dim := range chart.Dims {
dim.ID = fmt.Sprintf(dim.ID, host)
}
}

return charts
}

func (p *Ping) addHostCharts(host string) {
charts := newHostCharts(host)

if err := p.Charts().Add(*charts...); err != nil {
p.Warning(err)
}
}
49 changes: 49 additions & 0 deletions modules/ping/collect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-3.0-or-later

package ping

import (
"fmt"
"sync"
)

func (p *Ping) collect() (map[string]int64, error) {
mu := &sync.Mutex{}
mx := make(map[string]int64)
var wg sync.WaitGroup

for _, v := range p.Hosts {
wg.Add(1)
go func(v string) { defer wg.Done(); p.pingHost(v, mx, mu) }(v)
}
wg.Wait()

return mx, nil
}

func (p *Ping) pingHost(host string, mx map[string]int64, mu *sync.Mutex) {
stats, err := p.prober.ping(host)
if err != nil {
p.Error(err)
return
}

mu.Lock()
defer mu.Unlock()

if !p.hosts[host] {
p.hosts[host] = true
p.addHostCharts(host)
}

px := fmt.Sprintf("host_%s_", host)
if stats.PacketsRecv != 0 {
mx[px+"min_rtt"] = stats.MinRtt.Microseconds()
mx[px+"max_rtt"] = stats.MaxRtt.Microseconds()
mx[px+"avg_rtt"] = stats.AvgRtt.Microseconds()
mx[px+"std_dev_rtt"] = stats.StdDevRtt.Microseconds()
}
mx[px+"packets_recv"] = int64(stats.PacketsRecv)
mx[px+"packets_sent"] = int64(stats.PacketsSent)
mx[px+"packet_loss"] = int64(stats.PacketLoss * 1000)
}
Loading

0 comments on commit 3ce5e65

Please sign in to comment.