#!/usr/bin/perl -T use strict; use warnings; use VServer; use Nagios::Plugin; use POSIX; our $VERSION = '1.5'; sub init_nagios_plugin() { my $plugin = Nagios::Plugin->new( usage => "Usage: %s [-h|--help] [-w|--warnings=...] " . "[-c|--critical=...] vserver-name", version => $VERSION, blurb => "This plugin could monitor the load of single vserver guests." ); $plugin->add_arg( spec => 'w|warning=s', help => "Warning thresholds for the differnet memory types (VM, RSS, ANON, LOCK).", label => "RANGE[,RANGE[,RANGE[,RANGE]]]", ); $plugin->add_arg( spec => 'c|critical=s', help => "Critical thresholds for the differnet memory types (VM, RSS, ANON, LOCK).", label => "RANGE[,RANGE[,RANGE[,RANGE]]]", ); return $plugin; } sub parse_thresholds($) { my $arg = shift; if ($arg) { if ($arg =~ m/([-:@~0-9]+),([-:@~0-9]+),([-:@~0-9]+),([-:@~0-9]+)/) { return ($1, $2, $3, $4); } if ($arg =~ m/([-:@~0-9]+),([-:@~0-9]+),([-:@~0-9]+)/) { return ($1, $2, $3, $3); } if ($arg =~ m/([-:@~0-9]+),([-:@~0-9]+)/) { return ($1, $2, $2, $2); } if ($arg =~ m/([-:@~0-9]+)/) { return ($1, $1, $1, $1); } } return (); } sub get_mem($$) { my $n = shift; my $context = shift; my $proc = VServer::get_proc_dir($context); $n->nagios_exit(UNKNOWN, "vserver not running") unless($proc); my $ps = POSIX::sysconf(&POSIX::_SC_PAGESIZE); $n->nagios_exit(UNKNOWN, "unable to determine pagesize") unless $ps; open(my $limit, "<", "$proc/limit") || $n->nagios_exit(UNKNOWN, "could not open '$proc/limit'"); my @mem = undef; while (<$limit>) { if ($_ =~ m/^VM:\s*([0-9]+)\s/) { $mem[0] = $1 * $ps; } elsif ($_ =~ m/RSS:\s*([0-9]+)\s/) { $mem[1] = $1 * $ps; } elsif ($_ =~ m/ANON:\s*([0-9]+)\s/) { $mem[2] = $1 * $ps; } elsif ($_ =~ m/VML:\s*([0-9]+)\s/) { $mem[3] = $1 * $ps; } } close($limit); return @mem; } # fix taint mode if ($0 =~ m/(\w[\w\/]*\w)/) { $ENV{'NAGIOS_PLUGIN'} = $1; } my $n = init_nagios_plugin(); $n->getopts(); alarm $n->opts->timeout; my (%warn, %crit); ($warn{'VM'}, $warn{'RSS'}, $warn{'ANON'}, $warn{'VML'}) = parse_thresholds($n->opts->w); ($crit{'VM'}, $crit{'RSS'}, $crit{'ANON'}, $crit{'VML'}) = parse_thresholds($n->opts->c); my $vserver = shift; unless ($vserver) { $n->nagios_exit(UNKNOWN, "vserver name required"); } my $context = VServer::get_context_id($vserver); unless ($context) { $n->nagios_exit(UNKNOWN, "vserver '$vserver' not found"); } my @mem = get_mem($n, $context); if (@mem) { my %values; my %desc; ($values{'VM'}, $values{'RSS'}, $values{'ANON'}, $values{'VML'}) = @mem; %desc = ( VM => 'virtual memory', RSS => 'resident set size', ANON => 'anonymous memory', VML => 'locked memory', ); my @status = [ UNKNOWN ]; my $output = ""; for my $mem (qw( VM RSS ANON VML )) { $n->add_perfdata(label => $mem, value => $values{$mem}, min => 0, warning => $warn{$mem}, critical => $crit{$mem}, ); push(@status, $n->check_threshold(check => $values{$mem}, warning => $warn{$mem}, critical => $crit{$mem}, ) ); $values{$mem} = int(($values{$mem} / 1024) / 1024); $output .= " - $desc{$mem}: $values{$mem}MB"; } $n->nagios_exit($n->max_state(@status), "used memory$output"); } $n->nagios_exit(UNKNOWN, 'unable to parse memory statistics');