This is an old revision of the document!
Monitorix is a great tool to measure and graph your devices and services .
it works perfectly on your local device to monitor and archive performances and usages.
Although there are many builtin monitored items (system, cpu, net, sensors, applications …) and features, you may have to monitor a special device or application that is not yet integrated .
That's the purpose of this page to explain how I managed to monitor my personnal gateway to the Internet which doesn't have builtin graph capabilities .
I want to get In and Out trafic like that :
First we need to install and configure monitorix, there are many tutorials to do that, as I am using centos 8 system I followed that one :
In this page I will demonstrate how I manage to monitor In and Out bandwith usage of my FreeBox-Crystal which is a French ADSL router . The device does provide an http service to get the status of its services . it replies on the Lan interface at the address of the router itself
this page returns many information in text format like this :
______________________________________________________________________ Etat de la Freebox ______________________________________________________________________ Informations générales : ======================== Modèle Freebox ADSL Version du firmware 1.5.28 Mode de connection Dégroupé Temps depuis la mise en route 33 jours, 20 heures, 34 minutes .... Adsl : ====== Etat Showtime Protocole ADSL2+ Mode Interleaved Descendant Montant -- -- Débit ATM 11074 kb/s 681 kb/s ... Interfaces réseau : ------------------- Lien Débit entrant Débit sortant -- -- -- WAN Ok 63 ko/s 9 ko/s Ethernet 100baseTX-FD 10 ko/s 54 ko/s
From the differents information provided by this web interface, the ones I want to graph is on the WAN interface the In trafic (here 63 Ko/s) and Out (9 ko/s)
I am not a monitorix developer , but with great and smart indication from Monitorix developers , as there is no generic module nor snmp capailities (anyway my Freebox doesn't provide such) , I was advise to create my own module based on an existing one that already collect and graph values from an http request . The Nginx module was my starting point .
you can check location of all the monitorix components by requesting file location of tha monitorix package with :
# rpm -ql monitorix /etc/logrotate.d/monitorix /etc/monitorix /etc/monitorix/conf.d /etc/monitorix/monitorix.conf /etc/sysconfig/monitorix /usr/bin/monitorix /usr/lib/monitorix /usr/lib/monitorix/HTTPServer.pm /usr/lib/monitorix/Monitorix.pm ... /usr/lib/monitorix/nginx.pm ... /var/lib/monitorix/www /var/lib/monitorix/www/cgi /var/lib/monitorix/www/cgi/monitorix.cgi ...
here we can see particularly /etc/monitorix/monitorix.conf which is the main configuration file and /usr/lib/monitorix/nginx.pm which is the module I will duplicate for my device .
# cp nginx.pm fbxcfr.pm # pwd /usr/lib/monitorix
After you have check that monitorix work fine with native modules, to help debuging , I removed all modules from the main config file : monitorix.conf in order that logs shows only potential problem of my specific module here named fbxcfr (just after nginx) .
<graph_enable> system = n kern = n proc = n .... nginx = n fbxcfr = y
duplicate all nginx parameters in the conf file to fbxcfr (or whatever name you give to your module) so that your module is taken into account by the monitorix daemon . this happens if different sections: graph_enable, graph_name, graph_title and graphs
<graph_enable> fbxcfr = y ... # fbxcfr graph # ----------------------------------------------------------------------------- <fbxcfr> url = http://192.168.3.254/pub/fbx_info.txt port = 80 rule = 24100 rigid = 0, 0, 0 limit = 100, 100, 100 </fbxcfr> ... graph_name = system, kern, proc, ... nginx, fbxcfr, <graph_title> ... nginx = Nginx statistics fbxcfr = FreeboX-Crystal statistics ... <graphs> ... _nginx1 = Nginx connections _nginx2 = Nginx requests _nginx3 = Nginx traffic _fbxcfr1 = FbxCFR connections _fbxcfr2 = FbxCFR requests _fbxcfr3 = FbxCFR traffic ...
stop your traditional run of monitorix
# systemctl stop monitorix.service
run it in debug mode to be ale to see potential errors
# /usr/bin/monitorix -c /etc/monitorix/monitorix.conf -p /run/monitorix.pid -d all
if the module is up and running (cf code fbxcfr.pm next) here's what the logs says after starting the daemon in debug mode
Tue Apr 21 17:57:49 2020 - Starting Monitorix version 3.12.0 (pid 1166). Tue Apr 21 17:57:49 2020 - Loaded main configuration file '/etc/monitorix/monitorix.conf'. Tue Apr 21 17:57:49 2020 - Entering in debug mode. Tue Apr 21 17:57:49 2020 - Changed process name to '/usr/bin/monitorix -c /etc/monitorix/monitorix.conf -p /run/monitorix.pid -d all'. Tue Apr 21 17:57:49 2020 - Flushing out iptables rules. Tue Apr 21 17:57:49 2020 - 0 iptables rules have been flushed. Tue Apr 21 17:57:49 2020 - 0 ip6tables rules have been flushed. Tue Apr 21 17:57:49 2020 - Initializing graphs. Tue Apr 21 17:57:49 2020 - fbxcfr::fbxcfr_init: Ok Tue Apr 21 17:57:49 2020 - Generating the 'index.html' file. Tue Apr 21 17:57:49 2020 - Setting owner/group and permission bits for the imgs/ directory. Tue Apr 21 17:57:49 2020 - Started HTTP built-in server (pid 1214). Tue Apr 21 17:57:49 2020 - Ok, ready. HTTPServer: You can connect to your server at http://localhost:8080/
then after few second (at next minute) , here comes my two values In and Out inserted in the rrd file
Tue Apr 21 17:58:00 2020 - Calling fbxcfr_update() Tue Apr 21 17:58:01 2020 - fbxcfr::fbxcfr_update: N:57344:6144
we can check the rrd file for the value it collected
# rrdtool fetch /var/lib/monitorix/fbxcfr.rrd LAST | tail -5 1587484440: 3,1267075959e+04 8,8793457323e+03 1587484500: 5,9931363328e+04 1,6254763554e+04 1587484560: 2,7674024499e+05 1,2321572864e+04 1587484620: 6,6060986658e+04 4,2323786411e+03 1587484680: 5,7390888533e+04 6,1252445867e+03
as explained earlier , I copied the nginx module to create mine fbxcfr module . I follows the same process of fetching a URL and parse it to collect interesting values to graph .
here the “Frame” of the package with 3 subroutines :
package fbxcfr; ... sub fbxcfr_init { ... sub fbxcfr_update { ... sub fbxcfr_cgi { ...
in order to not forget any replacement occurence of the nginx string, I search and replace every occurence of nginx with fbxcfr I used VI to do that , here's the magic command to search and repalce all in VI
:1,$s/nginx/fbxcfr/g
I change a few lines in the code (a dozen ) and commented many . Indeed the nginx module collect all these :
$reqs:$tot:$reads:$writes:$waits:$in:$out
from these only the 2 last ones (in/out) are of interest to me .
not to confused with the original values/variables I named mine din and dout
here are the main changes I did :
sub fbxcfr_update { ... my $fbxcfr = $config->{fbxcfr}; ... my $in = 0; my $out = 0; my $din = 0; my $dout = 0; my $url; if($fbxcfr->{url}) { $url = $fbxcfr->{url}; } else { $url = "http://192.168.0.254/pub/fbx_info.txt"; #hard coded here but can be set in monitorix.conf module parameters } ... #if(/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)\s*/) { #get line starting with 2 spaces then WAN string and match the 2 digit (\d+) values before string ko/s if(/^\s\sWAN\s+Ok\s+(\d+)\sko\/s\s+(\d+)\sko\/s/) { $din = $1; #print "din: $din\n"; # for debug $dout = $2; #print "dout: $dout\n"; # for debug $din *= 1024; $dout *= 1024; $rrdata .= ":$din:$dout"; RRDs::update($rrd, $rrdata); ... sub fbxcfr_cgi { ... push(@output, " <tr>\n"); push(@output, " <td bgcolor='$colors->{title_bg_color}'>\n"); } # comment out everything related to request , total, reads, writes , wait from the nginx values around line 387 =BEGIN push(@tmp, "AREA:total#44EEEE:Total"); push(@tmp, "GPRINT:total:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:total:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:total:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:total:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:reading#44EE44:Reading"); push(@tmp, "GPRINT:reading:LAST: Current\\: %5.0lf"); ... @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); =END =cut # end comment up until around line 626 (quite long !) # to begin with our In and Out values to graph push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); ... return @output; } 1;
here is the full module file (zunip to get the .pm )