Perl Development [ Home | Projects | Modules | Links | THINK | SETI | Cam | Car | AutoX | Photography | About ]

Ethernet Utilization
DATE: 10.29.2001
TYPE: SNMP Ethernet

The application was created to monitor and graph ethernet usage on network devices.

Using the Net::SNMP and GD::Graph modules, I run this utility on a schedule from 08:00-17:00 every day. It uses "runs" to gather ethernet utilization over 5 minute intervals with 10 a second sample pause. At the end of the day, it parses that data and creates a daily graph for display.

After a week's worth of data has been compiled, I run the program to munge the log files created during the week to create an overview of the same time table (08:00-17:00) for the entire week.

Sample Graph & Data

As you can see below, there is a table with data as well as the graph created each day. The table gives you information on the host, as well as avg/min/max data for that specific day. Below that is the graph with Incoming/Outgoing data plotted on the y-axis, and times show on the x-axis.

With each days graphed data there is also a log file created. This allows me to go back and munge larger data sets for a better scope. Right now I am doing weekly graphing on the daily logs, and I will move on to monthly and yearly when I have enough data.

Here is a snippet of info from the log file:

    Begin data collection for - Runs: 108
    Starting run 1\108 - In: 0.03 Out: 0.00 Time: 8:00
    Starting run 2\108 - In: 0.14 Out: 0.09 Time: 8:05
    Starting run 3\108 - In: 0.01 Out: 0.00 Time: 8:10
    [ .. ]
    Starting run 106\108 - In: 0.11 Out: 0.10 Time: 16:45
    Starting run 107\108 - In: 1.92 Out: 1.13 Time: 16:50
    Starting run 108\108 - In: 0.72 Out: 0.41 Time: 16:55
    Utilization Graph Completed - Run length: 9 hours
    Generation complete.

Here is a code snippet that shows you how each run is handled:

    for ($run = 1; $run <= $numRuns; $run++) {
    	print LOG "Starting run $run\\$numRuns - ";
    	unless ($run == $numRuns) { sleep("$pauseTime"); }
    sub snmpRun {
    	# get snmpdata run 1
    	# get snmpdata run 2
    	# run calculation and then
    	# push results into our arrays
    	# for the graph later	

Each snmpdata run collects current ifInOctets and ifOutOctets of the device you are querying. Then it does a simple calculation to figure out the utilization % at the current time.

    Delta(OctetType) * 8
    ---> OctetType Utilization
    Delta(SysUpTime) * ifSpeed

Basically you grab the difference in your OctetType, multiply by 8 to turn into bytes, then divide by the time difference multiplied by your interface speed (in bytes) to get your current utilization %.

Output & Viewing

On the first day of the week a folder is created in the current directory (wherever it is) named the current week in this format: MMDDYYYY. I use Monday as the start of the week, and it will create a directory if the current day is Monday. Here is a code snippet that handles it:

    if ($day < 10) { $day = "0$day"; }
    if ($wday eq "Mon") {
        $folderName = "$months{$mon}$day$year";
        unless (-d $folderName) {
    	        mkdir("$folderName", 0777) || die "Cannot make directory: ($!)\n";
    } else {
        foreach (<*>) { if (-d $_ && $_ =~ /\d+/) { push(@dirs, $_); }  }
        my @sortedDirs = sort { $a <=> $b } @dirs;
        $folderName = pop(@sortedDirs);

And as you can see it will check to see which "week" (by folder numeric value) is the newest folder to store files in. Once this has been established, each day of that week will be put into the proper folder. After the graph has been created, the SHTML file links to the image and writes the table data (avg's, max's etc).

After the last run on Friday, the is run. This runs through each log (log-$day.txt) file in the newest directory (see code snippet above) and creates a graph based on the 5 day average for each run. It also creates an SHTML page which links to each individual day of that week. Once this is finished I use a simple ftp script to send the files to my webserver.

Weekly Summary
    Host: (
    Run time: Fri Dec 7 17:00:33 2001
    System Uptime: 11 days, 05:35:57.50
    Received Average: 0.81 %
    Outgoing Average: 3.71 %

    Daily Usage Graphs:
    12032001 Monday Tuesday Wednesday Thursday Friday
    Incoming: --------- Outgoing: ---------

Below is a code snippet showing how each day is added together and then divided by timeframe (5 - days Mon-Fri).

    sub addValues {
    	@utilizationRecTotal = map { 
    		$utilRecMon[$_] + $utilRecTue[$_] + $utilRecWed[$_] + $utilRecThu[$_] + $utilRecFri[$_] 
    	} (0..107);
    	@utilizationOutTotal = map {
    		$utilOutMon[$_] + $utilOutTue[$_] + $utilOutWed[$_] + $utilOutThu[$_] + $utilOutFri[$_]
    	} (0..107);
    	foreach (@utilizationRecTotal) {
    		$utilizationRec[$recNumber] = $_ / 5;
    	foreach (@utilizationOutTotal) {
    		$utilizationOut[$outNumber] = $_ / 5;

Modified: Friday, 31-May-2002 16:42:32 CDT -