Страница 1 из 1
Скрипт для проверки ширины канала
Добавлено: 12 ноя 2014, 05:34
druide
Добрый день!
Стояла задача мониторинга ширины канала между головным офисом и филиалами предприятия. Везде используются роутеры микротик, поэтому решил использовать встроенный тест скорости.
Вот что получилось. Код хорошо комментирован, поэтому переделать его "под себя" думаю будет не сложно.
Код: Выделить всё
# Скрипт проверяет ширину канала между текущим и заданными хостами и отправляет результат на почту
# Скорость приема и передачи, соответственно
:local RxSpeed 0
:local TxSpeed 0
# Тело письма отчета
:local Msg ""
# Тема письма
:local Subject ""
# Текущее время и дата
:local CurDate ([/system clock get date]." ".[/system clock get time])
# Тут список ip хостов которые тестируем (это можно убрать, если будет тестироваться только один ip)
:local IpList [:toarray x.x.x.x,x.x.x.x]
# Описание хостов (что-бы отчет выглядел более понятным)
:local IpDescriptions [:toarray "host1, host2"]
:set Subject ("Band Width report ".$CurDate)
:local i 0
# Перебираем адреса в массиве IpList
:foreach TestIP in=$IpList do={
# Собственно сам тест
# Тут, user и password - учетные данные пользователя на удаленном устройстве, имеющего права на данную операцию.
/tool bandwidth-test address=$TestIP duration=60s protocol=tcp user=user password=password direction=both do={:set RxSpeed [$"rx-total-average"];:set TxSpeed [$"tx-total-average"]}
:set RxSpeed ($RxSpeed/1024)
:set TxSpeed ($TxSpeed/1024)
# Формируем отчет
:set Msg ($Msg.("Speed test to ".[:pick $IpDescriptions $i]."\r\nDestination ip:".$TestIP."\r\nRxSpeed= ".$RxSpeed." Kb/s\r\n"."TxSpeed= ".$TxSpeed." Kb/s\r\n\r\n"))
:set i ($i+1)
}
# Отправляем письмо.
# server - ip почтового сервера
# from - почтовый ящик с которого будет оправляться отчет
# user, password - данные авторизации на почтовом сервере.
# to - куда отправляем отчет
/tool e-mail send server=x.x.x.x port=25 from=router@server.ru body=$Msg user=user password=password to=admin@server.ru subject=$Subject
Спасибо участникам форума, кто помог в написании скрипта.
Re: Скрипт для проверки ширины канала
Добавлено: 11 май 2020, 00:18
drpioneer
Приветствую.
Вариант этого же скрипта с выводом инфы в журнал.
Код: Выделить всё
# Script for determining the bandwidth of VPN interfaces by Druide
# https://forummikrotik.ru/viewtopic.php?t=5986
# tested on ROS 6.46.5
# updated 2020/05/10
:local listIP [:toarray 192.168.89.1,192.168.90.1,192.168.91.1];
:local descriptionsIP [:toarray Moscow,Bryansk,Pupkino];
:local currentDate ([/system clock get date]." ".[/system clock get time]);
:local rxSpeed 0;
:local txSpeed 0;
:local index 0;
:local message "";
:local subject "";
:set subject (">>> Bandwidth VPN report on ".$currentDate);
:foreach testIP in=$listIP do={
:do {
/tool bandwidth-test address=$testIP duration=60s protocol=tcp user=LOGIN password=PASSWORD direction=both do={ :set rxSpeed [$"rx-total-average"]; :set txSpeed [$"tx-total-average"]; }
:set rxSpeed ($rxSpeed/1024);
:set txSpeed ($txSpeed/1024);
:set message ($message.(">>> speed test to ".[:pick $descriptionsIP $index].", destination IP: ".$testIP."\r\n>>> speed Rx: ".$rxSpeed." Kbps".", Tx: ".$txSpeed." Kbps\r\n"));
:set index ($index+1);
} on-error={ :log warning (">>> Script error. Not found VPN IP"); }
}
:log warning ($subject);
:log warning ($message);
Re: Скрипт для проверки ширины канала
Добавлено: 16 янв 2021, 01:28
drpioneer
Добрый день.
Обновил скрипт на предмет автоматического поиска и перебора подходящих VPN-интерфейсов.
Код: Выделить всё
# Script for determining the bandwidth of VPN interfaces by drPioneer
# https://forummikrotik.ru/viewtopic.php?t=5986
# tested on ROS 6.48
# updated 2021/04/21
:do {
:local localUser "login";
:local localPassword "password";
:local nameVPN "VPN";
:local fileName "disk1/bandwidth.txt";
:local countPing 2;
:local rxSpeed 0;
:local txSpeed 0;
:local message " Bandwidth test report on ";
:local currentDate ([/system clock get date]." ".[/system clock get time]);
:set message ($message.$currentDate.":");
:log warning ($message);
:set message ($message."\r\n");
if ($localUser != "" && $localPassword != "" && $nameVPN != "") do={
:foreach activeVPN in=[ /ip address find interface~$nameVPN; ] do={
:do {
:local remoteAddress [ /ip address get $activeVPN network; ];
:local localAddress [ /ip address get $activeVPN address; ];
:local interfaceVPN [ /ip address get $activeVPN interface; ];
:local staticIP " ";
:do { :set staticIP [ /ip route get [ find gateway=$interfaceVPN static=yes ] dst-address]; } on-error={ }
:local checkPing [ /ping $remoteAddress src-address=[ :pick $localAddress 0 ([ :len $localAddress ] - 3)] count=$countPing; ];
:if ($checkPing < ($countPing / 3 * 2)) do={
:log warning ( "Test of '$interfaceVPN' is fail, active interface not responded." );
:set message ("$message Test of '$interfaceVPN' is fail, active interface not responded.\r\n");
} else={
/tool bandwidth-test address=$remoteAddress duration=10s protocol=tcp user=$localUser password=$localPassword direction=both do={
:set rxSpeed ([$"rx-total-average"]);
:set txSpeed ([$"tx-total-average"]);
}
:local simpleMbRxReport ($rxSpeed / 1000000);
:local simpleMbTxReport ($txSpeed / 1000000);
:local lowMbRxReport ((($rxSpeed - ($simpleMbRxReport * 1000000)) * 1000000) / 1000);
:local lowMbTxReport ((($txSpeed - ($simpleMbTxReport * 1000000)) * 1000000) / 1000);
:local mbRxReport "";
:local mbTxReport "";
if ($simpleMbRxReport < 100) do={ if ($simpleMbRxReport < 10) do={ :set mbRxReport (" "); } else={ :set mbRxReport (" "); } }
if ($simpleMbTxReport < 100) do={ if ($simpleMbTxReport < 10) do={ :set mbTxReport (" "); } else={ :set mbTxReport (" "); } }
:set mbRxReport ("$mbRxReport$simpleMbRxReport.$[:pick $lowMbRxReport 0 2]");
:set mbTxReport ("$mbTxReport$simpleMbTxReport.$[:pick $lowMbTxReport 0 2]");
:set interfaceVPN ([:pick "'$interfaceVPN': " 0 41]);
:set remoteAddress ([:pick "$remoteAddress " 0 19]);
:set staticIP ([:pick "$staticIP " 0 19]);
:set mbRxReport ([:pick "$mbRxReport Mbps, " 0 12]);
:set mbTxReport ([:pick "$mbTxReport Mbps. " 0 12]);
:set message ("$message test to $interfaceVPN $remoteAddress $staticIP => Rx: $mbRxReport Tx: $mbTxReport\r\n");
:log warning ( "test to $interfaceVPN $remoteAddress $staticIP => Rx: $mbRxReport Tx: $mbTxReport" );
}
} on-error={ :log warning ("Script error. Not found some $nameVPN interfaces."); }
}
} else={ :set message ("$message Script error. Check variables: localUser, localPassword, nameVPN.\r\n"); }
:if ($fileName != "") do={
:if ( [:len [/file find name=$fileName]] = 0) do={ /file print file=$fileName where name=""; }
:do { /file set $fileName contents=($message."\r\n".[get $fileName contents]); } on-error={ }
} else={ :set message ("$message File name undefined - no output to file. Check variable fileName.\r\n"); }
:log warning (" End of bandwidth test.");
:set message ("$message End of bandwidth test.\r\n");
:put ($message);
}
Переменная
localUser содержит имя пользователя.
Переменная
localPassword содержит пароль пользователя.
Переменная
nameVPN содержит общую часть названия требуемых VPN-интерфейсов.
Можно указать переменную
fileName, тогда вывод будет дублироваться в указанный файл.
Re: Скрипт для проверки ширины канала
Добавлено: 13 июл 2021, 12:42
yuriy.shevchik
Спасибо
Re: Скрипт для проверки ширины канала
Добавлено: 03 янв 2024, 18:07
drpioneer
Версия скрипта, работающая и под ROS6, и под ROS7:
Код: Выделить всё
# Script for determining the bandwidth of VPN interfaces
# Script uses ideas by druide, Sertik, drPioneer
# https://forummikrotik.ru/viewtopic.php?t=5986
# tested on ROS 6.49.10 & 7.12
# updated 2023/12/29
:do {
:local user "";
:local pswd "";
:local countPing 2;
:local message "Bandwidth report from '$[system identity get name]':";
# --------------------------------------------------------------------------------- # digit conversion function via SI-prefix
:local NumSiPrefix do={
:local inp [:tonum $1]; :local cnt 0;
:while ($inp>1000) do={:set $inp ($inp/1000); :set $cnt ($cnt+1)}
:return ($inp.[:pick [:toarray "Bps,Kbps,Mbps,Gbps,Tbps,Pbps,Ebps,Zbps,Ybps"] $cnt]);
}
# ================================================================================= # main body of the script ========================
:local routeISP [/ip route find]; # gateways information
:if ($user!="" && $pswd!="" && [:len $routeISP]>0) do={
:local gwList [:toarray ""]; :local count 0;
:foreach idEth in=[/interface ethernet find] do={ # list of ethernet interfaces
:set ($gwList->$count) [/interface ethernet get $idEth name];
:set count ($count+1);
}
:local ethCount $count;
:foreach inetGate in=$routeISP do={ # enumeration of gateways
:local gwName [:tostr [/ip route get $inetGate gateway]];
:if ([:len $gwName]>0) do={
:local ifaceISP ""; # formation of interface name
:foreach idName in=[/interface find running=yes] do={
:local ifName [/interface get $idName name];
:if ([:len [find key=$ifName in=$gwName]]>0) do={:set ifaceISP $ifName}
}
:if ([:len $ifaceISP]>0) do={
:if ([:len [/interface bridge find name=$ifaceISP]]>0) do={ # checking the interface for entering the Bridge
:if ([:find $gwName "%"]>0) do={
:set $gwName [:pick $gwName ([:len [:pick $gwName 0 [:find $gwName "%"]]] +1) [:len $gwName]];
}
:if ($gwName~"((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)[.]){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)") do={
:local mcAddrGate [/ip arp get [find address=$gwName interface=$ifaceISP] mac-address];
:if ($mcAddrGate~"([0-9A-F]{2}[:]){5}[0-9A-F]{2}") do={
:set ifaceISP [/interface bridge host get [find mac-address=$mcAddrGate] interface];
} else={:set ifaceISP ""}
} else={:set ifaceISP ""}
}
:if ([:len $ifaceISP]>0) do={
:local checkIf [:len [find key=$ifaceISP in=$gwList]]; # checking the repetition of interface name
:if ($checkIf=0) do={
:set ($gwList->$count) $ifaceISP;
:set count ($count+1);
:local remAddr [/ip address get [find interface=$ifaceISP] network];
:local locAddr [/ip address get [find interface=$ifaceISP] address];
:local chkPing [/ping $remAddr src-address=[:pick $locAddr 0 ([:len $locAddr]-3)] count=$countPing];
:if ($chkPing<($countPing/3*2)) do={:set message "$message \r\n'$ifaceISP' is fail, interface not responded.";
} else={
:local rxSpeed ""; :local txSpeed "";
/tool bandwidth-test address=$remAddr duration=5s protocol=tcp user=$user password=$pswd direction=receive do={:set rxSpeed [$NumSiPrefix [$"rx-total-average"]]}
/tool bandwidth-test address=$remAddr duration=5s protocol=tcp user=$user password=$pswd direction=transmit do={:set txSpeed [$NumSiPrefix [$"tx-total-average"]]}
:set message "$message\r\n'$ifaceISP' $rxSpeed/$txSpeed (Rx/Tx)";
}
}
}
}
}
}
:if ($ethCount=$count) do={:set message "$message \r\nNo active VPN-routes"}
} else={:set message "$message \r\nEmpty variables 'user','pswd' or no active routes"}
:put $message; # output of message
log warning $message;
} on-error={ :log warning "Error, can't show bandwidth test"}
Переменные user/pswd хранят логин/пароль для встроенного BTestServer.
Re: Скрипт для проверки ширины канала
Добавлено: 12 фев 2024, 11:47
drpioneer
Приветствую всех!
Представляю вариант скрипта проверки ширины каналов с использованием встроенных в RouterOS тестов 'PingSpeed' и 'BandWidth':
Код: Выделить всё
# Script for determining bandwidth of channel
# Script uses ideas by druide, Sertik, drPioneer
# https://forummikrotik.ru/viewtopic.php?t=5986
# tested on ROS 6.49.10 & 7.12
# updated 2024/02/12
:do {
:local myFile ""; # file name, for example "bandwidth.txt";
:local listIP {
{name="MkBwTst"; ip=23.162.144.120; user="MikrotikBtest"; pswd="MikrotikBtest"; prot="tcp"};
{name="Neterra"; ip=87.121.0.45; user="neterra"; pswd="neterra"; prot="tcp"};
{name="Google"; ip=173.194.221.138; user=""; pswd=""; prot="tcp"};
# {name="MyVPN"; ip=192.168.1.10; user="test"; pswd="test"; prot="tcp"};
}
# channel speed measurement function --------------------------------------------------
:local BandWidthTest do={
# digit conversion function via SI-prefix -------------------------------------------
:local NumSiPrefix do={
:if ([:len $1]=0) do={:return "0Bps"}
:local inp [:tonum $1]; :local cnt 0;
:while ($inp>1000) do={:set $inp ($inp/1000); :set $cnt ($cnt+1)}
:return ($inp.[:pick [:toarray "Bps,Kbps,Mbps,Gbps,Tbps,Pbps,Ebps,Zbps,Ybps"] $cnt]);
}
:local rxSpd ""; :local txSpd ""; :local rxSts ""; :local txSts ""; :local pngTst;
/tool ping-speed address=$1 duration=11 do={:set pngTst [$NumSiPrefix [$"average"]]}
:local outMsg "PingSpeedTest:\t$pngTst\tBandWidthTest via $4:";
/tool bandwidth-test address=$1 user=$2 password=$3 protocol=$4 direction="receive" duration=5 do={
:set rxSpd [$NumSiPrefix [$"rx-total-average"]]; :set rxSts [$"status"];
}
/tool bandwidth-test address=$1 user=$2 password=$3 protocol=$4 direction="transmit" duration=5 do={
:set txSpd [$NumSiPrefix [$"tx-total-average"]]; :set txSts [$"status"];
}
:if ($rxSts=$txSts) do={:if ($rxSts~"done") do={:return "$outMsg\t$rxSpd/$txSpd(Rx/Tx)"} else={:return "$outMsg\t$rxSts"}}
:if ($txSts~"done") do={:return "$outMsg\t$rxSts"}
:if ($rxSts~"done") do={:return "$outMsg\t$txSts"}
:return "$outMsg\tunknown error";
}
# main body of script -----------------------------------------------------------------
:global outBndWdt "Bandwidth report from $[system identity get name]:";
:if ([:len $listIP]>0) do={
:foreach testCh in=$listIP do={
:local remNam ($testCh->"name");
:local remUsr ($testCh->"user"); :local remPsw ($testCh->"pswd");
:local remPrt ($testCh->"prot"); :local remAdr ($testCh->"ip");
:put ("> Test to '$remNam' ($remAdr) via $remPrt:");
:local pngCnt [/ping $remAdr count=3];
:if ($pngCnt<2) do={:set outBndWdt "$outBndWdt\r\n> $remNam\t$remAdr\tis fail, address not responded";
} else={:set outBndWdt "$outBndWdt\r\n> $remNam\t$remAdr\t$[$BandWidthTest $remAdr $remUsr $remPsw $remPrt]"}
}
} else={:set outBndWdt "$outBndWdt\r\n> Test is not possible, list of IP-addresses is empty"}
:put ("-----------------------------------------------------------------------------------------------------\r\n$outBndWdt");
:log warning $outBndWdt;
:if ([:len $myFile]!=0) do={
:local fileName ("$[/system identity get name]_$myFile");
:execute script=":global outBndWdt; :put \"$outBndWdt\";" file=$fileName;
:put ("File '$fileName' was successfully created");
} else={:put ("File creation is not enabled")}
} on-error={:put "Error, can't show bandwidth test"; :log warning "Error, can't show bandwidth test"}
/system script environment remove [find name~"outBndWdt"];
Для полноценной проверки ширины каналов, на дальних концах должны быть настроены BTestServer'ы: Tools/BTestServer, Enabled=yes, Authenticate=yes. Без настроенных BTestServer'ов скрипт тоже покажет скоростные характеристики каналов за счёт теста 'PingSpeed', для этого дальние концы каналов должны Ping'оваться.
В скрипте необходимо заполнить список каналов по шаблону:
- name="имя_канала"
- ip=ip_адрес_дальнего_конца_канала
- user="имя_пользователя_для_bandwidth_теста"
- pswd="пароль_для_bandwidth_теста"
- prot="протокол_для_bandwidth_теста_tcp_или_udp"
При запуске скрипта перебирается заданный список каналов и проводятся соответствующие тесты. По результатам тестов выводится полученная статистика. При указании имени файла в переменной 'myFile' результат также будет выводиться в файл.
Предлагаю заинтересованным потестить работу скрипта и отписать о замеченных проблемах.
Зеркало
тут.
Удачи!