Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Ethernet Utilization

by djw (Vicar)
on Oct 24, 2001 at 00:26 UTC ( [id://120895]=sourcecode: print w/replies, xml ) Need Help??
Category: Networking Code
Author/Contact Info djw
Description: SNMP query tool for reporting interface utilization stats. Does a get_request for sysUpTime, ifInOctets, and ifOutOctets and does a utilization calculation based on the difference of two samples and interface speed. Right now its setup to run every 5 minutes for an 8am-5pm workday.

You can see a sample of the graph plotted by GD::Graph here: http://perldev.org/projects/snmp/

Thanks, djw

UPDATE:
If you plan on using this, you will have to check your ethernet device's MIB OID. ifInOctets and ifOutOctets are the first two items in the @oids list, the last one is system uptime which you shouldn't have to change.
#!/usr/bin/perl -w
use strict;

use Net::SNMP qw(ticks_to_time);
use GD::Graph::lines;
use GD::Graph::colour;

use constant HOUR_IN_SECS => 3600;

my ($session, $error, $response, $run, $time, $upTime);
my (@utilizationRec, @utilizationOut, @runTimes);
my ($octetOutUtil, $octetInUtil, @timeSamples);

# Change these to match your needs
# --------------------------------------------

my $host      = "IP_ADDRESS";        # The host we want to monitor
my $hostname  = "SERVERNAME";        # its fancy netbios name
my $community = "public";        # The community name to read from
my $ifSpeed   = "IFSPEED";        # The speed of your interface

my $numRuns   = 108;            # +$pauseTime+$sleepTime dictates runt
+ime length
my $pauseTime = 290;            # 5 minutes - total right now is set t
+o one day    
my $sleepTime = 10;            # from 8am to 5pm

my $htmlFile  = "utilization.shtml";
my $runTime   = localtime;
my $runLength = ($pauseTime + $sleepTime) * $numRuns / HOUR_IN_SECS;

my $value     = 0;
my $recMax    = 0;
my $outMax    = 0;
my $outTotal  = 0;
my $recTotal  = 0;
my $recAvg    = 0;
my $outAvg    = 0;

# These are our specific SNMP OID's for 
# querying in and out octets and uptime
# --------------------------------------------

my @oids = ('1.3.6.1.2.1.2.2.1.10.16777219', '1.3.6.1.2.1.2.2.1.16.167
+77219', '1.3.6.1.2.1.1.3.0');

# This runs our SNMP get request so that I can
# populate our data for the graphs - calls the
# snmpRun() sub.
# --------------------------------------------

print "Begin data collection for $host - Runs: $numRuns\n";

for ($run = 1; $run <= $numRuns; $run++) {
    print "Starting run $run\\$numRuns - ";
    snmpRun();
    unless ($run == $numRuns) { sleep("$pauseTime"); }
}


# Now that our data is nicely entered into
# our arrays, we can plot our graphs out
# -------------------------------------------

createUtilGraph();
getAvgs();
upTime();
writeHTML();


sub snmpRun {
    # get the time

    use Time::localtime;
    my $tm = localtime;
    my ($hour, $min) = ($tm->hour, $tm->min);
    if ($min =~ /^\d$/) {
        $min = "0$min";
        $time = "$hour:$min";
    } else {
        $time = "$hour:$min";
    }


    # Run number 1
    # --------------------------------------

    ($session, $error) = Net::SNMP->session(
       -hostname    =>    $host,
       -community    =>    $community,
       -port    =>    161,
       -version    =>    "2c",
       -translate    =>    [ -timeticks => 0x0 ],
    );
    $session or die "Session error: $error\n";

    $response = $session->get_request(@oids);
    $response or die "Response error:" . "$session->error()" . "\n";

    $session->hostname();

    my $bytesIn   = $response->{'1.3.6.1.2.1.2.2.1.10.16777219'};
    my $bytesOut  = $response->{'1.3.6.1.2.1.2.2.1.16.16777219'};
    my $sysUpTime = $response->{'1.3.6.1.2.1.1.3.0'};
    
    $session->close();

    # Sleep till we go for the next run
    # --------------------------------------
    
    sleep("$sleepTime");

    # Run number 2
    # --------------------------------------

    ($session, $error) = Net::SNMP->session(
       -hostname    =>    $host,
       -community    =>    $community,
       -port    =>    161,
       -version    =>    "2c",
       -translate    =>    [ -timeticks => 0x0 ],
    );
    $session or die "Session error: $error\n";

    $response = $session->get_request(@oids);
    $response or die "Response error:" . "$session->error()" . "\n";

    $session->hostname();

    my $bytesIn2   = $response->{'1.3.6.1.2.1.2.2.1.10.16777219'};
    my $bytesOut2  = $response->{'1.3.6.1.2.1.2.2.1.16.16777219'};
    my $sysUpTime2 = $response->{'1.3.6.1.2.1.1.3.0'};
    
    $session->close();

    # Data is collected, now do our calculation
    # Delta(octetType) * 8
    # --- => octetType Utilization
    # Delta(sysUpTime)*10000
    # -----------------------------------------
    
    my $bytesInDiff   = $bytesIn2   - $bytesIn;
    my $bytesOutDiff  = $bytesOut2  - $bytesOut;
    my $sysUpTimeDiff = $sysUpTime2 - $sysUpTime;
    
    if ($bytesInDiff == 0) {
        $octetInUtil = "0.00";
    } else {
        my $octetInTemp  = ($bytesInDiff  * 8) / ($sysUpTimeDiff * $if
+Speed);
        $octetInTemp  =~ /(\d+)\.(\d\d)/;
        $octetInUtil = "$1.$2";
    }
    
    if ($bytesOutDiff == 0) {
        my $octetOutUtil = "0.00";
    } else {
        my $octetOutTemp = ($bytesOutDiff * 8) / ($sysUpTimeDiff * $if
+Speed);
        $octetOutTemp =~ /(\d+)\.(\d\d)/;
        $octetOutUtil = "$1.$2";
    }

    print "In: $octetInUtil Out: $octetOutUtil Time: $time\n";

    push( @utilizationRec, $octetInUtil );        # Push the data into
+ our
    push( @utilizationOut, $octetOutUtil);        # arrays for use in 
+our graphs
    push( @timeSamples, $time);            # Push the time from the ru
+n
}


sub createUtilGraph {
    my @outData = ( [ (@timeSamples) ], [ (@utilizationOut) ] );
    my @recData = ( [ (@timeSamples) ], [ (@utilizationRec) ] );
    
    my $graph = GD::Graph::lines->new(650,200);

    $graph->set(
        r_margin    =>    '4',
        title        =>    'Ethernet Utilization',
        x_label        =>    'Time (5 minute intervals with a 10 secon
+d sample pause)',
        y_label        =>    'Utilization %',
        x_label_skip    =>    '12',
        tick_length    =>    '-4',
        y_max_value    =>    '100',
        y_min_value    =>    '0',
        transparent    =>    '1',
        interlaced    =>    '1',
        valuesclr    =>    'black',
        bgclr        =>    'white',
        fgclr        =>    'black',
        accentclr    =>    'black',
        shadowclr    =>    'dgreen',
        labelclr    =>    'black',
        axislabelclr    =>    'black',
        textclr        =>    'black',
        dclrs        =>    [ qw(green) ],
    );

    my $gd = $graph->plot( \@outData );
    
    $graph->set( dclrs => [ qw(red) ] );
    
    $gd = $graph->plot( \@recData );
    
    open(IMG, "+>UtilData.png") || die "Can't create object: ($!)\n";
    binmode IMG;
    print IMG $gd->png;
    close(IMG);
    print "Utilization Graph Completed - Run length: $runLength hours\
+n";
}


sub getAvgs {

    # Here we figure out some avg's and peaks
    # from our collected octet data
    # -------------------------------------------

    foreach $value (@utilizationRec) { 
        if ($value > $recMax) { 
            $recMax = $value; 
        }
        $recTotal += $value;    
    }

    foreach $value (@utilizationOut) { 
        if ($value > $outMax) { 
            $outMax = $value; 
        }
        $outTotal += $value;
    }

    my $recAvgTemp = $recTotal / $numRuns;
    my $outAvgTemp = $outTotal / $numRuns;

    $recAvgTemp =~ /(\d+)\.(\d\d)/;
    $recAvg = "$1.$2";

    $outAvgTemp =~ /(\d+)\.(\d\d)/;
    $outAvg = "$1.$2";

}

sub upTime {
    ($session, $error) = Net::SNMP->session(
            -hostname    =>    $host,
            -community    =>    $community,
            -port        =>    161,
    );
    $session or die "Session error: $error\n";

    my $sysUpTime = '1.3.6.1.2.1.1.3.0';

    $response = $session->get_request($sysUpTime);
    $response or die "Response error:" . $session->error() . "\n";
    $session->hostname();
    $upTime = $response->{$sysUpTime};
    $session->close();
}

sub writeHTML {
    open(HTML, "+>$htmlFile") || die "Can't open file $htmlFile: ($!)\
+n";
    print HTML "<!--#include virtual=\"header.shtml\"-->\n";
    
    print HTML "<table border=\"0\" width=\"300\" cellspacing=\"2\">\n
+";
    print HTML "<tr><td class=\"framed\"><small>\n";
    print HTML "<table border=\"0\" cellpadding=\"0\" width=\"300\">\n
+";
    
    print HTML "<tr>\n";
    print HTML "<td align=\"right\"><small>Host:</small></td>\n";
    print HTML "<td align=\"right\"><b><small><b>$hostname ($host)</b>
+</small></b></td>\n";
    print HTML "</tr>\n";
    print HTML "<tr>\n";
    print HTML "<td align=\"right\"><small>Last run time:</small></td>
+\n";
    print HTML "<td align=\"right\"><small><b>$runTime</b></small></td
+>\n";
    print HTML "</tr>\n";
    print HTML "<tr>\n";
    print HTML "<td align=\"right\"><small>System Uptime:</small></td>
+\n";
    print HTML "<td align=\"right\"><small><b>$upTime</b></small></td>
+\n";
    print HTML "</tr>\n";    
    print HTML "<tr>\n";
    print HTML "<td align=\"right\"><small>Received Max:</small></td>\
+n";
    print HTML "<td align=\"right\"><small><b>$recMax %</b></small></t
+d>\n";
    print HTML "</tr>";
    print HTML "<tr>\n";
    print HTML "<td align=\"right\"><small>Outgoing Max:</small></td>\
+n";
    print HTML "<td align=\"right\"><small><b>$outMax %</b></small></t
+d>\n";
    print HTML "</tr>";
    print HTML "<tr>\n";
    print HTML "<td align=\"right\"><small>Received Average:</small></
+td>\n";
    print HTML "<td align=\"right\"><small><b>$recAvg %</b></small></t
+d>\n";
    print HTML "</tr>";
    print HTML "<tr>\n";
    print HTML "<td align=\"right\"><small>Outgoing Average:</small></
+td>\n";
    print HTML "<td align=\"right\"><small><b>$outAvg %</b></small></t
+d>\n";
    print HTML "</tr>";
    
    print HTML "</table>\n";
    print HTML "</small></td></tr></table><br>\n";
    
    print HTML "<small>Incoming: <font color=\"red\"><b>Red</b></font>
+</small><br>\n";
    print HTML "<small>Outgoing:</smal><font color=\"green\"><b>Green<
+/b></font></small>\n";
    print HTML "<br><br>";
    
    print HTML "<table border=\"0\"><tr><td class=\"framed\">\n";
    print HTML "<img src=\"UtilData.png\" border=\"0\">\n";
    print HTML "</td></tr></table>\n";
    print HTML "<!--#include virtual=\"footer.shtml\"-->\n";
    close(HTML);
}

print "Generation complete.\n";
Replies are listed 'Best First'.
Re: Ethernet Utilization
by andyselby (Acolyte) on Apr 16, 2009 at 21:45 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://120895]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-23 06:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found