File check_obs_scheduler of Package monitoring-plugins-obs_scheduler
#!/usr/bin/env perl
#
# Copyright (c) 2017 SUSE LLC.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
use strict;
use warnings;
use Getopt::Long;
use Data::Dumper;
#use YAML qw/LoadFile/;
BEGIN {
unshift @::INC, '/usr/lib/obs/server';
}
if (! caller) {
my $ret = eval {
my $mcos = Monitoring::Check::OBS::Scheduler->new();
$mcos->getopt();
$mcos->get_config();
$mcos->check_schedulers();
$mcos->check_results();
};
if (! defined $ret) {
print "UNKNOWN - $@";
exit 3;
}
}
package Monitoring::Check::OBS::Scheduler;
our $VERSION = '0.0.1';
use strict;
use warnings;
use Getopt::Long qw/GetOptionsFromArray/;
use Data::Dumper;
#use YAML qw/LoadFile/;
use Carp;
use XML::Structured ':bytes';
use BSConfiguration;
use BSXML;
use BSUtil;
# ATTRIBUTES
sub critical { return shift->_attribute(@_) } ## no critic (Subroutines::RequireArgUnpacking)
sub warning { return shift->_attribute(@_) } ## no critic (Subroutines::RequireArgUnpacking)
sub age { return shift->_attribute(@_) } ## no critic (Subroutines::RequireArgUnpacking)
sub config { return shift->_attribute(@_) } ## no critic (Subroutines::RequireArgUnpacking)
sub config_file { return shift->_attribute(@_) } ## no critic (Subroutines::RequireArgUnpacking)
sub results { return shift->_attribute(@_) } ## no critic (Subroutines::RequireArgUnpacking)
# METHODS
sub new {
my ($class,@args) = @_;
my $self =
{
critical => 0,
warning => 0,
age => 0,
config_file => '/etc/monitoring-plugins/check_obs_scheduler.yml',
results => [],
failed => [],
@args
};
bless $self, $class;
return $self;
}
sub _attribute {
my $self = shift;
my $value = shift;
my @caller = caller 1;
my $attr = $caller[3];
$attr =~ s/.*::([^:]*)$/$1/smx;
if (defined $value) { $self->{$attr} = $value };
return $self->{$attr};
}
sub failed {
my ($self) = @_;
$self->{failed} = [];
@{$self->{failed}} = grep { $_->{state} > 0 } @{$self->results};
@{$self->{failed}} = sort { $b->{state} <=> $a->{state} } @{$self->{failed}};
return $self->{failed};
}
sub get_failed_max_state {
my ($self) = @_;
return $self->{failed}->[0]->{state} || 0;
}
sub getopt {
my ($self) = @_;
if (! GetOptionsFromArray(\@ARGV, 'warning|w=i' => \$self->{warning}, 'critical|c=i' => \$self->{critical}, 'age|a=i' => \$self->{age}, 'config=s' => \$self->{config_file} )) {
my $bn = $0;
$bn =~ s{.*/(.*)$}{$1}smx;
print "Usage: $bn <-w warning> <-c critical> <--dir events_subdir>\n";
die "Error: Wrong arguments!\n";
}
return $self;
}
sub get_config {
my ($self) = @_;
my $cfile = $self->config_file;
#die "Config file '$cfile' not found!\n" if (! -f $cfile);
#return $self->config(LoadFile($cfile));
}
sub check_schedulers {
my ($self) = @_;
# cleanup results
$self->results([]);
my $cfg = $self->config;
opendir(INFO,"/bs/info");
my @INFOS = grep {/^schedulerinfo/} readdir (INFO);
close (INFO);
foreach my $info (sort @INFOS) {
$self->check_scheduler_single("/bs/info/$info", $cfg);
}
return $self->failed();
}
sub check_scheduler_single {
my ($self, $filename, $cfg) = @_;
my $si = readxml("$filename", $BSXML::schedulerinfo, 1);
my $si_arch = $si->{'arch'};
my $si_age = time() - $si->{'time'};
my $critical;
$critical->{'high'} = (defined($cfg->{$si_arch}->{critical})) ? $cfg->{$si_arch}->{critical} : $self->critical;
$critical->{'low'} = $critical->{'high'};
$critical->{'med'} = $critical->{'high'};
$critical->{'med'} *= 10;
$critical->{'low'} *= 100;
my $warning;
$warning->{'high'} = (defined($cfg->{$si_arch}->{warning})) ? $cfg->{$si_arch}->{warning} : $self->warning;
$warning->{'low'} = $warning->{'high'};
$warning->{'med'} = $warning->{'high'};
$warning->{'med'} *= 10;
$warning->{'low'} *= 100;
my $state = 0;
my $diff = 0;
my @perfdata;
my $summary;
my @summary;
for my $q (qw(high med low)) {
if ($si->{'queue'}->{$q} >= $warning->{$q}) {
$state = 1;
$diff = $si->{'queue'}->{$q} - $warning->{$q};
$summary->{$q} = "W:$si->{'queue'}->{$q}";
}
}
for my $q (qw(high med low)) {
if ($si->{'queue'}->{$q} >= $critical->{$q}) {
$state = 2;
$diff = $si->{'queue'}->{$q} - $critical->{$q};
$summary->{$q} = "C:$si->{'queue'}->{$q}";
}
if ($q eq "high") {
push @perfdata, "s_${si_arch}_$q=$si->{'queue'}->{$q};$warning->{$q};$critical->{$q}";
} else {
push @perfdata, "s_${si_arch}_$q=$si->{'queue'}->{$q};;$critical->{$q}";
}
}
my $si_max_age = $self->{age} ? $self->{age} : 0;
if ($si_max_age) {
push @perfdata, "s_${si_arch}_age=$si_age;;$si_max_age";
if ($si_max_age && $si_age >= $si_max_age) {
$state = 2;
$summary->{'age'} = "C:age";
}
}
push @summary, "$_:$summary->{$_}" for keys(%$summary);
push @{$self->results},
{
state => $state,
perfdata => join(" ",@perfdata),
diff => $diff,
name => $si_arch,
queue => join(",",@summary),
}
;
return;
}
sub check_results {
my ($self) = @_;
my $state = $self->get_failed_max_state();
if ($state) {
print $self->format_output_fail($state);
exit $state
} else {
print $self->format_output_ok();
exit 0;
}
}
sub format_output_fail {
my ($self, $state) = @_;
my $sname = { 0 => 'OK', 1 => 'WARNING', 2 => 'CRITICAL', 3 => 'UNKNOWN'};
croak('State "'.($state || q{}).'" not known') if ! $state;
my $out="$sname->{$state} - ";
for my $res (sort { $b->{state} <=> $a->{state} or $b->{diff} <=> $a->{diff} } @{$self->results} ) {
next if ! $res->{state};
$out = "$out $res->{name} ($res->{state}/$res->{queue}/$res->{diff})";
}
return "$out | ".$self->get_perfdata;
}
sub format_output_ok {
my ($self) = @_;
return 'OK - all schedulers checked | '.$self->get_perfdata."\n";
}
sub get_perfdata {
my ($self) = @_;
my @perfdata;
for my $res (@{$self->{results}}) {
push @perfdata, $res->{perfdata};
}
return join '; ', @perfdata;
}
1;