Zuletzt geändert: So, 24.04.2005

«11C» node-statusd.pl «PDF», «POD»



Download
#!/usr/bin/perl

use warnings;
use strict;

use Getopt::Long;
use Fcntl qw< :DEFAULT :flock >;
use Net::Ping;

use constant { UNKNOWN => 0, STAR => 2, ON => 3, OFF => 4 };

GetOptions(
  "interval=i" => \(my $interval = 5),
  "help"       => \&usage,
) or usage();
usage() unless @ARGV >= 1;

my %host = map {
  my ($h, $i) = split /:/, $_, 2;
  $i ||= $interval;
  $i =~ /^\d+$/ or die "Error: Interval of host \"$h\" is not a number!\n";
  ($h => $i);
} @ARGV;

$SIG{CHLD} = "IGNORE";
$|++;

# Mix last_checks so to not check all hosts at the same time.
my %last_check = map { $_ => time - int rand $host{$_} } keys %host;
my %status     = map { $_ => UNKNOWN } keys %host;
write_status();

my $ping = Net::Ping->new;

while(1) {
  foreach my $host (sort keys %last_check) {
    next if $last_check{$host} > time - $host{$host};
    $last_check{$host} = time;

    write_if_change($host, sub { $status{$host} = $ping->ping($host, 5) ? ON : OFF });
  }

  # To not hog all the CPU :)
  sleep 1;
}

sub write_if_change {
  my ($host, $sub) = @_;

  my $old_status = $status{$host};
  $sub->();
  my $new_status = $status{$host};

  if($old_status != $new_status) {
    $status{$host} = STAR;
    write_status();
    system "beep", "-r2", "-l150", "-f", $new_status == ON ? "1700" : "200"
      if $new_status == ON or $new_status == OFF;
    $status{$host} = $new_status;
    write_status();
  }
}

sub write_status {
  for (sort keys %host) {
    my $status = $status{$_};
    my $first  = substr $_, 0, 1;
    print
      $status == ON      ? uc $first :
      $status == OFF     ? lc $first :
      $status == UNKNOWN ? "?"       :
      $status == STAR    ? "*"       : die;
  }
  print "\n";
}

sub usage { print STDERR <<EOH; exit 0 }
node-statusd -- monitors the liveness of given hosts

Usage: $0 [--interval=5] -- host1 host2 host3 ...

Options:
  --interval=5
    Specifies the interval to wait between livetests.

Options may be abbreviated to uniqueness.
EOH