#!/usr/bin/perl -w use Net::SNMP; die "Usage: $0 [hostname] [community]\n" unless ( $ARGV[0] && $ARGV[1] ); $hostname = $ARGV[0]; $community = $ARGV[1]; # SNMP Timeout $timeout ="5"; # SNMP version $snmp_version = "2c"; $output_dir = "/home/cacti/stats/${hostname}"; $cache_dir = "/home/cacti/stats/${hostname}/cache"; $cache_file = "${cache_dir}/vserverclientconn_${hostname}.txt"; $snmpwalk = "/usr/bin/snmpwalk"; $snmptranslate = "/usr/bin/snmptranslate"; $snmpwalk_opt = "-On"; $snmptranslate_opt = "-m /home/cacti/mibs/F5/v10/F5-BIGIP-SYSTEM-MIB.txt:/home/cacti/mibs/F5/v10/F5-BIGIP-COMMON-MIB.txt:/home/cacti/mibs/F5/v10/F5-BIGIP-GLOBAL-MIB.txt:/home/cacti/mibs/F5/v10/F5-BIGIP-LOCAL-MIB.txt"; $prog_ps = "/bin/ps"; $opt_ps = "auxw"; $max_procs = "25"; $rrdtool = "/usr/bin/rrdtool"; # Debug $debug = "2"; if ( $debug > 0 ) { print "Config:\n"; print "Community: $community\n"; print "Hostname: $hostname\n"; } # Pool Prefix $prefix_name = ".1.3.6.1.4.1.3375.2.2.10.2.3.1.12"; # Don't get out of control, limit the number of procs $im_running = 0; open(PROC,"$prog_ps ${opt_ps}|") || warn "Cannot check process list:$!\n"; while() { $im_running++ if ( /${0}.*${hostname}/ ); } close(PROC); print "Running Processes: $im_running\n" if ( $debug > 1 ); print "Too many of me running, there might be a problem so I will not run again just yet.." if ( $im_running > $max_procs ); exit 0 if ( $im_running > $max_procs ); if ( ! -d "$output_dir" ) { print "Creating the directory to store the output from me (${output_dir}).."; $return = system("mkdir -p $output_dir"); if ( $return == "0") { print ".Success!\n"; } else { die ".Failed! (Now what?)\n"; } } if ( ! -d "$cache_dir" ) { print "Creating the directory to store the output from me (${cache_dir}).."; $return = system("mkdir -p $cache_dir"); if ( $return == "0") { print ".Success!\n"; } else { die ".Failed! (Now what?)\n"; } } if ( ! -f "$cache_file" ) { print "Cache file does not exist, I will create it.."; $return = system("touch $cache_file"); if ( $return == "0") { print ".Success!\n"; } else { die ".Failed! (Now what?)\n"; } } @snmpwalk_output = qw(); #print "$snmpwalk -v${snmp_version} -c $community $snmpwalk_opt $hostname $prefix_name\n"; open(SNMPWALK,"$snmpwalk -v${snmp_version} -c $community $snmpwalk_opt $hostname ${prefix_name}|") || die "Cannot run snmpwalk: $!\n"; while() { push @snmpwalk_output, ("$_"); } close(SNMPWALK); foreach (@snmpwalk_output) { #print "$_"; $vserver_oid = 0; $conns = 0; if ( /(${prefix_name}.*)\s=\sCounter64:.*/ ) { $vserver_oid = $1; snmp_cache_check("$vserver_oid"); snmp_translate("$vserver_oid") if ( $vserver_name eq "CACHE_MISS" ); } print "Name: $vserver_name\tOID: $vserver_oid\n" if ( $debug > 3 ); get_vserver_client_count("$vserver_oid","$vserver_name"); # get_pool_members("$pool_name","${pool_oid}"); # exit $pool_up; } sub snmp_cache_check { ( $vserver_oid ) = @_; print "Checking SNMP cache for ${vserver_oid}..." if ( $debug > 2 ); open(SNMPCACHE,"$cache_file") || warn "Cannot read ${cache_file}: $!\n"; while() { if ( /^${vserver_oid}\tVSERVER:(.*)/ ) { $vserver_name = $1; print "$vserver_name found!\n\n" if ( $debug > 2 ); return $vserver_name; } } close(SNMPCACHE); print "Cache miss?\n\n" if ( $debug > 2 ); $vserver_name = "CACHE_MISS"; return $vserver_name; } sub snmp_translate { ( $vserver_oid ) = @_; $vserver_name = 0; open(SNMPTRANSLATE,"$snmptranslate $snmptranslate_opt $vserver_oid 2>/dev/null|") || die "Cannot run ${snmptranslate}: $!\n"; while() { if ( /^F5-BIGIP-LOCAL-MIB.*\"(.*)\"/ ) { $vserver_name = $1; open(SNMPCACHE,">>$cache_file") || warn "Cannot write to ${cache_file}:$!\n"; print "Adding to SNMP cache file (${cache_file}) with:\n" if ( $debug > 2 ); print SNMPCACHE "${vserver_oid}\tVSERVER:${vserver_name}\n"; print "${vserver_oid}\tVSERVER:${vserver_name}\n\n" if ( $debug > 2 ); close(SNMPCACHE); } } die "Could not determine Virtual server name for ${vserver_oid}!\n" if ( $vserver_name eq "0" ); return $vserver_name; } sub get_vserver_client_count { ( $oid,$vserver_name ) = @_; $conns = 0; #print "Scanning $oid\n"; ($session,$error) = Net::SNMP->session( Hostname => ${hostname}, version => ${snmp_version}, Community => ${community}, timeout => ${timeout}); die "session error: $error" unless ($session); $snmp_result_raw = $session->get_request("$oid"); warn "request error: ".$session->error unless (defined $snmp_result_raw); $session->close; $conns = $snmp_result_raw->{"$oid"}; $conns = 0 if ( $conns =~ /nosuchinstance/i ); $rrd_output_file = "/home/cacti/public_html/cacti/rra/${hostname}/vs_conn_${vserver_name}.rrd"; $rrd_ds_raw = "DS:connections:GAUGE:120:0:U RRA:AVERAGE:0.5:1:150000 RRA:AVERAGE:0.5:1:180000 RRA:AVERAGE:0.5:6:50000 RRA:AVERAGE:0.5:24:10000 RRA:AVERAGE:0.5:288:1000 RRA:MAX:0.5:1:150000 RRA:MAX:0.5:1:180000 RRA:MAX:0.5:6:50000 RRA:MAX:0.5:24:10000 RRA:MAX:0.5:288:1000"; $rrdtool_template = "connections"; $rrdtool_results = "$conns"; create_rrd("$rrd_output_file","$rrd_ds_raw") if ( ! -f "$rrd_output_file" ); update_rrd("$rrd_output_file","--template $rrdtool_template N:${rrdtool_results}"); } sub update_rrd { my ( $rrdfile, $rrd_results ) = @_; #print "." if ( $debug == 0 ); print "Running rrdtool update $rrdfile ${rrd_results}..\n" if ( $debug > 0 ); open(RRDTOOL_UPDATE,"|$rrdtool update $rrdfile $rrd_results") || warn "Cannot run ${rrdtool}: $!\n"; while() { print $_; } close(RRDTOOL_UPDATE); } sub create_rrd { #open(ERRLOG,">>$log") || warn "Cannot open ${log}: $!\n"; my ( $rrdfile, $rrd_ds_raw ) = @_; # # Get the directory to create(if needed) before attempting RRD creation # $directory = $rrdfile; $directory =~ s/(.*)\/.*/$1/g; # # Extract the filename itself # $file = $rrdfile; $file =~ s/.*\/(.*rrd)$/$1/g; # # Print Debug Information # if ( $debug > 2 ) { print "It appears that $rrdfile does not exist, I will create it for you using the defaults:\n"; print "Directory: $directory\n"; print "RRD File to create: $file\n"; print "Full Path to filename: $rrdfile\n"; print "The DS for your RRD is: $rrd_ds_raw\n"; print "\nHere is where I would create the RRD ..\n"; } # # Create the directory for the RRD if needed # if ( ! -d "$directory" ) { print "The directory for the RRD $directory does not exist, creating it now.."; $return = system("mkdir -p $directory"); if ( $return == "0") { print ".Success!\n"; } else { die ".Failed!\n"; } } # # Log Debug Information # print scalar(localtime) . "\t The RRD $rrdfile does not exist, creating it with the defaults: rrdtool create $rrdfile --step 60 $rrd_ds_raw\n"; # # Go ahead and create the RRD already # print "Creating the RRD(${rrdfile}) itself.."; open(RRDTOOL_CREATE,"|$rrdtool create $rrdfile --step 60 $rrd_ds_raw") || die "Cannot run ${rrdtool}: $!\n"; while () { print $_; } close(RRDTOOL_CREATE); die "File was not created?!" unless ( -f "$rrdfile" ); #RRDs::create ("$rrdfile","--step","60","$rrd_ds_raw"); #my $ERR=RRDs::error; #die "ERROR while creating ${rrdfile}: $ERR\n" if $ERR; $rrd_size_bytes = (stat("$rrdfile"))[7]; $rrd_size_megs = sprintf("%0.2f",($rrd_size_bytes/1024/1024)); print "Success! (Filesize is $rrd_size_megs MB)\n"; print scalar(localtime) . "\tSuccessfully Created $rrdfile (${rrd_size_megs} MB)\n"; }