pandorafms/pandora_plugins/MySQL/pandora_mysql.pl
Ramon Novoa 8edaad4e5a Push /usr/lib/perl5 to the back of the module search path.
When /usr/lib/perl5 is added to the front of the module search path it
takes precedence over libraries distributed with binary versions of
Pandora FMS. This can be fixed by pushing it to the back instead.
2021-04-15 17:56:02 +02:00

1189 lines
35 KiB
Perl

#!/usr/bin/perl
# Pandora FMS Plugin for MySQL
# (c) Artica ST 2015
# v1.4, 19 Feb 2015
# ----------------------------------------------------------------------
# Default lib dir for RPM and DEB packages
BEGIN { push @INC, '/usr/lib/perl5'; }
use strict;
use Data::Dumper;
use POSIX qw(setsid strftime);
use POSIX;
use Time::Local;
#---------------------------- Global parameters -----------------------#
# OS and OS version
my $OS = $^O;
# Store original PATH
my $ORIGINAL_PATH = $ENV{'PATH'};
# FLUSH in each IO
$| = 1;
# Conf file divided line by line
my @config_file;
# Conf filename received by command line
my $archivo_cfg = $ARGV[0];
# Hash with this plugin setup
my %plugin_setup;
# Array with different block checks
my @checks;
# ----------------------------------------------------------------------
# parse_dosline (line)
#
# This cleans DOS-like line and cleans ^M character. VERY Important when
# you process .conf edited from DOS
# ----------------------------------------------------------------------
sub parse_dosline ($){
my $str = $_[0];
$str =~ s/\r//g;
return $str;
}
# ----------------------------------------------------------------------
# load_external_setup (config file)
#
# Loads a config file
# ----------------------------------------------------------------------
sub load_external_setup ($){
my $archivo_cfg = $_[0];
my $buffer_line;
# Collect items from config file and put in an array
if (! open (CFG, "< $archivo_cfg")) {
print "[ERROR] Error opening configuration file $archivo_cfg: $!.\n";
logger ("[ERROR] Error opening configuration file $archivo_cfg: $!");
exit 0;
}
while (<CFG>) {
$buffer_line = parse_dosline ($_);
# Parse configuration file, this is specially difficult because can contain SQL code, with many things
if ($buffer_line !~ /^\#/) { # begins with anything except # (for commenting)
if ($buffer_line =~ m/(.+)\s(.*)/) {
push @config_file, $buffer_line;
}
}
}
close (CFG);
}
# ----------------------------------------------------------------------
# logger_begin (message)
# Beggining of logging to file
# ----------------------------------------------------------------------
sub logger_begin ($) {
my ($message) = @_;
my $file = "/tmp/pandora_mysql";
if (! open (FILE, "> $file")) {
print "[ERROR] Could not open logfile '$file' \n";
logger ("[ERROR] Error opening logfile $file");
exit 0;
}
# open (FILE, "> $file") or die "[FATAL] Could not open logfile '$file'";
print FILE strftime ("%Y-%m-%d %H:%M:%S", localtime()) . " >> " . $message . "\n";
close (FILE);
}
# ----------------------------------------------------------------------
# logger (message)
# Log to file
# ----------------------------------------------------------------------
sub logger ($) {
my ($message) = @_;
my $file = "/tmp/pandora_mysql";
if (! open (FILE, ">> $file")) {
print "[ERROR] Could not open logfile '$file' \n";
logger ("[ERROR] Error opening logfile $file");
exit 0;
}
print FILE strftime ("%Y-%m-%d %H:%M:%S", localtime()) . " >> " . $message . "\n";
close (FILE);
}
# ----------------------------------------------------------------------
# trim (string)
#
# Erase blank spaces before and after the string
# ----------------------------------------------------------------------
sub trim ($) {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
# ----------------------------------------------------------------------
# clean_blank (string)
#
# This function return a string without blankspaces, given a simple text
# string
# ----------------------------------------------------------------------
sub clean_blank($) {
my $input = $_[0];
$input =~ s/[\s\r\n]*//g;
return $input;
}
# ----------------------------------------------------------------------
# print_module (module name, module type, module value, module
# description, [module severity])
#
# This function returns a XML module part for the plugin
# ----------------------------------------------------------------------
sub print_module ($$$$;$) {
my $MODULE_NAME = $_[0];
my $MODULE_TYPE = $_[1];
my $MODULE_VALUE = $_[2];
my $MODULE_DESC = $_[3];
my $MODULE_SEVERITY = $_[4];
# If not a string type, remove all blank spaces and check for not value returned!
if ($MODULE_TYPE !~ m/string/) {
$MODULE_VALUE = clean_blank($MODULE_VALUE);
}
print "<module>\n";
print "<name>$MODULE_NAME</name>\n";
print "<type>$MODULE_TYPE</type>\n";
print "<data><![CDATA[$MODULE_VALUE]]></data>\n";
print "<description><![CDATA[$MODULE_DESC]]></description>\n";
if (defined($MODULE_SEVERITY)) {
print "<status>$MODULE_SEVERITY</status>\n";
} else {
print "<status>NORMAL</status>\n";
}
print "</module>\n";
}
# ----------------------------------------------------------------------
# parse_config
#
# This function load configuration tokens and store in a global hash
# called %plugin_setup accesible on all program.
# ----------------------------------------------------------------------
sub parse_config {
my $check_block = 0;
my $parametro;
# Some default options
$plugin_setup{"conf_mysql_homedir"} = "/var/lib/mysql";
$plugin_setup{"conf_mysql_basedir"} = "/var/lib/mysql";
$plugin_setup{"conf_temp"} = "/tmp";
$plugin_setup{"numchecks"} = 0;
$plugin_setup{"conf_mysql_version"} = "5.5";
foreach (@config_file) {
$parametro = $_;
if ($parametro =~ m/^include\s(.*)/i) {
load_external_setup ($1);
}
if ($parametro =~ m/^conf\_mysql\_version\s(.*)/i) {
$plugin_setup{"conf_mysql_version"} = trim($1);
}
if ($parametro =~ m/^conf\_mysql\_user\s(.*)/i) {
$plugin_setup{"conf_mysql_user"} = trim($1);
}
if ($parametro =~ m/^conf\_mysql\_pass\s(.*)/i) {
my $temp = $1;
$temp =~ s/\"//g;
$plugin_setup{"conf_mysql_pass"} = trim($temp);
}
if ($parametro =~ m/^conf\_mysql\_host\s(.*)/i) {
$plugin_setup{"conf_mysql_host"} = trim($1);
}
if ($parametro =~ m/^conf\_mysql\_homedir\s(.*)/i) {
$plugin_setup{"conf_mysql_homedir"} = trim($1);
}
if ($parametro =~ m/^conf\_mysql\_basedir\s(.*)/i) {
$plugin_setup{"conf_mysql_basedir"} = trim($1);
}
if ($parametro =~ m/^conf\_mysql\_logfile\s(.*)/i) {
$plugin_setup{"conf_mysql_logfile"} = trim($1);
}
if ($parametro =~ m/^conf\_temp\s(.*)/i) {
$plugin_setup{"conf_temp"} = trim($1);
}
if ($parametro =~ m/^conf\_logparser\s(.*)/i) {
$plugin_setup{"conf_logparser"} = trim($1);
}
# Detect begin of check definition
if ($parametro =~ m/^check\_begin/i) {
$check_block = 1;
$checks[$plugin_setup{"numchecks"}]{'type'} = 'unknown';
}
############### Specific check block parsing ###################
if ($check_block == 1) {
if ($parametro =~ m/^check\_end/i) {
$check_block = 0;
$plugin_setup{"numchecks"}++;
}
# Try to parse check type (System parameters)
if ($parametro =~ m/^check\_mysql\_service/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'mysql_service';
}
if ($parametro =~ m/^check\_mysql\_memory/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'mysql_memory';
}
if ($parametro =~ m/^check\_mysql\_cpu/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'mysql_cpu';
}
if ($parametro =~ m/^check\_system\_timewait/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'system_timewait';
}
if ($parametro =~ m/^check\_system\_diskusage/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'system_diskusage';
}
if ($parametro =~ m/^check\_mysql\_ibdata1/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'mysql_ibdata1';
}
if ($parametro =~ m/^check\_mysql\_logs/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'mysql_logs';
}
if ($parametro =~ m/^check\_mysql\_connect/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'mysql_connection';
}
# Try to parse check type (Performance parameters)
if ($parametro =~ m/^mysql\_status\s(.*)/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'status';
$checks[$plugin_setup{"numchecks"}]{'show'} = trim($1);
}
# Try to parse check type (Open SQL interface)
if ($parametro =~ m/^check\_sql\s(.*)/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'sql';
$checks[$plugin_setup{"numchecks"}]{'sql'} = trim($1);
}
# Try to parse check type (Query Innodb status)
if ($parametro =~ m/^mysql\_innodb\s(.*)/i) {
$checks[$plugin_setup{"numchecks"}]{'type'} = 'innodb';
$checks[$plugin_setup{"numchecks"}]{'query'} = trim($1);
}
if ($parametro =~ m/^check\_name\s(.*)/i) {
$checks[$plugin_setup{"numchecks"}]{'check_name'} = trim($1);
}
if ($parametro =~ m/^check\_schema\s(.*)/i) {
$checks[$plugin_setup{"numchecks"}]{'check_schema'} = trim($1);
}
if ($parametro =~ m/^module\_type\s(generic_data|generic_data_inc|generic_data_string|generic_proc|async_string|async_proc|async_data)/i) {
$checks[$plugin_setup{"numchecks"}]{'module_type'} = trim($1);
}
if ($parametro =~ m/^post\_condition\s+(==|!=|<|>)\s+(.*)/i) {
$checks[$plugin_setup{"numchecks"}]{'postcondition_op'} = trim($1);
$checks[$plugin_setup{"numchecks"}]{'postcondition_val'} = trim($2);
}
if ($parametro =~ m/^post\_execution\s(.*)/i) {
$checks[$plugin_setup{"numchecks"}]{'postexecution'} = trim($1);
}
if ($parametro =~ m/^data\_absolute/i) {
$checks[$plugin_setup{"numchecks"}]{'return_type'} = 'data_absolute';
}
if ($parametro =~ m/^data\_delta/i) {
$checks[$plugin_setup{"numchecks"}]{'return_type'} = 'data_delta';
}
if ($parametro =~ m/^post\_status\s(WARNING|CRITICAL)/i) {
$checks[$plugin_setup{"numchecks"}]{'status'} = trim($1);
}
} # Check block
}
}
# ----------------------------------------------------------------------
# check_mysql_service
#
# This function check MySQL service status
# ----------------------------------------------------------------------
sub check_mysql_service {
my ($mysql_service_result1, $mysql_service_result2, $mysql_service_result3, $mysql_service_result4);
my $mysql_service_result = 0;
# Try different flavours of mysql status
$mysql_service_result1 = `service mysql status 2> /dev/null`;
$mysql_service_result2 = `service mysqld status 2> /dev/null`;
$mysql_service_result3 = `/etc/init.d/mysql status 2> /dev/null`;
$mysql_service_result4 = `/etc/init.d/mysqld status 2> /dev/null`;
#print "1 >> " . $mysql_service_result1 . "\n";
#print "2 >> " . $mysql_service_result2 . "\n";
#print "3 >> " . $mysql_service_result3 . "\n";
#print "4 >> " . $mysql_service_result4 . "\n";
# If any of these ones is up then check result eq OK!
if (($mysql_service_result1 =~ /start/i) || ($mysql_service_result1 =~ /running/i) ||
($mysql_service_result2 =~ /start/i) || ($mysql_service_result2 =~ /running/i) ||
($mysql_service_result3 =~ /start/i) || ($mysql_service_result3 =~ /running/i) ||
($mysql_service_result4 =~ /start/i) || ($mysql_service_result4 =~ /running/i)) {
# OK!
$mysql_service_result = 1;
} else {
# Fail
$mysql_service_result = 0;
}
logger("[INFO] check_mysql_service with result: " . $mysql_service_result);
return $mysql_service_result;
}
# ----------------------------------------------------------------------
# check_mysql_memory
#
# This function check MySQL memory usage
# ----------------------------------------------------------------------
sub check_mysql_memory {
my $mysql_memory_result = 0;
# Depends on OS
if ($OS =~ /hpux/i){
$mysql_memory_result = `ps -eo comm,pmem | grep -v "grep" | grep "mysqld --basedir" | awk '{print \$2}'`;
} else {
$mysql_memory_result = `ps aux | grep -v "grep" | grep "mysqld --basedir" | awk '{print \$4}'`;
}
logger("[INFO] check_mysql_memory with result: " . $mysql_memory_result);
return $mysql_memory_result;
}
# ----------------------------------------------------------------------
# check_mysql_cpu
#
# This function check MySQL cpu usage
# ----------------------------------------------------------------------
sub check_mysql_cpu {
my $mysql_cpu_result = 0;
# Depends on OS
if ($OS =~ /hpux/i){
$mysql_cpu_result = `ps -eo comm,pcpu | grep -v "grep" | grep "mysqld --basedir" | awk '{print \$2}'`;
} else {
$mysql_cpu_result = `ps aux | grep -v "grep" | grep "mysqld --basedir" | awk '{print \$3}'`;
}
logger("[INFO] check_mysql_cpu with result: " . $mysql_cpu_result);
return $mysql_cpu_result;
}
# ----------------------------------------------------------------------
# check_system_timewait
#
# This function check system timewait
# ----------------------------------------------------------------------
sub check_system_timewait {
my $system_timewait_result = 0;
$system_timewait_result = `netstat -ntu | grep "TIME_WAIT" | wc -l`;
logger("[INFO] check_system_timewait with result: " . $system_timewait_result);
return $system_timewait_result;
}
# ----------------------------------------------------------------------
# check_system_diskusage
#
# This function check system disk usage
# ----------------------------------------------------------------------
sub check_system_diskusage {
my $system_diskusage_result_tmp = 0;
my $system_diskusage_result = 0;
if (!defined($plugin_setup{"conf_mysql_homedir"})) {
logger("[INFO] system_diskusage_result check needs conf_mysql_homedir token defined in configuration file.");
return 0;
}
my $system_diskusage_result_tmp = `df -k "$plugin_setup{'conf_mysql_homedir'}" | awk '{print \$5}' | tail -1 | tr -d "%"`;
$system_diskusage_result = 100 - $system_diskusage_result_tmp;
logger("[INFO] check_system_diskusage with result: " . $system_diskusage_result);
return $system_diskusage_result;
}
# ----------------------------------------------------------------------
# check_mysql_ibdata1
#
# This function check ibdata1 file disk usage
# ----------------------------------------------------------------------
sub check_mysql_ibdata1 {
my $mysql_ibdata1_result = 0;
if (!defined($plugin_setup{"conf_mysql_basedir"})) {
logger("[INFO] check_mysql_ibdata1 check needs conf_mysql_basedir token defined in configuration file.");
}
$mysql_ibdata1_result = `du -k $plugin_setup{"conf_mysql_basedir"}/ibdata1 | tail -1 | awk '{ print \$1 }'`;
logger("[INFO] check_mysql_ibdata1 with result: " . $mysql_ibdata1_result);
return $mysql_ibdata1_result;
}
# ----------------------------------------------------------------------
# check_mysql_connection
#
# This function check connection against MySQL, if goes wrong abort monitoring
# ----------------------------------------------------------------------
sub check_mysql_connection {
my $mysql_connection_result = 1;
my $connection_string = 0;
if (!defined($plugin_setup{"conf_mysql_pass"})){
$connection_string = "mysql -u" . $plugin_setup{"conf_mysql_user"} .
" -h" . $plugin_setup{"conf_mysql_host"} ;
}else{
# Connection string
$connection_string = "mysql -u" . $plugin_setup{"conf_mysql_user"} .
" -p" . $plugin_setup{"conf_mysql_pass"} .
" -h" . $plugin_setup{"conf_mysql_host"} ;
}
my $tmp_file = $plugin_setup{'conf_temp'} . '/mysql_connection.tmp';
my $connection_result = `$connection_string -e "SELECT 1 FROM DUAL" 2> $tmp_file`;
# Collect info from temp file
open (TMP, "< $tmp_file");
while (<TMP>) {
my $buffer_line = parse_dosline ($_);
if ($buffer_line =~ /error/i) {
$mysql_connection_result = 0;
}
}
close (TMP);
unlink($tmp_file);
logger("[INFO] check_mysql_connection with result: " . $mysql_connection_result);
# Abort monitoring
if ($mysql_connection_result == 0) {
print_module("MySQL_connection_error", "async_string", "Error", "MySQL plugin cannot connect to Database. Abort execution of plugin", "CRITICAL");
}
return $mysql_connection_result;
}
# ----------------------------------------------------------------------
# check_mysql_logs
#
# This function check ibdata1 file disk usage
# ----------------------------------------------------------------------
sub check_mysql_logs(;$) {
my $module_type = $_[0];
my $mysql_logs_result = 0;
if (!defined($plugin_setup{"conf_logparser"})) {
logger("[INFO] check_mysql_logs check needs conf_logparser token defined in configuration file.");
return 0;
}
if (!defined($plugin_setup{"conf_logparser"})) {
logger("[INFO] check_mysql_logs check needs conf_mysql_logfile token defined in configuration file.");
return 0;
}
my $plugin_call = $plugin_setup{"conf_logparser"}. " " . $plugin_setup{"conf_mysql_logfile"} . " MySQL_error_logs error 2> /dev/null";
$mysql_logs_result = `$plugin_call`;
if ($mysql_logs_result ne "") {
logger ("[INFO] check_mysql_logs with result:\n$mysql_logs_result");
print $mysql_logs_result;
# Process output of grep_log plugin
my @temp = split ("\n", $mysql_logs_result);
my @result;
# Try to get return values
my $i = 0;
foreach (@temp) {
# Get return values
if ($_ =~ /<data><value><!\[CDATA\[(.*)\]\]><\/value><\/data>/){
$result[$i] = $1;
$i++;
}
}
return @result;
} else {
logger ("[INFO] Blank output in check_mysql_logs searching in logfile: " . $plugin_setup{"conf_mysql_logfile"});
# if (defined($module_type)) {
# print_module("MySQL_error_logs", $module_type, "Blank output", "Blank output in check_mysql_logs searching in logfile " . $plugin_setup{"conf_mysql_logfile"});
# } else {
# print_module("MySQL_error_logs", "async_string", "Blank output", "Blank output in check_mysql_logs searching in logfile " . $plugin_setup{"conf_mysql_logfile"});
# }
}
}
# ----------------------------------------------------------------------
# check_mysql_status (SHOW parameter, [SQL statement/ Query for Innodb status, Mysql_schema])
#
# This function check status parameter (Performance parameters)
# ----------------------------------------------------------------------
sub check_mysql_status($;$$) {
my $show_parameter = $_[0];
my $sql_statement = $_[1];
my $sql_schema = $_[2];
my $mysql_status_result = 0;
if (!defined($show_parameter)){
logger("[INFO] Empty parameter in check_mysql_status check, please revise configuration file.");
return 0;
}
# Writes in temp file
my $temp_file = $plugin_setup{"conf_temp"} . "/mysql_pandora.tmp";
open (TEMP1, "> " . $temp_file);
# Depends on the request write different statements ('pending_io', 'sql', 'innodb' is different)
if ($show_parameter =~ /processlist/i) {
print TEMP1 "SHOW " . $show_parameter;
} elsif ($show_parameter =~ /total_size/i) {
print TEMP1 "SELECT \"Total_size\",
sum( data_length + index_length ) / 1024 / 1024 / 1024 \"Data Base Size in GB\"
FROM information_schema.TABLES";
} elsif (($show_parameter !~ /pending_io/i) and ($show_parameter !~ /sql/i) and ($show_parameter ne 'innodb')) {
print TEMP1 "SHOW GLOBAL STATUS LIKE '" . $show_parameter . "'";
}
close (TEMP1);
# Connection string
my $connection_string = 0;
if (!defined($plugin_setup{"conf_mysql_pass"} ) ){
$connection_string = "mysql -u" . $plugin_setup{"conf_mysql_user"} .
" -h" . $plugin_setup{"conf_mysql_host"} ;
}else{
$connection_string = "mysql -u" . $plugin_setup{"conf_mysql_user"} .
" -p" . $plugin_setup{"conf_mysql_pass"} .
" -h" . $plugin_setup{"conf_mysql_host"} ;
}
#my $connection_string = "mysql -u" . $plugin_setup{"conf_mysql_user"} .
# " -p" . $plugin_setup{"conf_mysql_pass"} .
# " -h" . $plugin_setup{"conf_mysql_host"} ;
# If its a query, then try to add schema to the connection string
if ($show_parameter =~ /sql/i) {
if (defined($sql_schema)) {
$connection_string .= " $sql_schema";
}
}
my $post_sql = '';
# If we want to retrieve 'active sessions' count lines
if ($show_parameter =~ /processlist/i) {
$post_sql = ' | wc -l';
} # Rest of request have this suffix
else {
$post_sql = ' | tail -1 | awk \'{print $2}\'';
}
# 'pending_io' and 'sql' and 'innodb' are different
if (($show_parameter !~ /pending_io/i) and ($show_parameter !~ /sql/i) and ($show_parameter ne 'innodb')) {
$mysql_status_result = `$connection_string < $temp_file $post_sql`;
} elsif ($show_parameter =~ /sql/i) {
$mysql_status_result = `$connection_string -e "$sql_statement" | tail -1`;
} elsif ($show_parameter =~ /innodb/i) {
if ($plugin_setup{"conf_mysql_version"} == "5.0") {
$mysql_status_result = `$connection_string -e "SHOW INNODB STATUS\\G"`;
} else {
$mysql_status_result = `$connection_string -e "SHOW ENGINE INNODB STATUS\\G"`;
}
# Process output of show innodb status
my @temp = split ("\n", $mysql_status_result);
# If we detect query lines then output
$mysql_status_result = 0;
foreach (@temp) {
if ($_ =~ m/$sql_statement\s+(.*)/) {
$mysql_status_result = $1;
}
}
} else {
if ($plugin_setup{"conf_mysql_version"} == "5.0") {
$mysql_status_result = `$connection_string -e "SHOW INNODB STATUS\\G"`;
} else {
$mysql_status_result = `$connection_string -e "SHOW ENGINE INNODB STATUS\\G"`;
}
# Process output of show innodb status
my @temp = split ("\n", $mysql_status_result);
# If we detect 'i/o waiting' lines then increment counter
$mysql_status_result = 0;
foreach (@temp) {
if ($_ =~ m/(.*)waiting for i\/o request(.*)/){
$mysql_status_result++;
}
}
}
unlink ($temp_file);
# If we want to retrieve active session substract 1 due to header
if ($show_parameter =~ /processlist/i) {
if ($mysql_status_result > 0){
$mysql_status_result--;
}
}
logger("[INFO] check_mysql_status executing: $show_parameter with result: " . $mysql_status_result);
return $mysql_status_result;
}
# ----------------------------------------------------------------------
# is_numeric (arg)
#
# Return TRUE if given argument is numeric
# ----------------------------------------------------------------------
sub is_numeric($) {
my $val = $_[0];
if (!defined($val)){
return 0;
}
# Replace "," for "."
$val =~ s/\,/\./;
my $DIGITS = qr{ \d+ (?: [.] \d*)? | [.] \d+ }xms;
my $SIGN = qr{ [+-] }xms;
my $NUMBER = qr{ ($SIGN?) ($DIGITS) }xms;
if ( $val !~ /^${NUMBER}$/ ) {
return 0; #Non-numeric
} else {
return 1; #Numeric
}
}
# ----------------------------------------------------------------------
# eval_postcondition (result, operator, value)
#
# This function eval postcondition and return a boolean
# ----------------------------------------------------------------------
sub eval_postcondition($$$) {
my $result = $_[0];
my $operator = $_[1];
my $value = $_[2];
my $eval_postcondition_result = 0;
my $result_type = is_numeric($result);
logger("[INFO] Evaluating poscondition: $result $operator $value.");
# Numeric result
if ($result_type == 1) {
# Equal to
if ($operator =~ /==/) {
if (int($result) == int($value)) {
$eval_postcondition_result = 1;
}
}# Not equal to
elsif ($operator =~ /!=/) {
if (int($result) != int($value)) {
$eval_postcondition_result = 1;
}
}# Less than
elsif ($operator =~ /</) {
if (int($result) < int($value)) {
$eval_postcondition_result = 1;
}
}# More than
elsif ($operator =~ />/) {
if (int($result) > int($value)) {
$eval_postcondition_result = 1;
}
} else {
logger("[ERROR] Unknown operator in postcondition, please revise your configuration file.");
$eval_postcondition_result = 0;
}
} # Non numeric result
else {
my $result_value = sprintf("%s", $result);
my $string_value = sprintf("%s", $value);
# Equal to
if ($operator =~ /==/) {
if ($result_value =~ /$string_value/) {
$eval_postcondition_result = 1;
}
}# Not equal to
elsif ($operator =~ /!=/) {
if ($result_value !~ /$string_value/) {
$eval_postcondition_result = 1;
}
}# Less than
elsif ($operator =~ /</) {
if ($result_value lt $string_value) {
$eval_postcondition_result = 1;
}
}# More than
elsif ($operator =~ />/) {
if ($result_value gt $string_value) {
$eval_postcondition_result = 1;
}
} else {
logger("[ERROR] Unknown operator in postcondition, please revise your configuration file.");
$eval_postcondition_result = 0;
}
}
return $eval_postcondition_result;
}
# ----------------------------------------------------------------------
# eval_postcondition_array (Array result, operator, value)
#
# This function eval postcondition and return a boolean if some of the
# elements fulfill the condition
# ----------------------------------------------------------------------
sub eval_postcondition_array {
# This works
my $value = pop;
my $operator = pop;
my @result = @_;
my $eval_postcondition_array_result = 0;
my $return_postcondition_element = 0;
# Eval all array
foreach my $single_result (@result) {
$return_postcondition_element = 0;
$return_postcondition_element = eval_postcondition($single_result, $operator, $value);
if ($return_postcondition_element) {
$eval_postcondition_array_result = 1;
}
}
return $eval_postcondition_array_result;
}
# ----------------------------------------------------------------------
# store_result_check(check_type, value)
#
# This function stores in a temporary file the last value of the check
# ----------------------------------------------------------------------
sub store_result_check($$) {
my $type = $_[0];
my $value = $_[1];
# Compose the temp filename
my $tmp_file = $plugin_setup{'conf_temp'} . '/mysql_check_' . $type . '.tmp';
# Try to open temp file
if (! open (TMP, "> $tmp_file")) {
logger("[ERROR] Error opening temp file: $tmp_file for write last check value: $type, $value");
return;
}
# Write las check value
print TMP $value;
close (TMP);
logger("[INFO] Saving last check value: $value of check: $type in file $tmp_file .");
}
# ----------------------------------------------------------------------
# process_delta_data(check_type, value)
#
# This function calculates delta value for the current check
# ----------------------------------------------------------------------
sub process_delta_data($$) {
my $type = $_[0];
my $value = $_[1];
my $buffer_line;
# Compose the temp filename
my $tmp_file = $plugin_setup{'conf_temp'} . '/mysql_check_' . $type . '.tmp';
# Collect info from temp file
# If it's not possible then return token for not print module
if (! open (TMP, "< $tmp_file")) {
return '::MYSQL _ NON EXEC';
}
while (<TMP>) {
$buffer_line = parse_dosline ($_);
}
my $process_delta_result = int($value) - int($buffer_line);
close (TMP);
# If delta value is negative then reset check last value
if ($process_delta_result < 0) {
logger("[INFO] Reset last value of check_" . $type . " due to negative value: " . $process_delta_result);
return '::MYSQL _ NON EXEC';
}
logger("[INFO] check_" . $type . " postprocessed by delta calculation: " . $process_delta_result);
return $process_delta_result;
}
###############################################################################
###############################################################################
######################## MAIN PROGRAM CODE ####################################
###############################################################################
###############################################################################
# ----------------------------------------------------------------------
# Checks input parameter from command line (Conf file)
# ----------------------------------------------------------------------
my $log_init = 0;
# Load config file from command line
if ($#ARGV == -1){
print "I need at least one parameter: Complete path to external configuration file \n";
logger_begin("[ERROR] Path to configuration file it's needed");
# Logfile is initiated
$log_init = 1;
exit 0;
}
# Check for conf file
if ( ! -f $archivo_cfg ) {
printf "\n [ERROR] Cannot open configuration file at $archivo_cfg. \n\n";
if ($log_init == 1) {
logger("[ERROR] Cannot open configuration file at $archivo_cfg, please set permissions correctly.");
} else {
logger_begin("[ERROR] Cannot open configuration file at $archivo_cfg, please set permissions correctly.");
$log_init = 1;
}
print_module("MySQL_plugin_error", "generic_proc", 0, "Cannot open configuration file at $archivo_cfg, please set permissions correctly.");
exit 0;
}
# ----------------------------------------------------------------------
# Parse external configuration file
# ----------------------------------------------------------------------
load_external_setup ($archivo_cfg);
if ($log_init == 1){
logger("[INFO] Parsing config file $archivo_cfg.");
} else {
logger_begin("[INFO] Parsing config file $archivo_cfg.");
$log_init = 1;
}
parse_config;
=COMMENT
print Dumper(%plugin_setup);
print Dumper(@checks);
exit;
=cut
# ----------------------------------------------------------------------
# First check connection to MySQL
# ----------------------------------------------------------------------
my $result_connection = check_mysql_connection;
if ($result_connection == 0) {
logger ("[ERROR] Connection to MySQL error, abort monitoring.");
exit 0;
}
# ----------------------------------------------------------------------
# Process each check
# ----------------------------------------------------------------------
my $result_check;
my $module_type;
my $module_status;
my @result_check;
my $performance_parameter;
foreach (@checks) {
# Don't asumme performance parameter
$performance_parameter = 0;
my $type = $_->{'type'};
my $postcondition_op = $_->{'postcondition_op'};
my $postcondition_val = $_->{'postcondition_val'};
my $postexecution = $_->{'postexecution'};
my $check_status = $_->{'status'};
my $check_show = $_->{'show'};
my $return_type = $_->{'return_type'};
my $check_name = $_->{'check_name'};
$result_check = 0;
# Process check (System parameters)
if ($_->{'type'} eq 'mysql_service') {
$result_check = check_mysql_service;
} elsif ($_->{'type'} eq 'mysql_memory') {
$result_check = check_mysql_memory;
} elsif ($_->{'type'} eq 'mysql_cpu') {
$result_check = check_mysql_cpu;
} elsif ($_->{'type'} eq 'system_timewait') {
$result_check = check_system_timewait;
} elsif ($_->{'type'} eq 'system_diskusage') {
$result_check = check_system_diskusage;
} elsif ($_->{'type'} eq 'mysql_ibdata1') {
$result_check = check_mysql_ibdata1;
} elsif ($_->{'type'} eq 'mysql_connection') {
$result_check = check_mysql_connection;
} elsif ($_->{'type'} eq 'mysql_logs') {
@result_check = check_mysql_logs($_->{'module_type'});
}
# Process check (Perfomance parameters)
elsif ($_->{'type'} eq 'status') {
# This is a performance parameter
$performance_parameter = 1;
$result_check = check_mysql_status($_->{"show"});
}
# Process check (Open SQL interface)
elsif ($_->{'type'} eq 'sql') {
$performance_parameter = 1;
$result_check = check_mysql_status($_->{'type'}, $_->{"sql"}, $_->{'check_schema'});
}
# Process check (Query Innodb status)
elsif ($_->{'type'} eq 'innodb') {
$result_check = check_mysql_status($_->{'type'}, $_->{"query"});
}else {
logger("[INFO] Check block with invalid type, discart it. Please revise your configuration file.");
$result_check = 0;
}
# Use results
if (($_->{'type'} ne 'unknown')) {
# Prints module ('mysql_logs' check prints it's module inside check_mysql_logs function)
if ($_->{'type'} ne 'mysql_logs') {
# Evalue module type
$module_type = $_->{'module_type'};
# 'mysql_service' and 'mysql_connection' has always generic_proc type
if (($_->{'type'} eq 'mysql_service') or ($type eq 'mysql_connection')) {
$module_type = 'generic_proc';
}# By default type is generic_data
else {
$module_type = 'generic_data';
}
my $last_result_check = $result_check;
# If where are dealing with a performance parameter then look at return_type value
if ($performance_parameter and defined($_->{'return_type'})) {
if ($_->{'return_type'} eq 'data_delta') {
$result_check = process_delta_data($_->{'type'} . '_' . $_->{'show'}, $result_check);
}
}
# Store result_check in temp file for delta postprocess
if ($performance_parameter) {
store_result_check($type . '_' . $check_show, $last_result_check);
}
}
# Postcondition ('mysql_logs' type will have an array like result)
my $exec_postexecution = 0;
my $result_check_test = sprintf("%s", $result_check);
if (($type eq 'mysql_logs') and ($result_check_test ne '::MYSQL _ NON EXEC')) {
# if (defined($postcondition_op) and defined($postcondition_val)) {
# $exec_postexecution = eval_postcondition_array(@result_check, $postcondition_op, $postcondition_val);
# }
# If data has been returned, exec postcommand
if (@result_check) {
$exec_postexecution = 1;
}
}# Postcondition (other check types)
elsif (defined($postcondition_op) and defined($postcondition_val) and ($result_check_test ne '::MYSQL _ NON EXEC')) {
$exec_postexecution = eval_postcondition($result_check, $postcondition_op, $postcondition_val);
}
# If postcondition is not fulfilled then don't assign status to module
if (!$exec_postexecution) {
$check_status = 'NORMAL';
}
# Prints module ('mysql_logs' check prints it's module inside check_mysql_logs function)
if ($type ne 'mysql_logs') {
if ($result_check_test ne '::MYSQL _ NON EXEC') {
# Prints module
if ($type eq 'status') {
print_module("MySQL_" . $type . '_' . $check_show, $module_type, $result_check, '', $check_status);
} else {
if (defined($check_name)) {
print_module("MySQL_" . $type . "_" . $check_name, $module_type, $result_check, '', $check_status);
} else {
print_module("MySQL_" . $type, $module_type, $result_check, '', $check_status);
}
}
} else {
logger("[INFO] First execution of delta value for check $type, ignoring.");
}
}
# Exec command
if ($exec_postexecution) {
if (defined($postexecution)) {
logger("[INFO] Executing postexecution command: " . $postexecution);
if ($postexecution =~ /\_DATA\_/i) {
my $round_data = ceil ($result_check);
logger("[INFO] Detected macro _DATA_ in postexecution command, replacing with: $result_check");
$postexecution =~ s/\_DATA\_/$round_data/;
}
my $command_output = `$postexecution`;
logger("[INFO] Postexecution command result: " . $command_output);
}
}
} # type ne 'unknown'
}