26 Nov 2009

Network monitoring with MRTG

If you work with any kind of networks, the chances are you've heard of, or even used, MRTG. There are not active development of MRTG today, but bugfix patches are still being added now and then.

So why are we still using it? MRTG just works. It stable and robust. And it does what it is supposed to do and nothing else. This makes MRTG still king of monitoring network equipment over SNMP. Well, that is, until Munin 1.4 is released in a couple of days. Munin 1.4 have (better) SNMP support - they are aiming at MRTG.

So until Munin 1.4 is released and stabilizes, I'll use MRTG in production. I've added some minor wrappers around MRTG so that adding and removing nodes gets dead easy. This way, other people can add/remove equipments without knowing too much about MRTG.

Every Linux distribution out there have MRTG in their repository. If yours don't, change distribution or compile MRTG yourself.

1. First of all, we add all our network equipment in a text file:

  $ cat /etc/mrtg/network.cfg
  #
  # SNMP capable switches goes here
  #
  # After adding hosts here, run
  #
  #   /etc/mrtg/mrtgmaker.sh
  #   /etc/mrtg/indexer.sh
  #
  # Format (community is optional) and override default
  #
  # [community]@IP description
  #
  # Example:
  # 192.168.1.1 Core Network Router 1 (Location A)
  # secret@10.0.0.1 Core Network Router 2 (Location B)
  10.1.1.1 Cisco 6500 08/09 Core Network Router 1
  192.168.1.1 Cisco 4948 09/09

2. I create a small script that reads the network equipment from the text-file and generate mrtg.cfg:

  $ cat /etc/mrtg/mrtgmaker.sh
  #!/bin/bash
  #
  # This should be run every time you add a SNMP capable
  # switch under /etc/mrtg/network.cfg
  #
 
  [ -r /etc/mrtg/network.cfg ] || exit 1
 
  ALL=""
 
  while read switch
  do
     if `echo $switch | grep -q ^#` || `echo $switch | grep -q "^$"`; then
        continue
     fi
     HOST=`echo $switch | awk ' { print $1 }'`
     ALL="$ALL $HOST"
 
  done < /etc/mrtg/network.cfg
 
  echo "Harvesting SNMP info from $ALL"
 
  /usr/bin/cfgmaker --snmp-options=:::::2 --show-op-down --global 'AddHead[_]: ' --global 'Options[_]: growright, bits' --global 'HtmlDir: /var/www/html/mrtg' --global 'ImageDir: /var/www/html/mrtg' --global 'LogDir: /var/lib/mrtg' --global 'ThreshDir: /var/lib/mrtg' --community=SECRET --output=/etc/mrtg/mrtg.cfg --subdirs=HOSTNAME $ALL
 
  echo "Config file: /etc/mrtg/mrtg.cfg"
  echo "You should now run /etc/mrtg/indexer.sh"

3. Then we need to add a script to update the HTML

$ cat /etc/mrtg/indexer.sh
#!/bin/bash
#
# This should be run every time you add a SNMP capable
# switch under /etc/mrtg/network.cfg
#

echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>MRTG @ Company Name</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<meta http-equiv="Refresh" content="300">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<meta name="robots" content="noarchive">
<link href="favicon.ico" rel="shortcut icon">
<link rel="stylesheet" type="text/css" href="mrtg.css">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1>MRTG @ Company Name</h1>
<img src="company_logo.png" height="135" width="130" align="right" alt="Company Name logo"/>
<blockquote>
' > /var/www/html/mrtg/index.html

while read switch
do
if `echo $switch | grep -q ^#` || `echo $switch | grep -q "^$"`; then
continue
fi

IP=$(echo $switch | cut -d" " -f1)
IP=${IP#*@}
DESC=$(echo $switch | cut -d" " -f2-40)
DATE=$(date)
DNSNAME=$(dig +short -x $IP 2> /dev/null)

echo "Indexing $IP"
/usr/bin/indexmaker --nolegend --subtitle='<h2><a href="../">Back home</a></h2>' \
--pageend="<em>MRTG @ Company Name - generated on $HOSTNAME</em>" \
--addhead='<link rel="stylesheet" type="text/css" href="/mrtg.css">' \
--output /var/www/html/mrtg/$IP.html --filter name=~$IP \
--title="Network utilitization for $DNSNAME ($IP)" /etc/mrtg/mrtg.cfg

if [ -z $DNSNAME ]
then
echo "<font size="+1">⇒ <a href="$IP.html">$IP</a> — $DESC</font> <br>" >> /var/www/html/mrtg/index.html
else
echo "<font size="+1">⇒ <a href="$IP.html">$IP</a>, $DNSNAME — $DESC</font> <br>" >> /var/www/html/mrtg/index.html
fi

done < /etc/mrtg/network.cfg

echo "
</blockquote>
<p>MRTG is also used as datasource for our Network Weathermap — <a href="http://weathermap/">http://weathermap</a>
<hr>
<em><font size=\"-1\">More info: <a href=\"http://wiki/mediawiki/index.php/MRTG\">
http://wiki/mediawiki/index.php/MRTG</a></font><br></em>
<em><font size=\"-1\">Generated by $HOSTNAME:$0</font></em>
</body>
</html>" >> /var/www/html/mrtg/index.html



4. We add a stylesheet to make thing a little prettier:

  $ cat /var/www/html/mrtg/mrtg.css
  body {
    background-color: #EFEFEF;
    color: #000000;
    font-family: sans-serif;
    font-size: 12px;
  }
 
  h1 {
    background-color: #CCCCCC;
    font-family: sans-serif;
    font-size: 18px;
    font-weight: bold;
  }
 
  h2 {
    font-family: sans-serif;
    font-size: 16px;
    font-weight: bold;
  }
 
  a {
    text-decoration: none;
  }

5. We test:

  # /etc/mrtg/mrtgmaker.sh
  Harvesting SNMP info from 10.1.1.1 192.168.1.1
  Config file: /etc/mrtg/mrtg.cfg
  You should now run /etc/mrtg/indexer.sh
  # /etc/mrtg/indexer.sh
  Indexing 10.1.1.1
  Indexing 192.168.1.1

We are then presented with an overview page then takes us to each switch/router: