Multi Router Traffic Grapher


Jump to: navigation, search



Tobias Oetiker's MRTG has been used for years by network administrators around the world to produce graphs of network utilization. Although there are more modern tools today that can monitor hundreds of interfaces and a myriad of other attributes, MRTG is still very good for your home router. After all, you probably only have one interface in it.

Note: This application is dependent on SNMP. It will be installed automatically if you skipped the previous guide. It would be better to install it separately first and make sure it works correctly before continuing.


You know the install routine by now. This port has an options screen but simply select OK on it.

# cd /usr/ports/net-mgmt/mrtg
# make
# make install clean
# rehash

You need to create a configuration file and there is a script to help you with that. Don't forget to replace the domain name with your own.

# cfgmaker --ifref=descr --ifdesc=descr > /usr/local/etc/mrtg/mrtg.cfg

You also need to create a working directory for MRTG's files on your webserver so you have someplace you can browse and watch the graphs. It isn't absolutely necessary for this directory to be owned by myweb but make it so anyway.

# mkdir /usr/home/myweb/public_html/
# chown myweb:myweb /usr/home/myweb/public_html/

You need to add that path in the configuration file so open it in the editor and find these lines:

#  for UNIX
# WorkDir: /home/http/mrtg

Remove the comment from the WorkDir line and edit the path to point to the folder you just created.

WorkDir: /usr/home/myweb/public_html/

The configuration generated has sections for every interface on your router, both physical and virtual, but only the physical ones should be uncommented. There are some html code there you can alter to get a nicer output but for now leave it as it is. To have MRTG collect statistics and produce graphs you can add it as a crontab job that runs every five minutes.

*/5 * * * * /usr/local/bin/mrtg /usr/local/etc/mrtg/mrtg.cfg >/dev/null 2>&1

When the script has run for the first time you will find a few html files and images in the webfolder you created and they can be accessed like this:


Note: This section is optional and describes a small addon to MRTG to produce better looking output. You can safely skip this if it gets too complicated.

You probably notice that the output doesn't look exactly as good as what you may have seen on the Internet. MRTG's log format and the way it generates the images every five minutes makes it unfit for very large installations with hundreds of interfaces to monitor. Both these drawbacks are addressed by a small CGI script called 14all.

A CGI script is by tradition a Perl script that is executed by the web server and the output from it is served as HTML code to the client. It's exactly the same principle as with PHP with the difference that the Perl script isn't embedded in the web page's HTML code but exists as a separate file. CGI scripts are traditionally placed in a folder called cgi-bin and Apache comes with such a folder configured by default in /usr/local/www/apache22/cgi-bin. You can use that folder if you want but this guide will show you how to create your own cgi-bin folder within your web structure. You can either create a separate cgi-bin folder for each of your virtual hosts or you can let two or more of them share a common folder with the help of the ScriptAlias directive. This guide will put a common cgi-bin folder in the folder structur of your main web site.

Start by editing /usr/local/etc/apache22/extra/httpd-vhost.conf. Locate the <VirtualHost> section defining your main site and put these lines before the closing </VirtualHost> tag:

ScriptAlias /cgi-bin/ "/usr/home/myweb/public_html/"

<Directory "/usr/home/myweb/public_html/">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all

Don't forget to replace the domain name with that of your own. The CGI folder will be placed outside your web root for security reasons. To have it appear inside your web root, like http://your.domain/cgi-bin/, you need to create an alias that redirects any attempt to access that folder to its real physical location instead. ScriptAlias will do this for you and is a variant of the Alias directive that works in the same way with the difference that it executes the files in the folder instead of serving them directly as web pages. The <Directory> directive must be added to give Apache permission to access the files since this is a folder that is placed outside the web root where you don't have any Apache permissions defined at this point.

To continue, you'll need to install rrdtool which will do the logging and graph generation for you. This port will pull in an extensive set of dependencies. As usual you can leave the settings on the option page at its default values.

# cd /usr/ports/databases/rrdtool
# make
# make install clean

You will also need a small utility called wget. Default options are fine.

# cd /usr/ports/ftp/wget
# make
# make install clean
# rehash

Now you can create that folder and you do it as the myweb user to get the file permissions correct from the start. You'll have to perform a number of tasks as myweb so don't switch back to root until instructed to do so.

[myweb]$ mkdir /usr/home/myweb/public_html/

Enter that folder and download the CGI script directly from the developer's web site.

[myweb]$ cd /usr/home/myweb/public_html/
[myweb]$ wget

The script has to be edited in a few places to work correctly but instead of guiding you from line to line, let's introduce another Unix concept called diff files. A diff file is a small text file containing the lines that have to be changed. It's also so cleverly crafted that it can automatically locate both the file you need to patch and the lines within it that needs patching. It's routinely used in code development. Copy the contents below and paste it into a new file in the cgi-bin folder and call it 14all.diff.

