aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKnut Auvor Grythe <knut@auvor.no>2015-04-02 08:50:54 +0200
committerroot <root@einstein.tg15.gathering.org>2015-04-02 08:50:54 +0200
commitd1eeb0c628ec5cbdb9649a241a02f97016b83015 (patch)
tree7d44b19f5abb73f569e40e02316da3735a1dfb6a
parente7658b685aab2f9ca9670df65454886384de0295 (diff)
New SNMP polling script
-rwxr-xr-xclients/snmpfetchng.pl170
1 files changed, 170 insertions, 0 deletions
diff --git a/clients/snmpfetchng.pl b/clients/snmpfetchng.pl
new file mode 100755
index 0000000..8b14c60
--- /dev/null
+++ b/clients/snmpfetchng.pl
@@ -0,0 +1,170 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use DBI;
+use POSIX;
+use Time::HiRes;
+use SNMP;
+use Data::Dumper;
+use lib '../include';
+use nms;
+
+our $dbh = nms::db_connect();
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+
+#my $qualification = 'sysname LIKE \'e71%\'';
+
+my $qualification = <<"EOF";
+(last_updated IS NULL OR now() - last_updated > poll_frequency)
+AND (locked='f' OR now() - last_updated > '5 minutes'::interval)
+AND ip is not null
+EOF
+
+# Borrowed from snmpfetch.pl
+our $qswitch = $dbh->prepare(<<"EOF")
+SELECT
+ *,
+ DATE_TRUNC('second', now() - last_updated - poll_frequency) AS overdue
+FROM
+ switches
+ NATURAL LEFT JOIN switchtypes
+WHERE
+$qualification
+ORDER BY
+ priority DESC,
+ overdue DESC
+LIMIT 10
+FOR UPDATE OF switches
+EOF
+ or die "Couldn't prepare qswitch";
+our $qlock = $dbh->prepare("UPDATE switches SET locked='t', last_updated=now() WHERE switch=?")
+ or die "Couldn't prepare qlock";
+our $qunlock = $dbh->prepare("UPDATE switches SET locked='f', last_updated=now() WHERE switch=?")
+ or die "Couldn't prepare qunlock";
+my @switches = ();
+
+our $temppoll = $dbh->prepare("INSERT INTO switch_temp (switch,temp,time) VALUES((select switch from switches where sysname = ?),?,now())")
+ or die "Couldn't prepare temppoll";
+sub mylog
+{
+ my $msg = shift;
+ my $time = POSIX::ctime(time);
+ $time =~ s/\n.*$//;
+ printf STDERR "[%s] %s\n", $time, $msg;
+}
+
+sub populate_switches
+{
+ @switches = ();
+ $qswitch->execute()
+ or die "Couldn't get switch";
+
+ while (my $ref = $qswitch->fetchrow_hashref()) {
+ push @switches, {
+ 'sysname' => $ref->{'sysname'},
+ 'id' => $ref->{'switch'},
+ 'mgtip' => $ref->{'ip'},
+ 'community' => $ref->{'community'}
+ };
+ }
+ $dbh->commit;
+}
+
+sub inner_loop
+{
+ mylog("Starting run");
+ populate_switches();
+ for my $refswitch (@switches) {
+ my %switch = %{$refswitch};
+ mylog( "START: Polling $switch{'sysname'} ($switch{'mgtip'}) ");
+
+ $switch{'start'} = time;
+ $qlock->execute($switch{'id'})
+ or die "Couldn't lock switch";
+ $dbh->commit;
+ my $s = new SNMP::Session(DestHost => $switch{'mgtip'},
+ Community => $switch{'community'},
+ Version => '2');
+ my @vars = ();
+ push @vars, [ "sysName", 0];
+ push @vars, [ "sysDescr", 0];
+ push @vars, [ "1.3.6.1.4.1.2636.3.1.13.1.7.7.1.0", 0];
+ my $varlist = SNMP::VarList->new(@vars);
+ $s->get($varlist, [ \&ckcall, \%switch ]);
+ $s->gettable('ifTable',callback => [\&callback, \%switch]);
+ }
+ mylog( "Added " . @switches . " ");
+ SNMP::MainLoop(5);
+}
+
+sub ckcall
+{
+ my %switch = %{$_[0]};
+
+ my $vars = $_[1];
+ my ($sysname,$sysdescr,$temp) = (undef,undef,undef);
+ for my $var (@$vars) {
+ if ($var->[0] eq "sysName") {
+ $sysname = $var->[2];
+ } elsif ($var->[0] eq "sysDescr") {
+ $sysdescr = $var->[2];
+ } elsif ($var->[0] eq "enterprises.2636.3.1.13.1.7.7.1.0.0") {
+ $temp = $var->[2];
+ }
+ }
+ if (defined $temp && $temp =~ /^\d+$/) {
+ $temppoll->execute($switch{'sysname'},$temp);
+ } else {
+ warn "Couldn't read temp for " . $switch{'sysname'} . ", got " . (defined $temp ? $temp : "undef");
+ }
+ $dbh->commit;
+}
+my @values = ('ifDescr','ifSpeed','ifType','ifOperStatus','ifInErrors','ifOutErrors','ifOutOctets','ifInOctets');
+my $query = "INSERT INTO polls2 (switch,time";
+foreach my $val (@values) {
+ $query .= ",$val";
+}
+$query .= ") VALUES(?,timeofday()::timestamp";
+foreach my $val (@values) {
+ $query .= ",?";
+}
+$query .= ");";
+
+our $qpoll = $dbh->prepare($query)
+ or die "Couldn't prepare qpoll";
+sub callback
+{
+ my %switch = %{$_[0]};
+ my $table = $_[1];
+
+ my %ifs = ();
+
+ foreach my $key (keys %{$table}) {
+ my $descr = $table->{$key}->{'ifDescr'};
+
+ if ($descr =~ m/(ge|xt|xe)-/ && $descr !~ m/\./) {
+ $ifs{$descr} = $table->{$key};
+ }
+ }
+
+
+ foreach my $key (keys %ifs) {
+ my @vals = ();
+ foreach my $val (@values) {
+ if (!defined($ifs{$key}{$val})) {
+ die "Missing data";
+ }
+ push @vals, $ifs{$key}{$val};
+ }
+ $qpoll->execute($switch{'id'},@vals) || die "ops";
+ }
+ mylog( "STOP: Polling $switch{'sysname'} took " . (time - $switch{'start'}) . "s");
+ $qunlock->execute($switch{'id'})
+ or die "Couldn't unlock switch";
+ $dbh->commit;
+}
+
+while (1) {
+ inner_loop();
+}