git.lirion.de

Of git, get, and gud

summaryrefslogtreecommitdiffstats
path: root/nagios-plugins-contrib-24.20190301~bpo9+1/check_mysql_health/check_mysql_health-2.2.2/plugins-scripts/Nagios/DBD/MySQL/Cluster.pm
diff options
context:
space:
mode:
Diffstat (limited to 'nagios-plugins-contrib-24.20190301~bpo9+1/check_mysql_health/check_mysql_health-2.2.2/plugins-scripts/Nagios/DBD/MySQL/Cluster.pm')
-rwxr-xr-xnagios-plugins-contrib-24.20190301~bpo9+1/check_mysql_health/check_mysql_health-2.2.2/plugins-scripts/Nagios/DBD/MySQL/Cluster.pm620
1 files changed, 620 insertions, 0 deletions
diff --git a/nagios-plugins-contrib-24.20190301~bpo9+1/check_mysql_health/check_mysql_health-2.2.2/plugins-scripts/Nagios/DBD/MySQL/Cluster.pm b/nagios-plugins-contrib-24.20190301~bpo9+1/check_mysql_health/check_mysql_health-2.2.2/plugins-scripts/Nagios/DBD/MySQL/Cluster.pm
new file mode 100755
index 0000000..7e83842
--- /dev/null
+++ b/nagios-plugins-contrib-24.20190301~bpo9+1/check_mysql_health/check_mysql_health-2.2.2/plugins-scripts/Nagios/DBD/MySQL/Cluster.pm
@@ -0,0 +1,620 @@
+package DBD::MySQL::Cluster;
+
+use strict;
+use Time::HiRes;
+use IO::File;
+use Data::Dumper;
+
+my %ERRORS=( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 );
+my %ERRORCODES=( 0 => 'OK', 1 => 'WARNING', 2 => 'CRITICAL', 3 => 'UNKNOWN' );
+
+{
+ our $verbose = 0;
+ our $scream = 0; # scream if something is not implemented
+ our $access = "dbi"; # how do we access the database.
+ our $my_modules_dyn_dir = ""; # where we look for self-written extensions
+
+ my @clusters = ();
+ my $initerrors = undef;
+
+ sub add_cluster {
+ push(@clusters, shift);
+ }
+
+ sub return_clusters {
+ return @clusters;
+ }
+
+ sub return_first_cluster() {
+ return $clusters[0];
+ }
+
+}
+
+sub new {
+ my $class = shift;
+ my %params = @_;
+ my $self = {
+ hostname => $params{hostname},
+ port => $params{port},
+ username => $params{username},
+ password => $params{password},
+ timeout => $params{timeout},
+ warningrange => $params{warningrange},
+ criticalrange => $params{criticalrange},
+ version => 'unknown',
+ nodes => [],
+ ndbd_nodes => 0,
+ ndb_mgmd_nodes => 0,
+ mysqld_nodes => 0,
+ };
+ bless $self, $class;
+ $self->init_nagios();
+ if ($self->connect(%params)) {
+ DBD::MySQL::Cluster::add_cluster($self);
+ $self->init(%params);
+ }
+ return $self;
+}
+
+sub init {
+ my $self = shift;
+ my %params = @_;
+ if ($self->{show}) {
+ my $type = undef;
+ foreach (split /\n/, $self->{show}) {
+ if (/\[(\w+)\((\w+)\)\]\s+(\d+) node/) {
+ $type = uc $2;
+ } elsif (/id=(\d+)(.*)/) {
+ push(@{$self->{nodes}}, DBD::MySQL::Cluster::Node->new(
+ type => $type,
+ id => $1,
+ status => $2,
+ ));
+ }
+ }
+ } else {
+ }
+ if ($params{mode} =~ /^cluster::ndbdrunning/) {
+ foreach my $node (@{$self->{nodes}}) {
+ $node->{type} eq "NDB" && $node->{status} eq "running" && $self->{ndbd_nodes}++;
+ $node->{type} eq "MGM" && $node->{status} eq "running" && $self->{ndb_mgmd_nodes}++;
+ $node->{type} eq "API" && $node->{status} eq "running" && $self->{mysqld_nodes}++;
+ }
+ } else {
+ printf "broken mode %s\n", $params{mode};
+ }
+}
+
+sub dump {
+ my $self = shift;
+ my $message = shift || "";
+ printf "%s %s\n", $message, Data::Dumper::Dumper($self);
+}
+
+sub nagios {
+ my $self = shift;
+ my %params = @_;
+ my $dead_ndb = 0;
+ my $dead_api = 0;
+ if (! $self->{nagios_level}) {
+ if ($params{mode} =~ /^cluster::ndbdrunning/) {
+ foreach my $node (grep { $_->{type} eq "NDB"} @{$self->{nodes}}) {
+ next if $params{selectname} && $params{selectname} ne $_->{id};
+ if (! $node->{connected}) {
+ $self->add_nagios_critical(
+ sprintf "ndb node %d is not connected", $node->{id});
+ $dead_ndb++;
+ }
+ }
+ foreach my $node (grep { $_->{type} eq "API"} @{$self->{nodes}}) {
+ next if $params{selectname} && $params{selectname} ne $_->{id};
+ if (! $node->{connected}) {
+ $self->add_nagios_critical(
+ sprintf "api node %d is not connected", $node->{id});
+ $dead_api++;
+ }
+ }
+ if (! $dead_ndb) {
+ $self->add_nagios_ok("all ndb nodes are connected");
+ }
+ if (! $dead_api) {
+ $self->add_nagios_ok("all api nodes are connected");
+ }
+ }
+ }
+ $self->add_perfdata(sprintf "ndbd_nodes=%d ndb_mgmd_nodes=%d mysqld_nodes=%d",
+ $self->{ndbd_nodes}, $self->{ndb_mgmd_nodes}, $self->{mysqld_nodes});
+}
+
+
+sub init_nagios {
+ my $self = shift;
+ no strict 'refs';
+ if (! ref($self)) {
+ my $nagiosvar = $self."::nagios";
+ my $nagioslevelvar = $self."::nagios_level";
+ $$nagiosvar = {
+ messages => {
+ 0 => [],
+ 1 => [],
+ 2 => [],
+ 3 => [],
+ },
+ perfdata => [],
+ };
+ $$nagioslevelvar = $ERRORS{OK},
+ } else {
+ $self->{nagios} = {
+ messages => {
+ 0 => [],
+ 1 => [],
+ 2 => [],
+ 3 => [],
+ },
+ perfdata => [],
+ };
+ $self->{nagios_level} = $ERRORS{OK},
+ }
+}
+
+sub check_thresholds {
+ my $self = shift;
+ my $value = shift;
+ my $defaultwarningrange = shift;
+ my $defaultcriticalrange = shift;
+ my $level = $ERRORS{OK};
+ $self->{warningrange} = $self->{warningrange} ?
+ $self->{warningrange} : $defaultwarningrange;
+ $self->{criticalrange} = $self->{criticalrange} ?
+ $self->{criticalrange} : $defaultcriticalrange;
+ if ($self->{warningrange} !~ /:/ && $self->{criticalrange} !~ /:/) {
+ # warning = 10, critical = 20, warn if > 10, crit if > 20
+ $level = $ERRORS{WARNING} if $value > $self->{warningrange};
+ $level = $ERRORS{CRITICAL} if $value > $self->{criticalrange};
+ } elsif ($self->{warningrange} =~ /([\d\.]+):/ &&
+ $self->{criticalrange} =~ /([\d\.]+):/) {
+ # warning = 98:, critical = 95:, warn if < 98, crit if < 95
+ $self->{warningrange} =~ /([\d\.]+):/;
+ $level = $ERRORS{WARNING} if $value < $1;
+ $self->{criticalrange} =~ /([\d\.]+):/;
+ $level = $ERRORS{CRITICAL} if $value < $1;
+ }
+ return $level;
+ #
+ # syntax error must be reported with returncode -1
+ #
+}
+
+sub add_nagios {
+ my $self = shift;
+ my $level = shift;
+ my $message = shift;
+ push(@{$self->{nagios}->{messages}->{$level}}, $message);
+ # recalc current level
+ foreach my $llevel (qw(CRITICAL WARNING UNKNOWN OK)) {
+ if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$llevel}}})) {
+ $self->{nagios_level} = $ERRORS{$llevel};
+ }
+ }
+}
+
+sub add_nagios_ok {
+ my $self = shift;
+ my $message = shift;
+ $self->add_nagios($ERRORS{OK}, $message);
+}
+
+sub add_nagios_warning {
+ my $self = shift;
+ my $message = shift;
+ $self->add_nagios($ERRORS{WARNING}, $message);
+}
+
+sub add_nagios_critical {
+ my $self = shift;
+ my $message = shift;
+ $self->add_nagios($ERRORS{CRITICAL}, $message);
+}
+
+sub add_nagios_unknown {
+ my $self = shift;
+ my $message = shift;
+ $self->add_nagios($ERRORS{UNKNOWN}, $message);
+}
+
+sub add_perfdata {
+ my $self = shift;
+ my $data = shift;
+ push(@{$self->{nagios}->{perfdata}}, $data);
+}
+
+sub merge_nagios {
+ my $self = shift;
+ my $child = shift;
+ foreach my $level (0..3) {
+ foreach (@{$child->{nagios}->{messages}->{$level}}) {
+ $self->add_nagios($level, $_);
+ }
+ #push(@{$self->{nagios}->{messages}->{$level}},
+ # @{$child->{nagios}->{messages}->{$level}});
+ }
+ push(@{$self->{nagios}->{perfdata}}, @{$child->{nagios}->{perfdata}});
+}
+
+
+sub calculate_result {
+ my $self = shift;
+ if ($ENV{NRPE_MULTILINESUPPORT} &&
+ length join(" ", @{$self->{nagios}->{perfdata}}) > 200) {
+ foreach my $level ("CRITICAL", "WARNING", "UNKNOWN", "OK") {
+ # first the bad news
+ if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$level}}})) {
+ $self->{nagios_message} .=
+ "\n".join("\n", @{$self->{nagios}->{messages}->{$ERRORS{$level}}});
+ }
+ }
+ $self->{nagios_message} =~ s/^\n//g;
+ $self->{perfdata} = join("\n", @{$self->{nagios}->{perfdata}});
+ } else {
+ foreach my $level ("CRITICAL", "WARNING", "UNKNOWN", "OK") {
+ # first the bad news
+ if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$level}}})) {
+ $self->{nagios_message} .=
+ join(", ", @{$self->{nagios}->{messages}->{$ERRORS{$level}}}).", ";
+ }
+ }
+ $self->{nagios_message} =~ s/, $//g;
+ $self->{perfdata} = join(" ", @{$self->{nagios}->{perfdata}});
+ }
+ foreach my $level ("OK", "UNKNOWN", "WARNING", "CRITICAL") {
+ if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$level}}})) {
+ $self->{nagios_level} = $ERRORS{$level};
+ }
+ }
+}
+
+sub debug {
+ my $self = shift;
+ my $msg = shift;
+ if ($DBD::MySQL::Cluster::verbose) {
+ printf "%s %s\n", $msg, ref($self);
+ }
+}
+
+sub connect {
+ my $self = shift;
+ my %params = @_;
+ my $retval = undef;
+ $self->{tic} = Time::HiRes::time();
+ eval {
+ use POSIX ':signal_h';
+ local $SIG{'ALRM'} = sub {
+ die "alarm\n";
+ };
+ my $mask = POSIX::SigSet->new( SIGALRM );
+ my $action = POSIX::SigAction->new(
+ sub { die "connection timeout\n" ; }, $mask);
+ my $oldaction = POSIX::SigAction->new();
+ sigaction(SIGALRM ,$action ,$oldaction );
+ alarm($self->{timeout} - 1); # 1 second before the global unknown timeout
+ my $ndb_mgm = "ndb_mgm";
+ $params{hostname} = "127.0.0.1" if ! $params{hostname};
+ $ndb_mgm .= sprintf " --ndb-connectstring=%s", $params{hostname}
+ if $params{hostname};
+ $ndb_mgm .= sprintf ":%d", $params{port}
+ if $params{port};
+ $self->{show} = `$ndb_mgm -e show 2>&1`;
+ if ($? == -1) {
+ $self->add_nagios_critical("ndb_mgm failed to execute $!");
+ } elsif ($? & 127) {
+ $self->add_nagios_critical("ndb_mgm failed to execute $!");
+ } elsif ($? >> 8 != 0) {
+ $self->add_nagios_critical("ndb_mgm unable to connect");
+ } else {
+ if ($self->{show} !~ /Cluster Configuration/) {
+ $self->add_nagios_critical("got no cluster configuration");
+ } else {
+ $retval = 1;
+ }
+ }
+ };
+ if ($@) {
+ $self->{errstr} = $@;
+ $self->{errstr} =~ s/at $0 .*//g;
+ chomp $self->{errstr};
+ $self->add_nagios_critical($self->{errstr});
+ $retval = undef;
+ }
+ $self->{tac} = Time::HiRes::time();
+ return $retval;
+}
+
+sub trace {
+ my $self = shift;
+ my $format = shift;
+ $self->{trace} = -f "/tmp/check_mysql_health.trace" ? 1 : 0;
+ if ($self->{verbose}) {
+ printf("%s: ", scalar localtime);
+ printf($format, @_);
+ }
+ if ($self->{trace}) {
+ my $logfh = new IO::File;
+ $logfh->autoflush(1);
+ if ($logfh->open("/tmp/check_mysql_health.trace", "a")) {
+ $logfh->printf("%s: ", scalar localtime);
+ $logfh->printf($format, @_);
+ $logfh->printf("\n");
+ $logfh->close();
+ }
+ }
+}
+
+sub DESTROY {
+ my $self = shift;
+ my $handle1 = "null";
+ my $handle2 = "null";
+ if (defined $self->{handle}) {
+ $handle1 = ref($self->{handle});
+ if (defined $self->{handle}->{handle}) {
+ $handle2 = ref($self->{handle}->{handle});
+ }
+ }
+ $self->trace(sprintf "DESTROY %s with handle %s %s", ref($self), $handle1, $handle2);
+ if (ref($self) eq "DBD::MySQL::Cluster") {
+ }
+ $self->trace(sprintf "DESTROY %s exit with handle %s %s", ref($self), $handle1, $handle2);
+ if (ref($self) eq "DBD::MySQL::Cluster") {
+ #printf "humpftata\n";
+ }
+}
+
+sub save_state {
+ my $self = shift;
+ my %params = @_;
+ my $extension = "";
+ mkdir $params{statefilesdir} unless -d $params{statefilesdir};
+ my $statefile = sprintf "%s/%s_%s",
+ $params{statefilesdir}, $params{hostname}, $params{mode};
+ $extension .= $params{differenciator} ? "_".$params{differenciator} : "";
+ $extension .= $params{socket} ? "_".$params{socket} : "";
+ $extension .= $params{port} ? "_".$params{port} : "";
+ $extension .= $params{database} ? "_".$params{database} : "";
+ $extension .= $params{tablespace} ? "_".$params{tablespace} : "";
+ $extension .= $params{datafile} ? "_".$params{datafile} : "";
+ $extension .= $params{name} ? "_".$params{name} : "";
+ $extension =~ s/\//_/g;
+ $extension =~ s/\(/_/g;
+ $extension =~ s/\)/_/g;
+ $extension =~ s/\*/_/g;
+ $extension =~ s/\s/_/g;
+ $statefile .= $extension;
+ $statefile = lc $statefile;
+ open(STATE, ">$statefile");
+ if ((ref($params{save}) eq "HASH") && exists $params{save}->{timestamp}) {
+ $params{save}->{localtime} = scalar localtime $params{save}->{timestamp};
+ }
+ printf STATE Data::Dumper::Dumper($params{save});
+ close STATE;
+ $self->debug(sprintf "saved %s to %s",
+ Data::Dumper::Dumper($params{save}), $statefile);
+}
+
+sub load_state {
+ my $self = shift;
+ my %params = @_;
+ my $extension = "";
+ my $statefile = sprintf "%s/%s_%s",
+ $params{statefilesdir}, $params{hostname}, $params{mode};
+ $extension .= $params{differenciator} ? "_".$params{differenciator} : "";
+ $extension .= $params{socket} ? "_".$params{socket} : "";
+ $extension .= $params{port} ? "_".$params{port} : "";
+ $extension .= $params{database} ? "_".$params{database} : "";
+ $extension .= $params{tablespace} ? "_".$params{tablespace} : "";
+ $extension .= $params{datafile} ? "_".$params{datafile} : "";
+ $extension .= $params{name} ? "_".$params{name} : "";
+ $extension =~ s/\//_/g;
+ $extension =~ s/\(/_/g;
+ $extension =~ s/\)/_/g;
+ $extension =~ s/\*/_/g;
+ $extension =~ s/\s/_/g;
+ $statefile .= $extension;
+ $statefile = lc $statefile;
+ if ( -f $statefile) {
+ our $VAR1;
+ eval {
+ require $statefile;
+ };
+ if($@) {
+printf "rumms\n";
+ }
+ $self->debug(sprintf "load %s", Data::Dumper::Dumper($VAR1));
+ return $VAR1;
+ } else {
+ return undef;
+ }
+}
+
+sub valdiff {
+ my $self = shift;
+ my $pparams = shift;
+ my %params = %{$pparams};
+ my @keys = @_;
+ my $last_values = $self->load_state(%params) || eval {
+ my $empty_events = {};
+ foreach (@keys) {
+ $empty_events->{$_} = 0;
+ }
+ $empty_events->{timestamp} = 0;
+ $empty_events;
+ };
+ foreach (@keys) {
+ $self->{'delta_'.$_} = $self->{$_} - $last_values->{$_};
+ $self->debug(sprintf "delta_%s %f", $_, $self->{'delta_'.$_});
+ }
+ $self->{'delta_timestamp'} = time - $last_values->{timestamp};
+ $params{save} = eval {
+ my $empty_events = {};
+ foreach (@keys) {
+ $empty_events->{$_} = $self->{$_};
+ }
+ $empty_events->{timestamp} = time;
+ $empty_events;
+ };
+ $self->save_state(%params);
+}
+
+sub requires_version {
+ my $self = shift;
+ my $version = shift;
+ my @instances = DBD::MySQL::Cluster::return_clusters();
+ my $instversion = $instances[0]->{version};
+ if (! $self->version_is_minimum($version)) {
+ $self->add_nagios($ERRORS{UNKNOWN},
+ sprintf "not implemented/possible for MySQL release %s", $instversion);
+ }
+}
+
+sub version_is_minimum {
+ # the current version is newer or equal
+ my $self = shift;
+ my $version = shift;
+ my $newer = 1;
+ my @instances = DBD::MySQL::Cluster::return_clusters();
+ my @v1 = map { $_ eq "x" ? 0 : $_ } split(/\./, $version);
+ my @v2 = split(/\./, $instances[0]->{version});
+ if (scalar(@v1) > scalar(@v2)) {
+ push(@v2, (0) x (scalar(@v1) - scalar(@v2)));
+ } elsif (scalar(@v2) > scalar(@v1)) {
+ push(@v1, (0) x (scalar(@v2) - scalar(@v1)));
+ }
+ foreach my $pos (0..$#v1) {
+ if ($v2[$pos] > $v1[$pos]) {
+ $newer = 1;
+ last;
+ } elsif ($v2[$pos] < $v1[$pos]) {
+ $newer = 0;
+ last;
+ }
+ }
+ #printf STDERR "check if %s os minimum %s\n", join(".", @v2), join(".", @v1);
+ return $newer;
+}
+
+sub instance_rac {
+ my $self = shift;
+ my @instances = DBD::MySQL::Cluster::return_clusters();
+ return (lc $instances[0]->{parallel} eq "yes") ? 1 : 0;
+}
+
+sub instance_thread {
+ my $self = shift;
+ my @instances = DBD::MySQL::Cluster::return_clusters();
+ return $instances[0]->{thread};
+}
+
+sub windows_cluster {
+ my $self = shift;
+ my @instances = DBD::MySQL::Cluster::return_clusters();
+ if ($instances[0]->{os} =~ /Win/i) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+sub system_vartmpdir {
+ my $self = shift;
+ if ($^O =~ /MSWin/) {
+ return $self->system_tmpdir();
+ } else {
+ return "/var/tmp/check_mysql_health";
+ }
+}
+
+sub system_oldvartmpdir {
+ my $self = shift;
+ return "/tmp";
+}
+
+sub system_tmpdir {
+ my $self = shift;
+ if ($^O =~ /MSWin/) {
+ return $ENV{TEMP} if defined $ENV{TEMP};
+ return $ENV{TMP} if defined $ENV{TMP};
+ return File::Spec->catfile($ENV{windir}, 'Temp')
+ if defined $ENV{windir};
+ return 'C:\Temp';
+ } else {
+ return "/tmp";
+ }
+}
+
+
+package DBD::MySQL::Cluster::Node;
+
+use strict;
+
+our @ISA = qw(DBD::MySQL::Cluster);
+
+my %ERRORS=( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 );
+my %ERRORCODES=( 0 => 'OK', 1 => 'WARNING', 2 => 'CRITICAL', 3 => 'UNKNOWN' );
+
+sub new {
+ my $class = shift;
+ my %params = @_;
+ my $self = {
+ mode => $params{mode},
+ timeout => $params{timeout},
+ type => $params{type},
+ id => $params{id},
+ status => $params{status},
+ };
+ bless $self, $class;
+ $self->init(%params);
+ if ($params{type} eq "NDB") {
+ bless $self, "DBD::MySQL::Cluster::Node::NDB";
+ $self->init(%params);
+ }
+ return $self;
+}
+
+sub init {
+ my $self = shift;
+ my %params = @_;
+ if ($self->{status} =~ /@(\d+\.\d+\.\d+\.\d+)\s/) {
+ $self->{addr} = $1;
+ $self->{connected} = 1;
+ } elsif ($self->{status} =~ /accepting connect from (\d+\.\d+\.\d+\.\d+)/) {
+ $self->{addr} = $1;
+ $self->{connected} = 0;
+ }
+ if ($self->{status} =~ /starting,/) {
+ $self->{status} = "starting";
+ } elsif ($self->{status} =~ /shutting,/) {
+ $self->{status} = "shutting";
+ } else {
+ $self->{status} = $self->{connected} ? "running" : "dead";
+ }
+}
+
+
+package DBD::MySQL::Cluster::Node::NDB;
+
+use strict;
+
+our @ISA = qw(DBD::MySQL::Cluster::Node);
+
+my %ERRORS=( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 );
+my %ERRORCODES=( 0 => 'OK', 1 => 'WARNING', 2 => 'CRITICAL', 3 => 'UNKNOWN' );
+
+sub init {
+ my $self = shift;
+ my %params = @_;
+ if ($self->{status} =~ /Nodegroup:\s*(\d+)/) {
+ $self->{nodegroup} = $1;
+ }
+ $self->{master} = ($self->{status} =~ /Master\)/) ? 1 : 0;
+}
+
+