Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
#!/usr/bin/perl -w # netsnmpiio.pl # pod at tail use strict; use Net::SNMP; my $target = shift or Usage(); my $iters = (shift or 2); my $delay = (shift or 30); my $ifIndex = (shift or 2); my $outdir = (shift or '.'); my $community = (shift or 'public'); my $timeout = 15; my $port = 161; Usage() unless ( $target =~ (/\w+/) and $iters =~ (/\d+/) and $delay =~ (/\d+/) and $ifIndex =~ (/\d+/) and $outdir =~ (/.*/) and $community =~ (/[\w+\.\/]/) ); # ifName, ifSpeed, ifInOctets, ifOutOctets # ifDescr ".1.3.6.1.2.1.2.2.1.2.$ifIndex", my @oids = ( ".1.3.6.1.2.1.31.1.1.1.1.$ifIndex", ".1.3.6.1.2.1.2.2.1.5.$ifIndex", ".1.3.6.1.2.1.2.2.1.10.$ifIndex", ".1.3.6.1.2.1.2.2.1.16.$ifIndex", ); my ($mday,$mon,$year) = (localtime)[3..5]; my $ymd = sprintf("%04d%02d%02d",$year+1900,$mon+1,$mday); my %file = ( tmp => "$outdir/$target-$ifIndex-$ymd.tmp", csv => "$outdir/$target-$ifIndex-$ymd.csv", ); $file{xls} = "$outdir/$target-$ifIndex-$ymd.xls" if (my $have_SWE == 1 +); unless(-d $outdir && -w _) { print "\n\nSorry, $outdir isn't a directory,", " or you don't have write perms there.\n\n"; exit; } my @unlink1 = ( $file{tmp}, $file{csv}, ); push @unlink1, $file{xls} if ($have_SWE == 1); # Files writable only by this user for security purposes: # delete pre-existing out file because subsequent writes append: print "\nStart run of $0\n"; umask oct 133; for(@unlink1) { Unlink($_, 'verbose'); } print " Print csv header..."; open (CSV, ">$file{csv}") or die "Error opening $file{csv}: $!"; print CSV "Date,Time,Target,ifName,Seconds,MBytes,Mbits/s,%Util,\n"; close CSV or die "Error closing $file{csv}: $!"; print " done!\n"; print " Query target device..."; # Get down to business: my $i = 1; for(1..$iters) { open (TMP, ">>$file{tmp}") or die "Error opening $file{tmp}: $!"; # Localtime for human consumption, epoch for bw calcs. # Prepend relevant info to csv line: my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time); my $ymdhms = sprintf( "%04d-%02d-%02d,%02d:%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min,$sec); my $epochsec = time; print(TMP "$ymdhms,$epochsec,$target,$ifIndex,") or die "Error printing to $file{tmp}: $!"; # Here's where da *real* stuf happens: # my ($session, $error) = Net::SNMP->session( my $session = Net::SNMP->session( -hostname => $target, -community => $community, -port => $port, -timeout => $timeout, ); unless (defined($session)) { print TMP "SNMP SESSION ERROR,"; } for my $oid(@oids) { if (defined(my $response = $session->get_request($oid))) { print(TMP $response->{$oid}); } else { print TMP '0'; } print TMP ','; } $session->close(); # One line per iteration: # End of iteration: # delay between iterations, but not after last iteration: print TMP "\n"; close TMP or die "Error closing $file{tmp}: $!"; sleep $delay unless($i==$iters); $i++; } print " done!\n"; print " Munge .tmp to .csv (Mbps and %util)..."; { # Contained block to limit 'print csv with $,'. # Initialize prior array to 0 to avoid annoying 'not numeric' error +. local $, = ','; my @prior = (0) x 9; open (TMP, "<$file{tmp}") or die "Error opening $file{tmp}: $!"; open (CSV, ">>$file{csv}") or die "Error opening $file{csv}: $!"; # date,time,epochSecs,target,ifIndex,ifName,ifSpeed,ifInOctets,ifOu +tOctets, # 0 1 2 3 4 5 6 7 +8 while(<TMP>) { chomp; my @data = split ','; # Subtract epochSecs for deltaTime. # Protect against 'divide by zero' error. my $dtime = $data[2] - $prior[2]; next unless $dtime; my $inBytes = $data[7]; my $outBytes = $data[8]; my $priorInBytes = $prior[7]; my $priorOutBytes = $prior[8]; my $speed = $data[6]; # Handle counter-roll-over-to-zero in approximate fashion, # and prevent 'divide by zero' error if no OID response. $priorInBytes = 1 if( ($inBytes < $priorInBytes) or ($priorInBytes == 0) ); $priorOutBytes = 1 if( ($outBytes < $priorOutBytes) or ($priorOutBytes == 0) ); $speed = 1 if($speed == 0); my $recv = $inBytes - $priorInBytes; my $xmit = $outBytes - $priorOutBytes; my $Bytes = $recv + $xmit; my $MBytes = $Bytes / 1048576; my $Mbits = $MBytes * 8; my $Mbps = $Mbits / $dtime; # * 100 convert decimal to percent # * 1000000 move decimal point to match $speed # * 1.048576 bits per Megabit my $util = ($Mbps * 100 * 1000000) / ($speed * 1.048576); # Round output, but not @data(next iteration's @prior). my $MBytesRound = sprintf("%.3f",$MBytes); my $MbpsRound = sprintf("%.3f",$Mbps); my $utilRound = sprintf("%.3f",$util); # Don't output bogus first iteration. if($prior[2] > 0) { print CSV @data[0,1,3,5,], "$dtime,$MBytesRound,$MbpsRound,$utilRound,\n"; # print CSV @data[0,1,3,5,], "$dtime,$MBytes,$Mbps,$util,\n"; } # Set current values for 'prior' on next iteration. @prior = @data; } close (TMP) or die "Error closing $file{tmp}: $!"; close (CSV) or die "Error closing $file{csv}: $!"; } print " done!\n"; # Munge csv to xls *if* Spreadsheet::WriteExcel module installed. BEGIN { $have_SWE = 0; eval { require Spreadsheet::WriteExcel }; unless ($@) { Spreadsheet::WriteExcel->import(); $have_SWE =1; } } if ($have_SWE == 1) { print " Create xls outfile from csv..."; open (CSVFILE, $file{csv}) or die "Error opening $file{csv}: $!"; my $workbook = Spreadsheet::WriteExcel -> new($file{xls}); my $worksheet = $workbook -> addworksheet(); my $row = 0; while (<CSVFILE>) { chomp; my @field = split(',', $_); my $column = 0; foreach my $token (@field) { $worksheet -> write($row, $column, $token); $column++; } $row++; } my $format1 = $workbook -> addformat(); $format1 -> set_bold(); $format1 -> set_align('center'); $format1 -> set_bg_color('tan'); # $format1 -> set_border(); $worksheet -> set_row(0, undef, $format1); $workbook -> close() or die "Error closing $workbook: $!"; print " done!\n"; } # Wrap it all up: my @unlink2 = ( $file{tmp}, ); for(@unlink2) { Unlink($_, 'verbose'); } print "Completed run of $0.\n"; print " $file{xls}\n" if ($have_SWE == 1); print " $file{csv}\n", ; # " $file{tmp}\n", exit 0; ###################################################################### +##### # Delete outfiles from prior run (if same name as this run) sub Unlink { my $file = $_[0]; my $echo = $_[1]; if (-e $file && -w _) { print " Unlink $file..." if ($echo eq 'verbose'); unlink $file or die "Error unlinking $file: $!"; print " *poof*\n" if ($echo eq 'verbose'); } } ###################################################################### +##### sub Usage { print " Ooot! You forgot to enter necessary information, or entered bad information! Usage: netsnmpiio.pl target iterations delay ifIndex outdir ROcommunitystring target: an IPaddress, DNS name, or FQDN. iterations: how many queries you wish to run. (default 2) delay: seconds to wait between iterations. (default 30) ifIndex: SNMP parameter specifying port or interface. (default 2) outdir: destination dir for outfile. No trailing '/'. (default '.') ROcoumminitystring: SNMP string. (default 'public') Example: netsnmpiio.pl routerC 30 600 7 MyCommunityString /datadir "; exit 1; } ###################################################################### +##### =head1 NAME netsnmpiio.pl =head1 SYNOPSIS Query SNMP-enabled devices for interface (in|out)put octets. Csv outfile ~ 70KB per iteration. "clear counters" before running; CatOSv5 rollover > 4,000,000,000 Intended for spot-tests of individual interfaces. Other tools (MRTG, SNMPc, CWSI) do well for large number of ports. netsnmpiio.pl target iterations delay ifIndex outdir ROcommunitystrin +g target: an IPaddress, DNS name, or FQDN. iterations: how many queries you wish to run. (default of 2) delay: seconds to wait between iterations. (default 30) ifIndex: SNMP parameter specifying port or interface. (default of 2) outdir: destination dir for outfile. No trailing '/'. (default '.') ROcoumminitystring: SNMP string. (default 'public') Example: netsnmpiio.pl hq5500 30 600 333 MyCommunityString /datadir Assorted conversions: 144 iterations 600 sec delay = 24 hours 432 iterations 600 sec delay = 3 days 1008 iterations 600 sec delay = 7 days 2016 iterations 600 sec delay = 14 days 100Mbps = 12.5MBps 1GB = 8,589,934,592 bits (1,073,741,824 * 8) 1MB = 8,388,608 bits (1,048,576 * 8) 1KB = 8,192 bits (1024 * 8) 1Gb = 1,073,741,824 bits (1024-e3) 1Mb = 1,048,576 bits (1024-e2) 1Kb = 1,024 bits (1024-e1) ifInOctets+ifOutOctets = Bytes ((Bytes*8)/1024)/seconds = Kbps ((Bytes*8)/1048576)/seconds = Mbps =head1 TESTED Net::SNMP 3.6 Perl 5.00503 Debian 2.2r3 Perl 5.00601 Cygwin on Win2kPro ActivePerl 5.6.1 Win2kPro =head1 UPDATED 2001-08-22 10:00 CDT Unlink .tmp at end of run. Confirm counter-roll-over-to-zero Does The Right Thing. 2001-08-17 10:30 CDT No xls outfile if Spreadsheet::WriteExcel module not installed. 2001-08-15 18:10 CDT Fix broken %util calculation. Correct minor tyops. 2001-08-14 21:15 CDT Display MBytes transferred. Gracefully handle non-responsive (host|OID): (MBytes|Mbps|%Util) = -0.000 Snmp query syntax cleaner. Don't print snmp query or session errors. Fix incorrect Bps calculations. Create xls outfile from csv. Correct error in Usage and pod. 2001-08-13 10:35 CDT Gracefully handle counter-roll-over-to-zero; ~4,000,000,000 on CatOS 5. Use ifName instead of ifDescr Cisco CatOS 5 report 'blade #/port #' instead of '10/100 utp ethernet (cat 3/5) +'. 2001-08-12 21:20 CDT Test with ActivePerl on Win2k. Fix sundry tyops. Post to PerlMonks networking code (requesting critique). Net::SNMP instead of UCD-SNMP system call: Advantages: Reduce non-Perl requirements. Eliminate annoying 'one-less-than-actual-ifIndex'. About one second quicker response. Drawbacks: Must use numeric OIDs. UCD SNMP utilities still quite handy. Initialize 'prior' array at '0' to eliminate annoying 'not numeric' message. Fix bad conversion math in pod. Add ifDescr. 2001-08-11 22:50 CDT Add example temp+csv output to pod. Round Bps to 0 decimal places. Round %util to 4 decimal places (100ths of %). Utilization percentage calculations, corrected for MegaBytes. Bypass bogus first Bps output since no prior epochSec. Bps calculations from raw SNMP data. Query ifSpeed for %util calculations. Defaults for all input values except target. Sanity-check $outdir: letters, numbers, dots, dashes, underscores. Filetest for write in outdir and outdir *is* directory. Simplify iteration localtime syntax. Cleaner syntax for no sleep after last iteration. Debug errant commas in csv. Unsubify snmp query localtime+time since only called once. @raw array instead of initial temp file. Filename of target-ifIndex-yyyymmdd.csv. Add hostname,oid,ifIndex to csv output. Use PcTime return values (print the values in main). Add $outdir. 2001-08-10 21:35 CDT Sanity-check input for (wordchars|numbers) as appropriate. More informative Usage(). Input from commandline instead of hardcoded. Efforts to improve data structure. No sleep after last iteration. 2001-08-09 16:10 CDT Leading-zero padded time/date in outfiles. yyyymmdd filenames w/sprintf. 2001-08-08 16:00 CDT Initial working code. =head1 TODOS Use hash instead of array for OIDs: OID name for key, numeric OID for value. Use DBI or MySQL or Postgres instead of csv. Use Text::xSV to parse csv. Bar graph output: GD::Graph + GD.pm + libgd Debian stable libgd1g too old for current GD.pm but needed by Webalyzer. 8^( Use Pod:Usage to automagically synchronize pod with Usage(). =head1 AUTHOR ybiC =head1 CREDITS Thanks to tachyon, HamNRye, tilly, lemming, wog, and crazyinsomniac. Oh yeah, and to some guy named vroom. ;^) =cut

In reply to (code)) Net::SNMP bandwidth query (deprecated by node 121950) by ybiC

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-03-28 15:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found