Note: The diffs below are valid at the time I write this tutorial. If a future upgrade of any component changes anything it would probably be the paths to and defined in the first half of the diff file. It's a good idea to check that those files actually exist in those folders before continuing.
--- 14all-1.1.txt       2003-01-05 19:50:37.000000000 +0100
+++ 14all.cgi   2008-08-16 12:55:58.000000000 +0200
@@ -11,12 +11,12 @@
 # if (from mrtg) is not in the module search path (@INC)
 # uncomment the following line and change the path appropriatly:
-use lib qw(/usr/local/mrtg-2/lib/mrtg2);
+use lib qw(/usr/local/lib/perl5/site_perl/5.8.8);
 # if RRDs (rrdtool perl module) is not in the module search path (@INC)
 # uncomment the following line and change the path appropriatly
 # or use a LibAdd: setting in the config file
-#use lib qw(/usr/local/rrdtool-1.0.38/lib/perl);
+use lib qw(/usr/local/lib/perl5/site_perl/5.8.8/mach);
 # RCS History - removed as it's available on the web
@@ -60,7 +60,7 @@
 #$cfgfile = 'mrtg.cfg';
 # use this so 14all.cgi gets the cfgfile name from the script name 
 # (14all.cgi -> 14all.cfg)
-$cfgfile = '';
+$cfgfile = '/usr/local/etc/mrtg/mrtg.cfg';
 # if you want to store your config files in a different place than your cgis:
 $cfgfiledir = '';
@@ -108,13 +108,13 @@
     <TD WIDTH=63><A ALT="MRTG"
-    BORDER=0 SRC="##ICONDIR##mrtg-l.gif"></A></TD>
+    BORDER=0 SRC="##ICONDIR##mrtg-l.png"></A></TD>
     <TD WIDTH=25><A ALT=""
-    BORDER=0 SRC="##ICONDIR##mrtg-m.gif"></A></TD>
+    BORDER=0 SRC="##ICONDIR##mrtg-m.png"></A></TD>
     <TD WIDTH=388><A ALT=""
-    BORDER=0 SRC="##ICONDIR##mrtg-r.gif"></A></TD>
+    BORDER=0 SRC="##ICONDIR##mrtg-r.png"></A></TD>

When the file is saved you can perform the actual patching.

[myweb]$ patch <14all.diff
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
|--- 14all-1.1.txt	2003-01-05 19:50:37.000000000 +0100
|+++ 14all.cgi	2008-08-16 12:55:58.000000000 +0200
Patching file 14all-1.1.txt using Plan A...
Hunk #1 succeeded at 11.
Hunk #2 succeeded at 60.
Hunk #3 succeeded at 108.

If no errors are reported you can rename the script and delete the obsolete files. You also have to make the script executable.

[myweb]$ mv 14all-1.1.txt 14all.cgi
[myweb]$ rm 14all.diff 14all-1.1.txt.orig
[myweb]$ chmod o+x 14all.cgi

Now you can switch back again to root and edit your MRTG configuration file /usr/local/etc/mrtg/mrtg.cfg. You need to add an option here to make it work with the cgi script and rrdtool. On second thought, the original configuration file is extremely bloated so let's strip out all the HTML and comments and only put what's absolutely necessary in there. It will be so much easier to deal with after that. So, delete every row in there and replace it with this:

WorkDir: /usr/home/myweb/public_html/
Options[_]: growright, bits
EnableIPv6: no
LogFormat: rrdtool
IconDir: /mrtg/
PathAdd: /usr/local/bin/
Interval: 5
14all*Columns: 1
14all*GraphErrorsToBrowser: 1
14all*IndexGraphSize[_]: 300 100

Target[em0]: \em0:public@localhost:
MaxBytes[em0]: 125000000
Title[em0]: Internal gigabit connection
XSize[em0]: 600
YSize[em0]: 200

Target[em1]: \em1:public@localhost:
MaxBytes1[em1]: 2500000
MaxBytes2[em1]: 250000
Title[em1]: External DSL connection
XSize[em1]: 600
YSize[em1]: 200

A few explanations:

  • LogFormat: rrdtool is the option to integrate MRTG with the cgi-script.
  • Every reference to em0 and em1 has to be adjusted to your own interface names, as well as the titles of course.
  • MaxBytes defines the maximum bandwidth of the interface in decimal bytes. Your DSL/cable connection most likely has different upload and download bandwidth and this can be defined with MaxBytes1 and MaxBytes2.
  • The size of the graphs are also increased so they'll be easier to read.

Before you try to access your new graphs you have to restart Apache to apply the virtual host changes.

# /usr/local/etc/rc.d/apache22 restart

Now you can access the index page and from there click on any of the interfaces to see more details.


  • /usr/local/etc/mrtg/mrtg.cfg is the configuration file for MRTG.

Unresolved issues

MRTG can run as a daemon with the credentials of the user mrtg instead of as root from the crontab. But as mrtg it doesn't have write access to the folder you created since it's owned by myweb. It's possible to change the user MRTG runs as with some rc-variables but if you change it to myweb it can't create a pid-file in /var/run/mrtg since that folder is created by the installation as owned my mrtg. A bug perhaps? Of course you can configure another virtual host in mrtg's home folder but it seems a little overkill for this simple task.


Personal tools