Selfnet Blog

Feb 08, 2015

Graphing interface errors with M R T G

If you ever want to graph interface errors with MRTG you'll find a few posts on mrtg related mailing lists, however none of them seemed to work with our installation of MRTG. There is no native support in MRTG but you can specify a template for interfaces via the experimental --if-template flag. The following code is based on an example by Tobias Oetiker, I have merely added support for multiple OIDs via a for loop. The code is ugly, but it works.

There is one kink to be aware of though: Since there is not always an evenly matched set of ifIN/ifOUT OIDs I've decided to graph all OIDs on their own. This is achieved by setting

1
Options[$target]: noo

for each OID and by that making sure that MRTG doesn't render 'outgoing' data.

To configure the template you have to fill the 3 arrays special_oid_name, special_oid and special_oid_desc according to your needs, I have included some example OIDs below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Author: Tobias Oetiker <tobi@oetiker.ch>  
# Date: 2006-09-06  
# Purpose: Add an Error graph for each Traffic Graph  
# 02/07/2015: add juniper interface errors / Hannes Rist  
# i am soooo sorry for this  
# see http://www.oidview.com/mibs/2636/JUNIPER-IF-MIB.html  
my @special_oid_name = ('ifJnxInFrameErrors', 'ifJnxInQDrops','ifJnxInRunts');
my @special_oid = ('1.3.6.1.4.1.2636.3.3.1.1.10','1.3.6.1.4.1.2636.3.3.1.1.11','1.3.6.1.4.1.2636.3.3.1.1.12');
my @special_oid_desc = ('Framing Errors: The number of input packets which were misaligned.','Drops: The number of packets dropped by the input queue ofthe I/O Manager ASIC.','Runts: Frames received that are smaller than the runt threshold.');
#$target_lines = $default_target_lines."\n";
for (my $i = 0; $i < @special_oid_name; $i++) {
 my $el = $default_target_lines;
 $el =~ s/^(Target\S+:\s+).+/${1}$special_oid[$i]$if_ref&$special_oid[$i]$if_ref:$router_connect/m; # Error Target
 $el =~ s/^([^\s\]]+)/${1}.$special_oid_name[$i]/gm; # Filename for error log and graphs
 $el =~ s|</h1>| - $special_oid_name[$i]</h1><span style="color: white; background-color: black;">$special_oid_desc[$i]</span><br />|i;
 $el =~ s|^(Title\[.+)|$1 - $special_oid_name[$i]|mi;
 $el =~ s/Traffic/$special_oid_name[$i]/;
 $el =~ s/^(MaxBytes)(\S+)\s+\d+/$1$2 10000/m;  # more than 10'000 errors a second are BIG trouble anyway
 $el .= <<LEGEND;
YLegend$2 $special_oid_name[$i] per Minute
ShortLegend$2 e/min
Legend1$2 $special_oid_name[$i] per Minute
Legend3$2 Maximal 5 Minute $special_oid_name[$i]
LegendI$2 &nbsp;$special_oid_name[$i]:
Options$2 perminute,noo
LEGEND

  if (oid_pick($router_connect,$v3opt,"$special_oid[$i].$if_index")){
        $target_lines .= $el;
  }
  $target_lines =~ s{<tr>\s+<td>(.+?)</td>\s+<td>(.+?)</td>\s*</tr>}{<tr><td>$1</td>\t<td>$2</td></tr>}g;

}

If you want to use it the template has to be passed as an argument to cfgmaker like so (Line 13):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/usr/bin/cfgmaker \
    --global 'workdir: /var/www/mrtg-rrd' \
    --global 'Forks: 5' \
    --global 'LogFormat: rrdtool' \
    --global 'Options[_]: bits' \
    --global 'WithPeak[_]: ymw' \
    --no-down \
    --show-op-down \
    --ifref=name \
    --ifdesc=alias \
    --enable-ipv6 \
    --if-filter="$default && !($if_type ~~ [1, 53, 131])" \
    --if-template=if_errors.tmpl \
    public@$device:::::2 \
    >> $device_err.cfg

After that running MRTG with $device_err.cfg will create graphs like this one:

Picture of RRDTOOL Graph

I hope this article is of some help and spares you of many hours searching the web.