Monitoring MTR Statistic with Influxdb & Grafana

The sometimes network guy confused to determine root cause related network problem & no data statistic to report as evidence of the root cause at the previously time. This time we will create a simple script to collect data and stored into influxdb. Take a cup of coffee and smoke ( not on the water ), Let’s Go! 😉

Install requirement package. we tested it in our environment using debian 9

apg-get install mtr docker-ce python3-pip -y

pip3 install influxdb

docker pull influxdb

The result of docker image have you download

influxdb latest 234234234 2 weeks ago 264MB


in this case above, image id docker is 234234234. Run container & make sure the container already up & have exposed to external

#docker run -d -p 8086:8086 234234234

#docker ps -a | grep 23423423
842501af3012 234234234 “/entrypoint.sh infl…” 20 hours ago Up 20 hours 0.0.0.0:8086->8086/tcp

#netstat -ntap | grep 8086
tcp6 0 0 :::8086 :::* LISTEN 27816/docker-proxy

login into docker and execute some of command in influxdb

# docker exec -it 234234234 /usr/bin/influx -precision rfc3339

Connected to http://localhost:8086 version 1.7.8
InfluxDB shell version: 1.7.8
>CREATE DATABASE mtr
>USE mtr
>CREATE USER mtruser with PASSWORD ‘123456’ WITH ALL PRIVILEGES
>GRANT ALL ON mtr TO mtruser


Create a bash script for collect data mtr, for example the name of file is mtr-exporter.sh in folder /opt/mtr-exporter-influx and put these script into those file have you created. in this scenario all files will put in folder /opt/mtr-exporter-influx.

# mkdir -p /opt/mtr-exporter-influx

# vi /opt/mtr-exporter-influx/mtr-exporter.sh

Put the script below & save

#!/bin/bash

INTERVAL=60
INFLUXDB_HOST="192.168.38.60"
INFLUXDB_PORT=8086

function monitor_mtr() {
  for MTR_HOST in $(cat /opt/mtr-exporter-influx/list-ip-dest); do
    ( mtr --report --tcp --port=443 --json --report-cycles $CYCLES $MTR_HOST | /usr/bin/python3 /opt/mtr-exporter-influx/save_data.py --host $INFLUXDB_HOST --port $INFLUXDB_PORT ) &
  done
}

which mtr &>/dev/null
if [ $? -eq 1 ]; then
  echo "mtr not found, please install mtr "
  exit 1
else
echo "collecting data..."
fi 
while true; do
  monitor_mtr
  sleep $INTERVAL
done

# chmod +x /opt/mtr-exporter-influx/mtr_exporter.sh

Create List of IP Destination that you will monitor. For example 1.1.1.1 and 8.8.8.8

# vi /opt/mtr-exporter-influx/list-ip-dest

The following format file after file created

# cat /opt/mtr-exporter-influx/list-ip-dest
1.1.1.1
8.8.8.8
#

Create a python script for export data mtr into Influxdb, for example the name of file save_data.py and put these script into your have you created

#!/usr/bin/env python3
import argparse
import json
import sys
import datetime as dt
import logging

from influxdb import InfluxDBClient, SeriesHelper

logging.basicConfig(level=logging.INFO)
db_name = 'mtr'
user = 'mtruser'
password = '123456'

class HubEntry(SeriesHelper):
     class Meta:
         series_name = '{destination}'
         fields = ['time', 'loss', 'snt', 'last', 'avg', 'best', 'wrst', 'stdev']
         tags = ['destination', 'hop']
         
def get_cmd_arguments():
     parser = argparse.ArgumentParser(description='JSON parser')
     parser.add_argument('--host', default='192.168.38.60', help='influxdb host')
     parser.add_argument('--port', default=8086, help='influxdb port')
return parser.parse_args()

mtr_result = json.load(sys.stdin)
# ping destination
destination = mtr_result['report']['mtr']['dst']
report_time = dt.datetime.utcnow()
for hub in mtr_result['report']['hubs']:
    # persist the hub entry
    # Modifying the data if needed so that is can be easily sorted in the event of more than 9 hops.
    if len(hub['count']) < 2:
        hop = "0" + hub['count'] + "-" + hub['host']
    else:
        hop = hub['count'] + "-" + hub['host']
    HubEntry(
        time=report_time,
        destination=destination,
        hop=hop,
        loss=hub['Loss%'],
        snt=hub['Snt'],
        last=hub['Last'],
        avg=hub['Avg'],
        best=hub['Best'],
        wrst=hub['Wrst'],
        stdev=hub['StDev']
    )
HubEntry.commit()

if name == 'main':
     main()

Assuming we have 3 files that have been created

#ls -l
mtr-exporter.sh
save_data.py
list-ip-dest

Create a linux service mtr-exporter, the example service name is mtr-exporter, create a file mtr-exporter.service in folder /lib/systemd/system

[Unit]
Description=mtr exporter
After=multi-user.target

[Service]
Type=idle
ExecStart=/bin/bash /opt/mtr-exporter-influx/mtr-export.sh

[Install]
WantedBy=multi-user.target

systemctl daemon-reload

systemctl start mtr-exporter.service


Add datasource in Grafana



Download the dashboard and then import from grafana




Reference https://grafana.com/grafana/dashboards/3288

Leave a Reply

Your email address will not be published. Required fields are marked *