#!/usr/bin/perl -T use strict; use warnings; use VServer; use Nagios::Plugin; use Nagios::Plugin::Functions; our $VERSION = '2.1'; sub init_nagios_plugin() { my $plugin = Nagios::Plugin->new( usage => "Usage: %s [-h|--help] [-w|--warnings=...] " . "[-c|--critical=...] [-d|--domain=...] " . "[-s|--service=...] [vserver-name]", version => $VERSION, blurb => "This plugin could monitor the load of vserver guests." ); $plugin->add_arg( spec => 'w|warning=s', help => "Warning thresholds for the different load types.", label => "INTEGER[,INTEGER[,INTEGER]]", ); $plugin->add_arg( spec => 'c|critical=s', help => "Critical thresholds for the different load types.", label => "INTEGER[,INTEGER[,INTEGER]]", ); $plugin->add_arg( spec => 'd|domain=s', help => 'Domainname to append in bulk mode or to stip ' . 'in single host mode.', label => "DOMAIN", ); $plugin->add_arg( spec => 's|service=s', help => 'Name of the service, as defined in the config of ' . 'the monitoring server. (default: ' . Nagios::Plugin::Functions::get_shortname() . ')', label => 'SERVICE', ); return $plugin; } sub parse_thresholds($) { my $arg = shift; if ($arg) { if ($arg =~ m/^([0-9]*),([0-9]*),([0-9]*)$/) { return ($1, $2, $3); } if ($arg =~ m/^([0-9]*),([0-9]*)$/) { return ($1, $2, $2); } if ($arg =~ m/^([0-9]*)$/) { return ($1, $1, $1); } } return undef; } sub output_results($$$$) { my $n = shift; my $name = shift; my $statuses = shift; my $output = shift; my $service = $ENV{NAGIOS_PLUGIN}; my $status = $n->max_state(@{$statuses}); $status = Nagios::Plugin::Functions::UNKNOWN unless defined $status && exists $Nagios::Plugin::Functions::STATUS_TEXT{$status}; my $result = $Nagios::Plugin::Functions::STATUS_TEXT{$status}; my $perf = $n->all_perfoutput(); print "$name\t$service\t$status\t$result - load average:$output | $perf\n\x17"; } sub handle_vserver($$$;$$) { my $id = shift; my $warn = shift; my $crit = shift; my $name = shift; my $domain = shift; my $n = init_nagios_plugin(); my $load = VServer::get_loadavg($id); if ($load) { my @status = [ UNKNOWN ]; my $output = ""; for my $key (qw( load1 load5 load15 )) { $n->add_perfdata(label => $key, value => $load->{$key}, warning => $warn->{$key}, critical => $crit->{$key}, min => 0, ); push(@status, $n->check_threshold(check => $load->{$key}, warning => $warn->{$key}, critical => $crit->{$key} ) ); $output .= " $load->{$key}"; } if ($name) { $n->nagios_exit($n->max_state(@status), "load average:$output"); } else { $name = VServer::get_name($id); output_results($n, "$name$domain", \@status, $output); } } } # fix taint mode $ENV{PATH} = undef; $ENV{'NAGIOS_PLUGIN'} = $1 if ($0 =~ m/(\w[\w\/]*\w)/); $ENV{'NAGIOS_PLUGIN'} = Nagios::Plugin::Functions::get_shortname(); my $n = init_nagios_plugin(); $n->getopts(); alarm $n->opts->timeout; my (%warn, %crit); ($warn{'load1'}, $warn{'load5'}, $warn{'load15'}) = parse_thresholds($n->opts->w); ($crit{'load1'}, $crit{'load5'}, $crit{'load15'}) = parse_thresholds($n->opts->c); for my $load (qw( load1 load5 load15 )) { if (defined $crit{$load} && defined $warn{$load} && $crit{$load} < $warn{$load}) { die("Parameter inconsistency: warning load is greater " . "than critical load for '$load'"); } } $ENV{'NAGIOS_PLUGIN'} = $1 if ($n->opts->s && $n->opts->s =~ m/^(.+)$/); my $domain = ''; $domain = ('.' . $n->opts->d) if $n->opts->d; if (my $vserver = shift) { $domain = quotemeta $domain; $vserver =~ s/$domain$//; my $context = VServer::get_context_id_by_name($vserver); unless ($context) { $n->nagios_exit(UNKNOWN, "vserver '$vserver' not found"); } handle_vserver($context, \%warn, \%crit, $vserver); $n->nagios_exit(UNKNOWN, 'unable to parse loadavg'); } else { for my $dir (glob("/proc/virtual/*/")) { my $id = VServer::get_context_id_by_dir($dir); handle_vserver($id, \%warn, \%crit, undef, $domain); } }