mirror of
https://github.com/dennypage/dpinger.git
synced 2024-05-19 06:50:01 +00:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
664f5c7aa6 | ||
|
|
0e963753e1 | ||
|
|
e3cb41889e | ||
|
|
9c31ea4380 | ||
|
|
fff9b65eb5 | ||
|
|
47f1a778b9 | ||
|
|
ce7d88bddf | ||
|
|
67b8ba1f6d | ||
|
|
c845c582b4 | ||
|
|
fbc7e8f87f | ||
|
|
efc17c7204 | ||
|
|
bc00923f62 | ||
|
|
bf18a6e2a8 | ||
|
|
cee7ac9da0 | ||
|
|
2b032751e5 | ||
|
|
84ee15b155 | ||
|
|
e10c51ad95 | ||
|
|
579ae3d66b | ||
|
|
64e644e7be | ||
|
|
a18d82ab6e | ||
|
|
34b0bb924e | ||
|
|
4173834bbe | ||
|
|
2a8eaa0c8f | ||
|
|
edb883498d | ||
|
|
c276feb339 | ||
|
|
ef21655e77 | ||
|
|
2d2d21892a | ||
|
|
a24c0cd0d0 | ||
|
|
fdbd4a1d96 | ||
|
|
6796fa0752 | ||
|
|
24022ac098 | ||
|
|
42c84e965e | ||
|
|
f94f6dcd47 | ||
|
|
99208a60fe | ||
|
|
eb67d76de0 | ||
|
|
0b68c438f2 | ||
|
|
daac746074 | ||
|
|
5348af36c6 | ||
|
|
b0fc95f618 | ||
|
|
e9ffd0b43e | ||
|
|
9e8968adce | ||
|
|
a8b44bedac | ||
|
|
1d34caccbd | ||
|
|
9c5bac8658 | ||
|
|
3a19391cee | ||
|
|
570ade420a | ||
|
|
3825066db9 | ||
|
|
f06b3c8f36 | ||
|
|
4a57f2584c | ||
|
|
afbde05bcb | ||
|
|
85d345f47f | ||
|
|
e0a0ae14f9 | ||
|
|
87cd4b6e3b | ||
|
|
919fad77a2 | ||
|
|
2e0430edea | ||
|
|
31432284dc | ||
|
|
e1d00b4210 | ||
|
|
1ec615486b | ||
|
|
6789e90a38 | ||
|
|
1b2e8e784b | ||
|
|
00229f717d | ||
|
|
4b82af813b | ||
|
|
feb01fa2d3 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
/dpinger
|
||||
/dpinger.debug
|
||||
/dpinger.full
|
||||
/dpinger.o
|
||||
/.*.swp
|
||||
|
||||
13
LICENSE
13
LICENSE
@@ -1,15 +1,15 @@
|
||||
Copyright (c) 2015, Denny Page
|
||||
Copyright (c) 2015-2022, Denny Page
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
@@ -21,4 +21,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
12
Makefile
12
Makefile
@@ -1,9 +1,9 @@
|
||||
PROG= dpinger
|
||||
MAN=
|
||||
CC=gcc
|
||||
WARNINGS=-Wall -Wextra -Wformat=2 -Wno-unused-result
|
||||
|
||||
BINDIR= ${PREFIX}/bin
|
||||
WARNS= 6
|
||||
#CC=clang
|
||||
#WARNINGS=-Weverything -Wno-unsafe-buffer-usage -Wno-cast-function-type-strict -Wno-padded -Wno-disabled-macro-expansion -Wno-reserved-id-macro
|
||||
|
||||
LDADD= -lpthread
|
||||
CFLAGS=${WARNINGS} -pthread -g -O2
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
all: dpinger
|
||||
|
||||
9
Makefile.freebsd
Normal file
9
Makefile.freebsd
Normal file
@@ -0,0 +1,9 @@
|
||||
PROG= dpinger
|
||||
MAN=
|
||||
|
||||
BINDIR= ${PREFIX}/bin
|
||||
WARNS= 6
|
||||
|
||||
LDADD= -lpthread
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
13
NOTES.md
Normal file
13
NOTES.md
Normal file
@@ -0,0 +1,13 @@
|
||||
<b>Loss accuracy</b>
|
||||
|
||||
In general, dpinger works a bit differently than other latency monitors. Rather than a "probe" that fires off and processes a handful of echo request/replies all at once, dpinger maintains a rolling array of echo requests spaced on the send interval. In other words, instead of waking up every second and sending 4 echo requests at once, dpinger sends an echo request every 250 milliseconds. When dpinger receives an echo reply, the time difference between the request packet and reply packet (latency) is recorded. There is nothing that times out an echo request/reply and records it as permanently lost.
|
||||
|
||||
When the alert check is made, or a report is generated, dpinger goes through the array and examines each echo request. If a reply has been received, it is used as part of the overall latency calculation. If a reply has not yet been received, the amount of time since the request is compared against the loss interval. If it is greater than the loss interval, the request/reply is counted as lost in the current report. However the concept of the request/reply being lost is not a permanent decision. In subsequent reports, if a the missing reply has been received, its latency will be used instead of being counted as lost.
|
||||
|
||||
It's important to keep in mind that latency and loss are reported as averages across the entire request set. The default time period for dpinger is 60 seconds, with an echo request being sent every 500 milliseconds. This means that the latency and loss will be reported as averages across 116-120 samples. The alert check runs every second by default. So each time, the 4 oldest entries in the set have been replaced by the 4 newest ones.
|
||||
|
||||
Note that if you want accurate loss reporting, it is important that the number of samples be sufficient. In order to achieve 1% loss resolution, you have need more than 100 samples in the set. The calculation for loss resolution is:
|
||||
|
||||
100 / ((time_period - loss_interval) / send_interval)
|
||||
|
||||
The default settings for dpinger report loss with an accuracy of 0.87%.
|
||||
25
README.md
25
README.md
@@ -1,9 +1,26 @@
|
||||
# dpinger
|
||||
|
||||
dpinger is a daemon for continous monitoring of latency and loss on a network connection. It is
|
||||
dpinger is a daemon for continuous monitoring of latency and loss on a network connection. It is
|
||||
intended for use by firewalls to monitor link health, as well as for providing information to
|
||||
various monitoring systems such as Cacti, Nagios, Zabbix, etc.
|
||||
|
||||
The output of dpinger can either be file or socket based, and consists of three numbers:
|
||||
|
||||
<Average Latency in μs> <Standard Deviation in μs> <Percentage of Loss>
|
||||
|
||||
dpinger also provides for invocation of a command based upon threshold values
|
||||
for Average Latency or Percentage of Loss. Arguments to the command are:
|
||||
|
||||
<Target IP> <Alarm on/off> <Average Latency> <Standard Deviation> <Percentage of Loss>
|
||||
|
||||
In addition to command invocation, dpinger can also log alerts via syslog.
|
||||
|
||||
If several instances of dpinger are being used to monitor different targets, or the same target
|
||||
with different source addresses, etc., an Identifier can be added to the output to identify
|
||||
which instance of dpinger is the source. This is particularly useful with syslog.
|
||||
|
||||
<br>
|
||||
|
||||
Usage examples:
|
||||
|
||||
dpinger -t 300s -r 60s 192.168.0.1 >> /tmp/dpinger.out
|
||||
@@ -38,3 +55,9 @@ Produce a report every 60 seconds and append it to /tmp/dpinger.out.
|
||||
Monitor IP address fe80::1 for latency and loss. Send echo requests every 200 milliseconds.
|
||||
Make current status available on demand via a Unix domain socket /tmp/igb1.status. Record
|
||||
process id in /run/dpinger.
|
||||
|
||||
dpinger -S -i Comcast -s 5s -t 600s -r 0 -L 10% -p /run/dpinger 8.8.8.8
|
||||
|
||||
Monitor IP address 8.8.8.8 for latency and loss. Send echo requests every five seconds and
|
||||
average results over 10 minutes. Log alerts via syslog including identifier string "Comcast"
|
||||
if average loss exceeds 10 percent. Record process id in /run/dpinger.
|
||||
|
||||
19
influx/README.md
Normal file
19
influx/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
Examples for dpinger logging/monitoring with InfluxDB and Grafana
|
||||
|
||||
<br>
|
||||
|
||||
Files:
|
||||
|
||||
dpinger_influx_logger
|
||||
|
||||
Python script for logging dpinger data in InfluxDB
|
||||
|
||||
|
||||
dpinger_start.sh
|
||||
|
||||
Sample start script for dpinger influx logging
|
||||
|
||||
|
||||
dpinger_grafana_dashboard.json
|
||||
|
||||
Example Grafana dashboard for monitoring dpinger data
|
||||
456
influx/dpinger_grafana_dashboard.json
Normal file
456
influx/dpinger_grafana_dashboard.json
Normal file
@@ -0,0 +1,456 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "datasource",
|
||||
"uid": "grafana"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": 3,
|
||||
"iteration": 1652309379625,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "$source"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "never",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "ms"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "loss"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "unit",
|
||||
"value": "percent"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "loss"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "#e00000",
|
||||
"mode": "fixed"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "custom.fillOpacity",
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"id": "custom.lineWidth",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "unit",
|
||||
"value": "percent"
|
||||
},
|
||||
{
|
||||
"id": "max",
|
||||
"value": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 19,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [
|
||||
"mean",
|
||||
"lastNotNull",
|
||||
"max",
|
||||
"min"
|
||||
],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "multi",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "8.3.5",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "latency",
|
||||
"groupBy": [
|
||||
{
|
||||
"params": [
|
||||
"$intervals"
|
||||
],
|
||||
"type": "time"
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
"null"
|
||||
],
|
||||
"type": "fill"
|
||||
}
|
||||
],
|
||||
"measurement": "dpinger",
|
||||
"orderByTime": "ASC",
|
||||
"policy": "default",
|
||||
"query": "SELECT mean(\"latency\") FROM \"wan\" WHERE $timeFilter GROUP BY time($__interval) fill(null)",
|
||||
"queryType": "randomWalk",
|
||||
"rawQuery": false,
|
||||
"refId": "A",
|
||||
"resultFormat": "time_series",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"latency"
|
||||
],
|
||||
"type": "field"
|
||||
},
|
||||
{
|
||||
"params": [],
|
||||
"type": "mean"
|
||||
}
|
||||
]
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"key": "name",
|
||||
"operator": "=~",
|
||||
"value": "/^$name$/"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"alias": "stddev",
|
||||
"groupBy": [
|
||||
{
|
||||
"params": [
|
||||
"$intervals"
|
||||
],
|
||||
"type": "time"
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
"null"
|
||||
],
|
||||
"type": "fill"
|
||||
}
|
||||
],
|
||||
"measurement": "dpinger",
|
||||
"orderByTime": "ASC",
|
||||
"policy": "default",
|
||||
"queryType": "randomWalk",
|
||||
"refId": "B",
|
||||
"resultFormat": "time_series",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"stddev"
|
||||
],
|
||||
"type": "field"
|
||||
},
|
||||
{
|
||||
"params": [],
|
||||
"type": "mean"
|
||||
}
|
||||
]
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"key": "name",
|
||||
"operator": "=~",
|
||||
"value": "/^$name$/"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"alias": "loss",
|
||||
"groupBy": [
|
||||
{
|
||||
"params": [
|
||||
"$intervals"
|
||||
],
|
||||
"type": "time"
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
"null"
|
||||
],
|
||||
"type": "fill"
|
||||
}
|
||||
],
|
||||
"measurement": "dpinger",
|
||||
"orderByTime": "ASC",
|
||||
"policy": "default",
|
||||
"queryType": "randomWalk",
|
||||
"refId": "C",
|
||||
"resultFormat": "time_series",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"loss"
|
||||
],
|
||||
"type": "field"
|
||||
},
|
||||
{
|
||||
"params": [],
|
||||
"type": "mean"
|
||||
}
|
||||
]
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"key": "name",
|
||||
"operator": "=~",
|
||||
"value": "/^$name$/"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "$name - ${intervals} intervals",
|
||||
"transformations": [],
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "1m",
|
||||
"schemaVersion": 36,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {
|
||||
"selected": false,
|
||||
"text": "dpinger",
|
||||
"value": "dpinger"
|
||||
},
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Source",
|
||||
"multi": false,
|
||||
"name": "source",
|
||||
"options": [],
|
||||
"query": "influxdb",
|
||||
"queryValue": "",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"type": "datasource"
|
||||
},
|
||||
{
|
||||
"current": {
|
||||
"selected": false,
|
||||
"text": "wan",
|
||||
"value": "wan"
|
||||
},
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "$source"
|
||||
},
|
||||
"definition": "SHOW TAG VALUES WITH KEY = \"name\"",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Name",
|
||||
"multi": false,
|
||||
"name": "name",
|
||||
"options": [],
|
||||
"query": "SHOW TAG VALUES WITH KEY = \"name\"",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 0,
|
||||
"tagValuesQuery": "",
|
||||
"tagsQuery": "",
|
||||
"type": "query",
|
||||
"useTags": false
|
||||
},
|
||||
{
|
||||
"auto": true,
|
||||
"auto_count": 500,
|
||||
"auto_min": "10s",
|
||||
"current": {
|
||||
"selected": false,
|
||||
"text": "auto",
|
||||
"value": "$__auto_interval_intervals"
|
||||
},
|
||||
"hide": 0,
|
||||
"label": "Intervals",
|
||||
"name": "intervals",
|
||||
"options": [
|
||||
{
|
||||
"selected": true,
|
||||
"text": "auto",
|
||||
"value": "$__auto_interval_intervals"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "10s",
|
||||
"value": "10s"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30s",
|
||||
"value": "30s"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1m",
|
||||
"value": "1m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "2m",
|
||||
"value": "2m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "5m",
|
||||
"value": "5m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "10m",
|
||||
"value": "10m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "15m",
|
||||
"value": "15m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30m",
|
||||
"value": "30m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1h",
|
||||
"value": "1h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "6h",
|
||||
"value": "6h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "12h",
|
||||
"value": "12h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1d",
|
||||
"value": "1d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "7d",
|
||||
"value": "7d"
|
||||
}
|
||||
],
|
||||
"query": "10s,30s,1m,2m,5m,10m,15m,30m,1h,6h,12h,1d,7d",
|
||||
"queryValue": "",
|
||||
"refresh": 2,
|
||||
"skipUrlSync": false,
|
||||
"type": "interval"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-24h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": [
|
||||
"1m",
|
||||
"5m"
|
||||
]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "WAN Latency",
|
||||
"uid": "ThwrgHYMk",
|
||||
"version": 46,
|
||||
"weekStart": ""
|
||||
}
|
||||
70
influx/dpinger_influx_logger
Executable file
70
influx/dpinger_influx_logger
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
dpinger_path = "/usr/local/bin/dpinger"
|
||||
|
||||
import os
|
||||
import sys
|
||||
import signal
|
||||
import requests
|
||||
from subprocess import Popen, PIPE
|
||||
from requests import post
|
||||
|
||||
# Handle SIGINT
|
||||
def signal_handler(signal, frame):
|
||||
try:
|
||||
dpinger.kill()
|
||||
except:
|
||||
pass
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
# Handle command line ars
|
||||
progname = sys.argv.pop(0)
|
||||
if (len(sys.argv) < 4):
|
||||
print('Usage: {0} influx_url influx_db host name target [additional dpinger options]'.format(progname))
|
||||
print(' influx_url URL of the Influx server')
|
||||
print(' influx_db name of the Influx database')
|
||||
print(' host value of "host" tag (example: output of hostname command)')
|
||||
print(' name value of "name" tag (example: a circuit name such as "wan")')
|
||||
print(' target IP address to monitor (also the value of the "target" tag)')
|
||||
sys.exit(1)
|
||||
influx_url = sys.argv.pop(0)
|
||||
influx_db = sys.argv.pop(0)
|
||||
host = sys.argv.pop(0)
|
||||
name = sys.argv.pop(0)
|
||||
target = sys.argv.pop(0)
|
||||
|
||||
influx_user = os.getenv('INFLUX_USER')
|
||||
influx_pass = os.getenv('INFLUX_PASS')
|
||||
|
||||
# Set up dpinger command
|
||||
cmd = [dpinger_path, "-f"]
|
||||
cmd.extend(sys.argv)
|
||||
cmd.extend(["-r", "10s", target])
|
||||
|
||||
# Set up formats
|
||||
url = '{0}/write?db={1}'.format(influx_url, influx_db)
|
||||
datafmt = "dpinger,host={0},name={1},target={2} latency={{0:.3f}},stddev={{1:.3f}},loss={{2}}i".format(host, name, target)
|
||||
|
||||
# Start up dpinger
|
||||
try:
|
||||
dpinger = Popen(cmd, stdout=PIPE, text=True, bufsize=0)
|
||||
except:
|
||||
print("failed to start dpinger")
|
||||
sys.exit(1)
|
||||
|
||||
# Start the show
|
||||
while True:
|
||||
line = dpinger.stdout.readline()
|
||||
if (len(line) == 0):
|
||||
print("dpinger exited")
|
||||
sys.exit(1)
|
||||
|
||||
[latency, stddev, loss] = line.split()
|
||||
data = datafmt.format(float(latency) / 1000, float(stddev) / 1000, loss)
|
||||
#print(data)
|
||||
try:
|
||||
post(url = url, auth = (influx_user, influx_pass), data = data)
|
||||
except:
|
||||
print("post failed")
|
||||
7
influx/dpinger_start.sh
Executable file
7
influx/dpinger_start.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
INFLUX_URL="http://myinfluxhost:8086"
|
||||
export INFLUX_USER="dpinger"
|
||||
export INFLUX_PASS="myinfluxpass"
|
||||
|
||||
exec /usr/local/dpinger_influx_logger $INFLUX_URL dpinger `hostname` wan 8.8.8.8
|
||||
25
rrd/README.md
Normal file
25
rrd/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
Example scripts for creating RRD graphs with dpinger
|
||||
|
||||
<br>
|
||||
|
||||
Files and Usage:
|
||||
|
||||
dpinger_rrd_create <name>
|
||||
|
||||
Create the rrd initial file.
|
||||
|
||||
dpinger_rrd_update <name> <target> <additional dpinger options>
|
||||
|
||||
Daemon updater script. Runs dpinger and feeds the rrd file.
|
||||
|
||||
dpinger_rrd_gencgi <name>
|
||||
|
||||
Generate a cgi script that displays graphs.
|
||||
|
||||
dpinger_rrd_graph <name>
|
||||
|
||||
Generate png files for use with static html
|
||||
|
||||
sample.html
|
||||
|
||||
Sample static html to display graphs.
|
||||
30
rrd/dpinger_rrd_create
Executable file
30
rrd/dpinger_rrd_create
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -ne 1 ]
|
||||
then
|
||||
echo "usage: $0 name"
|
||||
exit 1
|
||||
fi
|
||||
name="$1"
|
||||
|
||||
rrdfile="${name}.rrd"
|
||||
echo "Creating rrd file ${rrdfile}"
|
||||
|
||||
|
||||
# Time duration method doesn't work in all versions of rrdtool
|
||||
#rrdtool create "${rrdfile}" --step 1m \
|
||||
# DS:latency:GAUGE:5m:0:U \
|
||||
# DS:stddev:GAUGE:5m:0:U \
|
||||
# DS:loss:GAUGE:5m:0:100 \
|
||||
# RRA:AVERAGE:0.5:1m:15d \
|
||||
# RRA:AVERAGE:0.5:5m:90d \
|
||||
# RRA:AVERAGE:0.5:1h:3y
|
||||
|
||||
# This method works in all versions
|
||||
rrdtool create "${rrdfile}" --step 60 \
|
||||
DS:latency:GAUGE:300:0:U \
|
||||
DS:stddev:GAUGE:300:0:U \
|
||||
DS:loss:GAUGE:300:0:100 \
|
||||
RRA:AVERAGE:0.5:1:21600 \
|
||||
RRA:AVERAGE:0.5:5:25920 \
|
||||
RRA:AVERAGE:0.5:60:26352
|
||||
140
rrd/dpinger_rrd_gencgi
Executable file
140
rrd/dpinger_rrd_gencgi
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -ne 2 ]
|
||||
then
|
||||
echo "usage: $0 rrdname pngname"
|
||||
exit 1
|
||||
fi
|
||||
rrdname="${1}"
|
||||
pngname="${2}"
|
||||
|
||||
# Prefixes for rrd and png files. Note that if the prefix is a directory, it must incldue the trailing slash
|
||||
# If no value is set, the files are located in the current directory when the cgi script runs
|
||||
rrdprefix=
|
||||
pngprefix=/tmp/
|
||||
|
||||
|
||||
# Graph dimensions
|
||||
#graph_height=240
|
||||
#graph_width=720
|
||||
graph_height=280
|
||||
graph_width=840
|
||||
|
||||
# Preferred font
|
||||
font="DejaVuSansMono"
|
||||
|
||||
# Latency breakpoints in milliseconds
|
||||
latency_s0=20
|
||||
latency_s1=40
|
||||
latency_s2=80
|
||||
latency_s3=160
|
||||
latency_s4=320
|
||||
|
||||
# Latency colors
|
||||
latency_c0="dddddd"
|
||||
latency_c1="ddbbbb"
|
||||
latency_c2="d4aaaa"
|
||||
latency_c3="cc9999"
|
||||
latency_c4="c38888"
|
||||
latency_c5="bb7777"
|
||||
|
||||
# Standard deviation color & opacity
|
||||
stddev_c="55333355"
|
||||
|
||||
# Loss color
|
||||
loss_c="ee0000"
|
||||
|
||||
|
||||
gen_graph()
|
||||
{
|
||||
png=$1
|
||||
rrd=$2
|
||||
start=$3
|
||||
end=$4
|
||||
step=$5
|
||||
description=$6
|
||||
|
||||
echo "<RRD::GRAPH \"${png}\""
|
||||
echo "--lazy"
|
||||
echo "--start \"${start}\" --end \"${end}\" --step \"${step}\""
|
||||
echo "--height ${graph_height} --width ${graph_width}"
|
||||
echo "--title \"Average Latency and Packet Loss - ${description}\""
|
||||
echo "--disable-rrdtool-tag"
|
||||
echo "--color BACK#ffffff"
|
||||
echo "--font DEFAULT:9:\"${font}\""
|
||||
echo "--font AXIS:8:\"${font}\""
|
||||
|
||||
echo "DEF:latency_us=\"${rrd}\":latency:AVERAGE:step=\"${step}\""
|
||||
echo "CDEF:latency=latency_us,1000,/"
|
||||
echo "CDEF:latency_s0=latency,${latency_s0},MIN"
|
||||
echo "CDEF:latency_s1=latency,${latency_s1},MIN"
|
||||
echo "CDEF:latency_s2=latency,${latency_s2},MIN"
|
||||
echo "CDEF:latency_s3=latency,${latency_s3},MIN"
|
||||
echo "CDEF:latency_s4=latency,${latency_s4},MIN"
|
||||
echo "VDEF:latency_min=latency,MINIMUM"
|
||||
echo "VDEF:latency_max=latency,MAXIMUM"
|
||||
echo "VDEF:latency_avg=latency,AVERAGE"
|
||||
echo "VDEF:latency_last=latency,LAST"
|
||||
|
||||
echo "DEF:stddev_us=\"${rrd}\":stddev:AVERAGE:step=\"${step}\""
|
||||
echo "CDEF:stddev=stddev_us,1000,/"
|
||||
echo "VDEF:stddev_min=stddev,MINIMUM"
|
||||
echo "VDEF:stddev_max=stddev,MAXIMUM"
|
||||
echo "VDEF:stddev_avg=stddev,AVERAGE"
|
||||
echo "VDEF:stddev_last=stddev,LAST"
|
||||
|
||||
echo "DEF:loss=\"${rrd}\":loss:AVERAGE:step=\"${step}\""
|
||||
echo "CDEF:loss_neg=loss,-1,*"
|
||||
echo "VDEF:loss_min=loss,MINIMUM"
|
||||
echo "VDEF:loss_max=loss,MAXIMUM"
|
||||
echo "VDEF:loss_avg=loss,AVERAGE"
|
||||
echo "VDEF:loss_last=loss,LAST"
|
||||
|
||||
echo "COMMENT:\" Min Max Avg Last\n\""
|
||||
|
||||
echo "COMMENT:\" \""
|
||||
echo "AREA:latency#${latency_c5}"
|
||||
echo "AREA:latency_s4#${latency_c4}"
|
||||
echo "AREA:latency_s3#${latency_c3}"
|
||||
echo "AREA:latency_s2#${latency_c2}"
|
||||
echo "AREA:latency_s1#${latency_c1}"
|
||||
echo "AREA:latency_s0#${latency_c0}"
|
||||
echo "LINE1:latency#000000:\"Latency \""
|
||||
echo "GPRINT:\"latency_min:%8.3lf ms\t\""
|
||||
echo "GPRINT:\"latency_max:%8.3lf ms\t\""
|
||||
echo "GPRINT:\"latency_avg:%8.3lf ms\t\""
|
||||
echo "GPRINT:\"latency_last:%8.3lf ms\n\""
|
||||
|
||||
echo "COMMENT:\" \""
|
||||
echo "LINE1:stddev#${stddev_c}:\"Stddev \""
|
||||
echo "GPRINT:\"stddev_min:%8.3lf ms\t\""
|
||||
echo "GPRINT:\"stddev_max:%8.3lf ms\t\""
|
||||
echo "GPRINT:\"stddev_avg:%8.3lf ms\t\""
|
||||
echo "GPRINT:\"stddev_last:%8.3lf ms\n\""
|
||||
|
||||
echo "COMMENT:\" \""
|
||||
echo "AREA:loss_neg#${loss_c}:\"Loss \""
|
||||
echo "GPRINT:\"loss_min:%4.1lf %%\t\t\""
|
||||
echo "GPRINT:\"loss_max:%4.1lf %%\t\t\""
|
||||
echo "GPRINT:\"loss_avg:%4.1lf %%\t\t\""
|
||||
echo "GPRINT:\"loss_last:%4.1lf %%\n\""
|
||||
echo "COMMENT:\" \n\""
|
||||
echo "GPRINT:\"latency_last:Ending at %H\\:%M on %B %d, %Y\\r:strftime\""
|
||||
|
||||
echo ">"
|
||||
echo "<p>"
|
||||
}
|
||||
|
||||
(
|
||||
echo "#!/usr/bin/rrdcgi"
|
||||
echo "<html> <head> <title>Latency Statistics for ${rrdname}</title> </head> <body>"
|
||||
|
||||
gen_graph "${pngprefix}${pngname}-1.png" "${rrdprefix}${rrdname}.rrd" "now-8h" "now" "60" "Last 8 hours - 1 minute intervals"
|
||||
gen_graph "${pngprefix}${pngname}-2.png" "${rrdprefix}${rrdname}.rrd" "now-36h" "now" "300" "Last 36 hours - 5 minute intervals"
|
||||
gen_graph "${pngprefix}${pngname}-3.png" "${rrdprefix}${rrdname}.rrd" "now-8d" "now" "1800" "Last 8 days - 30 minute intervals"
|
||||
gen_graph "${pngprefix}${pngname}-4.png" "${rrdprefix}${rrdname}.rrd" "now-60d" "now" "14400" "Last 60 days - 4 hour intervals"
|
||||
gen_graph "${pngprefix}${pngname}-5.png" "${rrdprefix}${rrdname}.rrd" "now-1y" "now" "86400" "Last 1 year - 1 day intervals"
|
||||
gen_graph "${pngprefix}${pngname}-6.png" "${rrdprefix}${rrdname}.rrd" "now-4y" "now" "86400" "Last 4 years - 1 day intervals"
|
||||
|
||||
echo "</body> </html>"
|
||||
) > "${pngname}.cgi"
|
||||
131
rrd/dpinger_rrd_graph
Executable file
131
rrd/dpinger_rrd_graph
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -ne 2 ]
|
||||
then
|
||||
echo "usage: $0 rrdname pngname"
|
||||
exit 1
|
||||
fi
|
||||
rrdname="${1}"
|
||||
pngname="${2}"
|
||||
|
||||
# Prefixes for rrd and png files. Note that if the prefix is a directory, it must incldue the trailing slash
|
||||
# If no value is set, the files are located in the current directory
|
||||
rrdprefix=
|
||||
pngprefix=/tmp/
|
||||
|
||||
# Graph dimensions
|
||||
graph_height=240
|
||||
graph_width=720
|
||||
#graph_height=280
|
||||
#graph_width=840
|
||||
|
||||
# Preferred font
|
||||
font="DejaVuSansMono"
|
||||
|
||||
# Latency breakpoints in milliseconds
|
||||
latency_s0=20
|
||||
latency_s1=40
|
||||
latency_s2=80
|
||||
latency_s3=160
|
||||
latency_s4=320
|
||||
|
||||
# Latency colors
|
||||
latency_c0="dddddd"
|
||||
latency_c1="ddbbbb"
|
||||
latency_c2="d4aaaa"
|
||||
latency_c3="cc9999"
|
||||
latency_c4="c38888"
|
||||
latency_c5="bb7777"
|
||||
|
||||
# Standard deviation color & opacity
|
||||
stddev_c="55333355"
|
||||
|
||||
# Loss color
|
||||
loss_c="ee0000"
|
||||
|
||||
|
||||
gen_graph()
|
||||
{
|
||||
png=$1
|
||||
rrd=$2
|
||||
start=$3
|
||||
end=$4
|
||||
step=$5
|
||||
description=$6
|
||||
|
||||
rrdtool graph "${png}" \
|
||||
--lazy \
|
||||
--start "${start}" --end "${end}" --step "${step}" \
|
||||
--height "${graph_height}" --width "${graph_width}" \
|
||||
--title "Average Latency and Packet Loss - ${description}" \
|
||||
--disable-rrdtool-tag \
|
||||
--color BACK#ffffff \
|
||||
--font DEFAULT:9:"${font}" \
|
||||
--font AXIS:8:"${font}" \
|
||||
\
|
||||
DEF:latency_us="${rrd}":latency:AVERAGE:step="${step}" \
|
||||
CDEF:latency=latency_us,1000,/ \
|
||||
CDEF:latency_s0=latency,${latency_s0},MIN \
|
||||
CDEF:latency_s1=latency,${latency_s1},MIN \
|
||||
CDEF:latency_s2=latency,${latency_s2},MIN \
|
||||
CDEF:latency_s3=latency,${latency_s3},MIN \
|
||||
CDEF:latency_s4=latency,${latency_s4},MIN \
|
||||
VDEF:latency_min=latency,MINIMUM \
|
||||
VDEF:latency_max=latency,MAXIMUM \
|
||||
VDEF:latency_avg=latency,AVERAGE \
|
||||
VDEF:latency_last=latency,LAST \
|
||||
\
|
||||
DEF:stddev_us="${rrd}":stddev:AVERAGE:step="${step}" \
|
||||
CDEF:stddev=stddev_us,1000,/ \
|
||||
VDEF:stddev_min=stddev,MINIMUM \
|
||||
VDEF:stddev_max=stddev,MAXIMUM \
|
||||
VDEF:stddev_avg=stddev,AVERAGE \
|
||||
VDEF:stddev_last=stddev,LAST \
|
||||
\
|
||||
DEF:loss="${rrd}":loss:AVERAGE:step="${step}" \
|
||||
CDEF:loss_neg=loss,-1,* \
|
||||
VDEF:loss_min=loss,MINIMUM \
|
||||
VDEF:loss_max=loss,MAXIMUM \
|
||||
VDEF:loss_avg=loss,AVERAGE \
|
||||
VDEF:loss_last=loss,LAST \
|
||||
\
|
||||
COMMENT:" Min Max Avg Last\n" \
|
||||
\
|
||||
COMMENT:" " \
|
||||
AREA:latency#${latency_c5} \
|
||||
AREA:latency_s4#${latency_c4} \
|
||||
AREA:latency_s3#${latency_c3} \
|
||||
AREA:latency_s2#${latency_c2} \
|
||||
AREA:latency_s1#${latency_c1} \
|
||||
AREA:latency_s0#${latency_c0} \
|
||||
LINE1:latency#000000:"Latency " \
|
||||
GPRINT:"latency_min:%8.3lf ms\t" \
|
||||
GPRINT:"latency_max:%8.3lf ms\t" \
|
||||
GPRINT:"latency_avg:%8.3lf ms\t" \
|
||||
GPRINT:"latency_last:%8.3lf ms\n" \
|
||||
\
|
||||
COMMENT:" " \
|
||||
LINE1:stddev#${stddev_c}:"Stddev " \
|
||||
GPRINT:"stddev_min:%8.3lf ms\t" \
|
||||
GPRINT:"stddev_max:%8.3lf ms\t" \
|
||||
GPRINT:"stddev_avg:%8.3lf ms\t" \
|
||||
GPRINT:"stddev_last:%8.3lf ms\n" \
|
||||
\
|
||||
COMMENT:" " \
|
||||
AREA:loss_neg#${loss_c}:"Loss " \
|
||||
GPRINT:"loss_min:%4.1lf %%\t\t" \
|
||||
GPRINT:"loss_max:%4.1lf %%\t\t" \
|
||||
GPRINT:"loss_avg:%4.1lf %%\t\t" \
|
||||
GPRINT:"loss_last:%4.1lf %%\n" \
|
||||
\
|
||||
COMMENT:" \n" \
|
||||
GPRINT:"latency_last:Ending at %H\:%M on %B %d, %Y\r:strftime"
|
||||
}
|
||||
|
||||
|
||||
gen_graph "${pngprefix}${pngname}-1.png" "${rrdprefix}${rrdname}.rrd" "now-8h" "now" "60" "Last 8 hours - 1 minute intervals"
|
||||
gen_graph "${pngprefix}${pngname}-2.png" "${rrdprefix}${rrdname}.rrd" "now-36h" "now" "300" "Last 36 hours - 5 minute intervals"
|
||||
gen_graph "${pngprefix}${pngname}-3.png" "${rrdprefix}${rrdname}.rrd" "now-8d" "now" "1800" "Last 8 days - 30 minute intervals"
|
||||
gen_graph "${pngprefix}${pngname}-4.png" "${rrdprefix}${rrdname}.rrd" "now-60d" "now" "14400" "Last 60 days - 4 hour intervals"
|
||||
gen_graph "${pngprefix}${pngname}-5.png" "${rrdprefix}${rrdname}.rrd" "now-1y" "now" "86400" "Last 1 year - 1 day intervals"
|
||||
gen_graph "${pngprefix}${pngname}-6.png" "${rrdprefix}${rrdname}.rrd" "now-4y" "now" "86400" "Last 4 years - 1 day intervals"
|
||||
27
rrd/dpinger_rrd_update
Executable file
27
rrd/dpinger_rrd_update
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -lt 2 ]
|
||||
then
|
||||
echo "usage: $0 rrdname targetip [dpinger options]"
|
||||
exit 1
|
||||
fi
|
||||
name="$1"
|
||||
targetip="$2"
|
||||
shift 2
|
||||
options=$*
|
||||
|
||||
# Where the dpinger executable is located
|
||||
dpinger=/usr/local/bin/dpinger
|
||||
|
||||
|
||||
rrdfile="${name}.rrd"
|
||||
if [ \! -w ${rrdfile} ]
|
||||
then
|
||||
echo "$0: file \"${rrdfile}\" does not exist or is not writable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${dpinger} -f ${options} -s 500m -t 60s -r 60s ${targetip} |
|
||||
while read -r latency stddev loss; do
|
||||
rrdtool update "${rrdfile}" -t latency:stddev:loss "N:$latency:$stddev:$loss"
|
||||
done
|
||||
16
rrd/sample.html
Normal file
16
rrd/sample.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head><title>>Latency Statistics for WAN</title></head>
|
||||
<body>
|
||||
<img src="/tmp/wan-1.png" alt="wan-1">
|
||||
<p>
|
||||
<img src="/tmp/wan-2.png" alt="wan-2">
|
||||
<p>
|
||||
<img src="/tmp/wan-3.png" alt="wan-3">
|
||||
<p>
|
||||
<img src="/tmp/wan-4.png" alt="wan-4">
|
||||
<p>
|
||||
<img src="/tmp/wan-5.png" alt="wan-5">
|
||||
<p>
|
||||
<img src="/tmp/wan-6.png" alt="wan-6">
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user