В этой статье я расскажу как построить график в Linux при помощи gnuplot, взяв любые данные из маршрутизатора Mikrotik по SNMP. Мне нужно было строить график скорости по портам ether1 и wlan каждую секунду, поэтому график, который можно взять из самого микротика не подходил, так как он может дать только за 5 минут, и строит график в большом диапазоне.

Настройка роутера

Для начала включим SNMP на роутере.

/snmp set enabled=yes

Если вы будете настраивать на удаленном роутере, то следует пробросить 161 порт, а также настроить разрешенные адреса:

/ip firewall filter
add action=accept chain=input src-address=[addr1] dst-port=161 protocol=udp comment=snmp

Где [addr1] – это ip-адрес сервера, который будет брать данные с маршрутизатора.

Настройка Firewall на Mikrotik

Данные

Определимся с тем, что мы хотим получать. Мне нужны данные по портам ether1 и wlan, чтобы видеть количество Кбит/с.

Чтобы получать эти данные нужно узнать oid – идентификатор объекта, который содержит какое-то значение. Так как мне нужны порты, то вводим следующее:

/interface print oid

Появится список:

Нам нужны объекты bytes-in и bytes-out у интерфейса 0 и 1 – ether1 и wlan соответственно:

Запоминаем идентификаторы.

Ubuntu SNMP

Для начала проверим, что мы получаем, если отправим запрос по этим oid’ам.

Устанавливаем snmp:

sudo apt install snmp
snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.6.2

192.168.1.1 – адрес маршрутизатора

В ответ мы получаем количество полученных байт с момента включения маршрутизатора. Аналогично можно проверить другие oid.

Теперь, чтобы вычислить, сколько Кбит в данную секунду получает или отправляет порт, нужно воспользоваться формулой:

( конечноеЗначение – начальноеЗначение ) * 8 / 1000

В 1 байте 8 бит, в 1 Килобайте 1000 байт (грубо).

Ubuntu data.txt

Чтобы построить график нужно иметь точки с координатами. В моем случае ось x – это время, ось y – скорость в Кбит. Мне нужен график с периодом 20 секунд, чтобы видеть тенденцию, поэтому будут 20 точек (строк) для входящей и исходящей скорости у портов ether1 и wlan. То есть data.txt будет выглядеть так:

12:19:03 234 9174 0 0
12:19:04 181 7980 0 0
12:19:05 10 13 0 0
12:19:07 34 8 0 0 …

1 колонка – время, 2 – bytes-out ether1, 3 – bytes-in ether1, 4 – bytes-out wlan, 5 – bytes-in wlan

Создадим скрипт getDataFromMikrotik.sh для формирования data.txt:

#!/bin/bash
rm -f data.txt
#удаляем старый data.txt, если он есть

while true; do
	bytesRxEther1Old=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.6.2 | awk 'NF>1{print $NF}')
	bytesTxEther1Old=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.10.2 | awk 'NF>1{print $NF}')
	bytesRxWlanOld=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.6.1 | awk 'NF>1{print $NF}')
	bytesTxWlanOld=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.10.1 | awk 'NF>1{print $NF}')
	sleep 1
	bytesRxEther1New=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.6.2 | awk 'NF>1{print $NF}')
	bytesTxEther1New=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.10.2 | awk 'NF>1{print $NF}')
	bytesRxWlanNew=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.6.1 | awk 'NF>1{print $NF}')
	bytesTxWlanNew=$(snmpwalk -v1 -cpublic 192.168.1.1 1.3.6.1.2.1.31.1.1.1.10.1 | awk 'NF>1{print $NF}')
	echo $(date +%H:%M:%S) $(( ($bytesTxEther1New-$bytesTxEther1Old)*8/1000 )) $(( ($bytesRxEther1New-$bytesRxEther1Old)*8/1000 )) $(( ($bytesTxWlanNew-$bytesTxWlanOld)*8/1000 )) $(( ($bytesRxWlanNew-$bytesRxWlanOld)*8/1000 )) >> data.txt
	
	countLines=$(wc -l data.txt | cut -f 1 -d " " )
	
	if [ $countLines -ge 21 ]; then
		tail -n +2 data.txt > temp.txt && mv temp.txt data.txt
	fi
done

Команда tail -n +2 выводит data.txt без первой строчки и сохраняет вывод в temp.txt, затем temp.txt заменяет data.txt.

gnuplot

Устанавливаем gnuplot:

sudo apt install gnuplot

Создаем скрипт createGraph.p для построения графиков:

#!/gnuplot
set terminal png
set output 'graph.png'

set size 1, 1 # пропорции изображения
set multiplot # обозначаем, что строим несколько графиков

set size 1, 0.5 # пропорции первого графика - ширина, высота
set origin 0, 0.5 # начальные координаты графика
set title "ether1"
set xdata time # обозначаем x как временную ось
set timefmt '%H:%M:%S'
set format x "%H:%M:%S"
set xlabel "Time"
set ylabel "Kbps"
set xtics right rotate by 30 # поворачиваем подписи к оси x на 30 градусов вправо
set grid ytics xtics # добавляем сетку
set yrange [0:20000]
plot "data.txt" using 1:2 title "Tx" with filledcurves x1 fs solid 0.5 lc rgb 'red', "data.txt" using 1:3 title "Rx" with filledcurves x1 fs solid 0.5 lc rgb 'blue'

# using 1:2 - использовать 1 и 2 колонку в файле data.txt

set size 1, 0.5
set origin 0, 0
set title "wlan"
set xdata time
set timefmt '%H:%M:%S'
set format x "%H:%M:%S"
set xlabel "Time"
set ylabel "Kbps"
set xtics right rotate by 30
set grid ytics xtics
set yrange [0:20000]
plot "data.txt" using 1:4 title "Tx" with filledcurves x1 fs solid 0.5 lc rgb 'red', "data.txt" using 1:5 title "Rx" with filledcurves x1 fs solid 0.5 lc rgb 'blue'

Сохраняем скрипт, запускаем скрипт getDataFromMikrotik, ждем 20 секунд, чтобы накопить данные, желательно при этом иметь нагрузку на порты для наглядности. Затем рисуем график:

gnuplot createGraph.p
Получаем график graph.png

Рисуем каждую секунду с заменой

Чтобы рисовать график с задержкой в 1 секунду, то есть с погрешностью, создадим скрипт runGnuplot.sh:

#!/bin/bash
while true;
do
	gnuplot createGraph.p
	sleep 1
done

Изображение будет автоматически заменяться на новое.

Рисуем каждую секунду в новый файл

#!/bin/bash
while true;
do
	gnuplot createGraph.p
	mv graph.png /graph/graph-$(date +%H-%M-%S).png
done

В этом случае каждый новый файл будет перемещаться в предварительно созданную папку graph с именем вида graph-10-49-03.png

Графики объединенные в видео с помощью ffmpeg: