Setting up traffic monitoring using rrdtool (and snmp)

From Alpine Linux

Install programs

Install rrdtool

apk_add rrdtool

Create a rrd-database

The creation of the database is dependent on how many DataSources (DS) you have, and what type of DataSources you use.
In this example, we monitor eth0 and eth1 (RX and TX) on this local machine, and fetch (eth0 and eth1) information from another computer through snmp.

rrdtool create /root/exampledb.rrd \
--step 30 \
DS:pc1eth0rx:COUNTER:120:0:U \
DS:pc1eth0tx:COUNTER:120:0:U \
DS:pc1eth1rx:COUNTER:120:0:U \
DS:pc1eth1tx:COUNTER:120:0:U \
DS:pc2eth0rx:COUNTER:120:0:U \
DS:pc2eth0tx:COUNTER:120:0:U \
DS:pc2eth1rx:COUNTER:120:0:U \
DS:pc2eth1tx:COUNTER:120:0:U \
RRA:AVERAGE:0.5:1:3600 \
RRA:MAX:0.5:1:3600

This creates a Round Robin Database (RRD) called exampledb.rrd.

  • "--step 30" specifies the base interval in seconds with which data will be fed into the RRD.
  • The first "DS..." row assigns a name "pc1eth0rx".
  • "COUNTER" is for continuous incrementing counters like the ifInOctets counter in a router. The rest in the DS-row, I hopefully come back to later.
  • "RRA" is a RoundRobinArcive. Its tores information from the DataSource (DS) in various ways.
  • "RRA:AVARAGE..." will present a average value of (average for each second) and keep values for 3600 seconds (older than 3600 seconds will be overwritten).
  • "RRA:MAX" calulates the maximum value.

Gather information and put it in the RRD

Gathering data can be done in various ways and from various systems.
In our example we collect data from 2 different computers, each computer has eth0 and eth1 that we would like to monitor.

Feeding the database with information

Now we create a new script that starts by fetching the local information and then fetches snmp information from the next computer and then puts it all in the database.

Lets call the script /root/collect_data.sh.

#!/bin/sh
while true; do
sleep 30
ETH0=$(grep eth0 /proc/net/dev)
E0DOWN=$(echo $ETH0|tr \: \ |awk '{print $2}')
E0UP=$(echo $ETH0|tr \: \ |awk '{print $10}')
ETH1=$(grep eth1 /proc/net/dev)
E1DOWN=$(echo $ETH1|tr \: \ |awk '{print $2}')
E1UP=$(echo $ETH1|tr \: \ |awk '{print $10}')
rrdupdate /root/exampledb.rrd N:\
${E0DOWN}:${E0UP}:${E1DOWN}:${E1UP}:\
`/usr/bin/snmpget -v 1 -c general -Oqv 192.168.0.2 IF-MIB::ifInOctets.2`:\
`/usr/bin/snmpget -v 1 -c general -Oqv 192.168.0.2 IF-MIB::ifOutOctets.2`:\
`/usr/bin/snmpget -v 1 -c general -Oqv 192.168.0.2 IF-MIB::ifInOctets.3`:\
`/usr/bin/snmpget -v 1 -c general -Oqv 192.168.0.2 IF-MIB::ifOutOctets.3`:\
done

For this to work, you need to have a configured snmpd running on the 192.168.0.2 computer. The community-name 'general' might be different for you, depending on your snmp configuration.

Present the information in graphs

Now starts the fun part. We will display the gathered information.
The information can be presented in various ways (we will use LINE-graph).

rrdtool graph /root/result.png --start -1800  \
-a PNG -t "Network Interfaces" --vertical-label "bits/s" \
-w 1260 -h 800 -r \
DEF:pc1eth0rx=/root/exampledb.rrd:pc1eth0rx:AVERAGE \
DEF:pc1eth0tx=/root/exampledb.rrd:pc1eth0tx:AVERAGE \
DEF:pc1eth1rx=/root/exampledb.rrd:pc1eth1rx:AVERAGE \
DEF:pc1eth1tx=/root/exampledb.rrd:pc1eth1tx:AVERAGE \
DEF:pc2eth0rx=/root/exampledb.rrd:pc2eth0rx:AVERAGE \
DEF:pc2eth0tx=/root/exampledb.rrd:pc2eth0tx:AVERAGE \
DEF:pc2eth1rx=/root/exampledb.rrd:pc2eth1rx:AVERAGE \
DEF:pc2eth1tx=/root/exampledb.rrd:pc2eth1tx:AVERAGE \
CDEF:pc1eth0rxb=pc1eth0rx,8,\* \
CDEF:pc1eth0txb=pc1eth0tx,-8,\* \
CDEF:pc1eth1rxb=pc1eth1rx,8,\* \
CDEF:pc1eth1txb=pc1eth1tx,-8,\* \
CDEF:pc2eth0rxb=pc2eth0rx,8,\* \
CDEF:pc2eth0txb=pc2eth0tx,-8,\* \
CDEF:pc2eth1rxb=pc2eth1rx,8,\* \
CDEF:pc2eth1txb=pc2eth1tx,-8,\* \
AREA:pc1eth0rxb#D7CC00:PC1_EHT0-RX \
AREA:pc1eth0txb#D7CC00:PC1_EHT0-TX \
LINE2:pc1eth1rxb#D73600:PC1_EHT1-RX \
LINE2:pc1eth1txb#D73600:PC1_EHT1-TX \
LINE2:pc2eth0rxb#0101D6:PC2_EHT0-RX \
LINE2:pc2eth0txb#0101D6:PC2_EHT0-TX \
LINE2:pc2eth1rxb#00D730:PC2_EHT1-RX \
LINE2:pc2eth1txb#00D730:PC2_EHT1-TX
  • First define name of output and the time-span (we could also have definesd "--end").
  • We output some headers and Y-axis information.
  • Next we define the size of the png.
  • "DEF..." gets the information from the database.
  • "CDEF..." recalculates the original information (in our case we want to presnet bits instead of bytes).
  • "AREA..." displays a area-graph on the output.
  • "LINE2..." (or "LINE") writes a line-graph.
  • In the color settings, you could enter opacity at the end. "LINE3...#FF00007F" would have displayed a 3 pixel red line with approx. 50% opacity.

Save settings

Don't forget to save all your settings

lbu ci floppy