2012-08-21 Miguel de Dios <miguel.dedios@artica.es>

* lib/PandoraFMS/Server.pm:: added the feature to set a agent in
	"Quiet" mode.
	
	* lib/PandoraFMS/Core.pm, bin/pandora_server: cleaned source code
	style.




git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@6897 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
mdtrooper 2012-08-21 17:33:46 +00:00
parent 6eeda98886
commit 59ddc74a16
4 changed files with 211 additions and 166 deletions

View File

@ -1,3 +1,11 @@
2012-08-21 Miguel de Dios <miguel.dedios@artica.es>
* lib/PandoraFMS/Server.pm:: added the feature to set a agent in
"Quiet" mode.
* lib/PandoraFMS/Core.pm, bin/pandora_server: cleaned source code
style.
2012-08-20 Sergio Martin <sergio.martin@artica.es> 2012-08-20 Sergio Martin <sergio.martin@artica.es>
* ChangeLog: Fixed bad description in last commit * ChangeLog: Fixed bad description in last commit

View File

@ -47,13 +47,13 @@ my $DBH;
######################################################################################## ########################################################################################
sub pandora_shutdown () { sub pandora_shutdown () {
logger (\%Config, 'Pandora FMS Server \'' . $Config{'servername'} . '\' Shutdown by signal ', 1); logger (\%Config, 'Pandora FMS Server \'' . $Config{'servername'} . '\' Shutdown by signal ', 1);
# Stop servers # Stop servers
foreach my $server (@Servers) { foreach my $server (@Servers) {
$server->downEvent (); $server->downEvent ();
$server->stop (); $server->stop ();
} }
# Stop the netflow daemon # Stop the netflow daemon
pandora_stop_netflow_daemon (); pandora_stop_netflow_daemon ();
@ -69,20 +69,20 @@ sub pandora_shutdown () {
# Server startup. # Server startup.
######################################################################################## ########################################################################################
sub pandora_startup () { sub pandora_startup () {
# Start logging # Start logging
pandora_start_log (\%Config); pandora_start_log (\%Config);
# Connect to the DB # Connect to the DB
$DBH = db_connect ($Config{'dbengine'}, $Config{'dbname'}, $Config{'dbhost'}, $Config{'dbport'}, $DBH = db_connect ($Config{'dbengine'}, $Config{'dbname'}, $Config{'dbhost'}, $Config{'dbport'},
$Config{'dbuser'}, $Config{'dbpass'}); $Config{'dbuser'}, $Config{'dbpass'});
# Grab config tokens shared with the console and not in the .conf # Grab config tokens shared with the console and not in the .conf
pandora_get_sharedconfig (\%Config, $DBH); pandora_get_sharedconfig (\%Config, $DBH);
pandora_audit (\%Config, 'Pandora FMS Server Daemon starting', 'SYSTEM', 'System', $DBH); pandora_audit (\%Config, 'Pandora FMS Server Daemon starting', 'SYSTEM', 'System', $DBH);
# Load servers # Load servers
pandora_reset_server (\%Config, $DBH); pandora_reset_server (\%Config, $DBH);
push (@Servers, new PandoraFMS::DataServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::DataServer (\%Config, $DBH));
@ -92,15 +92,15 @@ sub pandora_startup () {
push (@Servers, new PandoraFMS::WMIServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::WMIServer (\%Config, $DBH));
push (@Servers, new PandoraFMS::PluginServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::PluginServer (\%Config, $DBH));
push (@Servers, new PandoraFMS::PredictionServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::PredictionServer (\%Config, $DBH));
enterprise_hook('load_enterprise_servers', [\@Servers, \%Config, $DBH]); enterprise_hook('load_enterprise_servers', [\@Servers, \%Config, $DBH]);
# Start the netflow daemon if necessary # Start the netflow daemon if necessary
pandora_start_netflow_daemon (); pandora_start_netflow_daemon ();
# Remove disabled servers # Remove disabled servers
@Servers = grep { defined ($_) } @Servers; @Servers = grep { defined ($_) } @Servers;
# Run # Run
foreach my $server (@Servers) { foreach my $server (@Servers) {
$server->run (); $server->run ();
@ -111,21 +111,21 @@ sub pandora_startup () {
# Server restart. # Server restart.
######################################################################################## ########################################################################################
sub pandora_restart () { sub pandora_restart () {
# Stop the servers # Stop the servers
foreach my $server (@Servers) { foreach my $server (@Servers) {
$server->stop (); $server->stop ();
} }
# Remove the servers # Remove the servers
while (pop (@Servers)) {}; while (pop (@Servers)) {};
# Close STDERR, redirected by pandora_start_log # Close STDERR, redirected by pandora_start_log
close (STDERR); close (STDERR);
# Wait before trying to start again # Wait before trying to start again
sleep ($Config{'restart_delay'}); sleep ($Config{'restart_delay'});
# Start the servers # Start the servers
pandora_startup (); pandora_startup ();
} }
@ -134,31 +134,31 @@ sub pandora_restart () {
# Server crash. Handler to write in the log unhandled errors and write it to console # Server crash. Handler to write in the log unhandled errors and write it to console
######################################################################################## ########################################################################################
sub pandora_crash () { sub pandora_crash () {
my $full_error = ""; my $full_error = "";
# Avoid show messages about enterprise library loading failurem, VERY # Avoid show messages about enterprise library loading failurem, VERY
# confussing, all of them are warnigs and not critical, and user should be # confussing, all of them are warnigs and not critical, and user should be
# worried about that. If perl has a more "clean" way to avoid this messages # worried about that. If perl has a more "clean" way to avoid this messages
# will be nice to replace this code, but at this time it's the only way I know # will be nice to replace this code, but at this time it's the only way I know
foreach my $error_line (@_) { foreach my $error_line (@_) {
# Trap the XML error and exit without nasty messages
# Trap the XML error and exit without nasty messages if ($error_line =~ m/XML\/Parser/) {
if ($error_line =~ m/XML\/Parser/){ logger (\%Config, "Problem parsing XML file, XML file discarded: $error_line", 2);
logger (\%Config, "Problem parsing XML file, XML file discarded: $error_line", 2); return;
return; }
}
elsif ($error_line !~ m/Enterprise/i && $error_line !~ m/Format_XS/i && $error_line !~ m/ConfigLocal/i){ elsif ($error_line !~ m/Enterprise/i && $error_line !~ m/Format_XS/i && $error_line !~ m/ConfigLocal/i){
logger (\%Config, '[E] \'' . $Config{'servername'} . "': $error_line", 1); logger (\%Config, '[E] \'' . $Config{'servername'} . "': $error_line", 1);
} }
else { else {
if ($error_line !~ m/Can\'t\slocate/) { if ($error_line !~ m/Can\'t\slocate/) {
logger (\%Config, '[E] \'' . $Config{'servername'} . "': $error_line", 1); logger (\%Config, '[E] \'' . $Config{'servername'} . "': $error_line", 1);
} else { }
else {
# Known errors of loading Enterprise, Format_XS and ConfigLocal # Known errors of loading Enterprise, Format_XS and ConfigLocal
# modules, non fatal. # modules, non fatal.
return; return;
@ -166,16 +166,15 @@ sub pandora_crash () {
} }
$full_error .= $error_line; $full_error .= $error_line;
} }
logger (\%Config, 'Pandora FMS Server \'' . $Config{'servername'} . '\' unhandled error.', 1); logger (\%Config, 'Pandora FMS Server \'' . $Config{'servername'} . '\' unhandled error.', 1);
# It's interesting show by console problems, not only in logs. This helps # It's interesting show by console problems, not only in logs. This helps
# to solve stupid problems like Database credential problems for example # to solve stupid problems like Database credential problems for example
print_message (\%Config, ' [E] Unhandled error in "' . $Config{'servername'} . "\". See more information in logfiles at '/var/log/pandora' \n", 0); print_message (\%Config, ' [E] Unhandled error in "' . $Config{'servername'} . "\". See more information in logfiles at '/var/log/pandora' \n", 0);
print_message (\%Config, " Error description:\n", 0); print_message (\%Config, " Error description:\n", 0);
print_message (\%Config, $full_error, 0); print_message (\%Config, $full_error, 0);
} }
######################################################################################## ########################################################################################

View File

@ -125,6 +125,8 @@ use PandoraFMS::Config;
use PandoraFMS::Tools; use PandoraFMS::Tools;
use PandoraFMS::GIS qw(distance_moved); use PandoraFMS::GIS qw(distance_moved);
#use Data::Dumper;
require Exporter; require Exporter;
our @ISA = ("Exporter"); our @ISA = ("Exporter");
@ -188,9 +190,9 @@ our @AlertStatus = ('Execute the alert', 'Do not execute the alert', 'Do not exe
########################################################################## ##########################################################################
sub get_agent_from_addr ($$) { sub get_agent_from_addr ($$) {
my ($dbh, $ip_address) = @_; my ($dbh, $ip_address) = @_;
return 0 if (! defined ($ip_address) || $ip_address eq ''); return 0 if (! defined ($ip_address) || $ip_address eq '');
my $agent = get_db_single_row ($dbh, 'SELECT * FROM taddress, taddress_agent, tagente my $agent = get_db_single_row ($dbh, 'SELECT * FROM taddress, taddress_agent, tagente
WHERE tagente.id_agente = taddress_agent.id_agent WHERE tagente.id_agente = taddress_agent.id_agent
AND taddress_agent.id_a = taddress.id_a AND taddress_agent.id_a = taddress.id_a
@ -203,9 +205,9 @@ sub get_agent_from_addr ($$) {
########################################################################## ##########################################################################
sub get_agent_from_name ($$) { sub get_agent_from_name ($$) {
my ($dbh, $name) = @_; my ($dbh, $name) = @_;
return 0 if (! defined ($name) || $name eq ''); return 0 if (! defined ($name) || $name eq '');
my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE tagente.nombre = ?', $name); my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE tagente.nombre = ?', $name);
return $agent; return $agent;
} }
@ -219,31 +221,39 @@ Generate alerts for a given I<$module>.
########################################################################## ##########################################################################
sub pandora_generate_alerts ($$$$$$$$;$$$) { sub pandora_generate_alerts ($$$$$$$$;$$$) {
my ($pa_config, $data, $status, $agent, $module, $utimestamp, $dbh, $timestamp, $extra_macros, $last_data_value, $alert_type) = @_; my ($pa_config, $data, $status, $agent, $module, $utimestamp, $dbh, $timestamp, $extra_macros, $last_data_value, $alert_type) = @_;
if ($agent->{'quiet'} == 1) {
logger($pa_config, "Generate Alert. The agent '" . $agent->{'nombre'} . "' is in quiet mode.", 10);
return;
}
# Do not generate alerts for disabled groups # Do not generate alerts for disabled groups
if (is_group_disabled ($dbh, $agent->{'id_grupo'})) { if (is_group_disabled ($dbh, $agent->{'id_grupo'})) {
return; return;
} }
# Get enabled alerts associated with this module # Get enabled alerts associated with this module
my $alert_type_filter = defined ($alert_type) ? " AND type = '$alert_type'" : ''; my $alert_type_filter = defined ($alert_type) ? " AND type = '$alert_type'" : '';
my @alerts = get_db_rows ($dbh, 'SELECT talert_template_modules.id as id_template_module, my @alerts = get_db_rows ($dbh, '
talert_template_modules.*, talert_templates.* SELECT talert_template_modules.id as id_template_module,
FROM talert_template_modules, talert_templates talert_template_modules.*, talert_templates.*
WHERE talert_template_modules.id_alert_template = talert_templates.id FROM talert_template_modules, talert_templates
AND id_agent_module = ? AND disabled = 0' . $alert_type_filter, $module->{'id_agente_modulo'}); WHERE talert_template_modules.id_alert_template = talert_templates.id
AND id_agent_module = ?
AND disabled = 0' . $alert_type_filter, $module->{'id_agente_modulo'});
foreach my $alert (@alerts) { foreach my $alert (@alerts) {
my $rc = pandora_evaluate_alert($pa_config, $agent, $data, $status, $alert, my $rc = pandora_evaluate_alert($pa_config, $agent, $data,
$utimestamp, $dbh, $last_data_value); $status, $alert, $utimestamp, $dbh, $last_data_value);
pandora_process_alert ($pa_config, $data, $agent, $module, pandora_process_alert ($pa_config, $data, $agent, $module,
$alert, $rc, $dbh, $timestamp, $extra_macros); $alert, $rc, $dbh, $timestamp, $extra_macros);
# Evaluate compound alerts even if the alert status did not change in # Evaluate compound alerts even if the alert status did not change in
# case the compound alert does not recover # case the compound alert does not recover
pandora_generate_compound_alerts ($pa_config, $data, $status, $agent, $module, pandora_generate_compound_alerts ($pa_config, $data, $status,
$alert, $utimestamp, $dbh, $timestamp) $agent, $module, $alert, $utimestamp, $dbh, $timestamp);
} }
} }
@ -264,19 +274,20 @@ B<Returns>:
########################################################################## ##########################################################################
sub pandora_evaluate_alert ($$$$$$$;$$$) { sub pandora_evaluate_alert ($$$$$$$;$$$) {
my ($pa_config, $agent, $data, $last_status, $alert, $utimestamp, $dbh, $last_data_value, $events, $event) = @_; my ($pa_config, $agent, $data, $last_status, $alert, $utimestamp, $dbh, $last_data_value, $events, $event) = @_;
if (defined ($agent)) { if (defined ($agent)) {
logger ($pa_config, "Evaluating alert '" . safe_output($alert->{'name'}) . "' for agent '" . safe_output ($agent->{'nombre'}) . "'.", 10); logger ($pa_config, "Evaluating alert '" . safe_output($alert->{'name'}) . "' for agent '" . safe_output ($agent->{'nombre'}) . "'.", 10);
} else { }
else {
logger ($pa_config, "Evaluating alert '" . safe_output($alert->{'name'}) . "'.", 10); logger ($pa_config, "Evaluating alert '" . safe_output($alert->{'name'}) . "'.", 10);
} }
# Value returned on valid data # Value returned on valid data
my $status = 1; my $status = 1;
# Get current time # Get current time
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time()); my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time());
# Check weekday # Check weekday
if ($alert->{'special_day'}) { if ($alert->{'special_day'}) {
logger ($pa_config, "Checking special days '" . $alert->{'name'} . "'.", 10); logger ($pa_config, "Checking special days '" . $alert->{'name'} . "'.", 10);
@ -287,14 +298,16 @@ sub pandora_evaluate_alert ($$$$$$$;$$$) {
if ($special_day ne '') { if ($special_day ne '') {
logger ($pa_config, $date . " is a special day for " . $alert->{'name'} . ". (as a " . $special_day . ")", 10); logger ($pa_config, $date . " is a special day for " . $alert->{'name'} . ". (as a " . $special_day . ")", 10);
return 1 if ($alert->{$special_day} != 1); return 1 if ($alert->{$special_day} != 1);
} else { }
else {
logger ($pa_config, $date . " is *NOT* a special day for " . $alert->{'name'}, 10); logger ($pa_config, $date . " is *NOT* a special day for " . $alert->{'name'}, 10);
return 1 if ($alert->{$DayNames[$wday]} != 1); return 1 if ($alert->{$DayNames[$wday]} != 1);
} }
} else { }
else {
return 1 if ($alert->{$DayNames[$wday]} != 1); return 1 if ($alert->{$DayNames[$wday]} != 1);
} }
# Check time slot # Check time slot
my $time = sprintf ("%.2d:%.2d:%.2d", $hour, $min, $sec); my $time = sprintf ("%.2d:%.2d:%.2d", $hour, $min, $sec);
if (($alert->{'time_from'} ne $alert->{'time_to'})) { if (($alert->{'time_from'} ne $alert->{'time_to'})) {
@ -304,56 +317,61 @@ sub pandora_evaluate_alert ($$$$$$$;$$$) {
return 1 if (($time le $alert->{'time_from'}) && ($time ge $alert->{'time_to'})); return 1 if (($time le $alert->{'time_from'}) && ($time ge $alert->{'time_to'}));
} }
} }
# Check time threshold # Check time threshold
my $limit_utimestamp = $alert->{'last_reference'} + $alert->{'time_threshold'}; my $limit_utimestamp = $alert->{'last_reference'} + $alert->{'time_threshold'};
if ($alert->{'times_fired'} > 0) { if ($alert->{'times_fired'} > 0) {
# Reset fired alerts # Reset fired alerts
if ($utimestamp > $limit_utimestamp) { if ($utimestamp > $limit_utimestamp) {
# Cease on valid data # Cease on valid data
$status = 3; $status = 3;
# Always reset # Always reset
($alert->{'internal_counter'}, $alert->{'times_fired'}) = (0, 0); ($alert->{'internal_counter'}, $alert->{'times_fired'}) = (0, 0);
} }
# Recover takes precedence over cease # Recover takes precedence over cease
$status = 4 if ($alert->{'recovery_notify'} == 1); $status = 4 if ($alert->{'recovery_notify'} == 1);
} elsif ($utimestamp > $limit_utimestamp && $alert->{'internal_counter'} > 0) { }
elsif ($utimestamp > $limit_utimestamp && $alert->{'internal_counter'} > 0) {
$status = 5; $status = 5;
} }
# Check for valid data # Check for valid data
# Simple alert # Simple alert
if (defined ($alert->{'id_template_module'})) { if (defined ($alert->{'id_template_module'})) {
return $status if ($alert->{'type'} eq "min" && $data >= $alert->{'min_value'}); return $status if ($alert->{'type'} eq "min" && $data >= $alert->{'min_value'});
return $status if ($alert->{'type'} eq "max" && $data <= $alert->{'max_value'}); return $status if ($alert->{'type'} eq "max" && $data <= $alert->{'max_value'});
if ($alert->{'type'} eq "max_min") { if ($alert->{'type'} eq "max_min") {
if ($alert->{'matches_value'} == 1) { if ($alert->{'matches_value'} == 1) {
return $status if ($data <= $alert->{'min_value'} || return $status if ($data <= $alert->{'min_value'} ||
$data >= $alert->{'max_value'}); $data >= $alert->{'max_value'});
} else { }
else {
return $status if ($data >= $alert->{'min_value'} && return $status if ($data >= $alert->{'min_value'} &&
$data <= $alert->{'max_value'}); $data <= $alert->{'max_value'});
} }
} }
if ($alert->{'type'} eq "onchange") { if ($alert->{'type'} eq "onchange") {
if ($alert->{'matches_value'} == 1) { if ($alert->{'matches_value'} == 1) {
if (is_numeric($last_data_value)){ if (is_numeric($last_data_value)) {
return $status if ($last_data_value == $data); return $status if ($last_data_value == $data);
} else { }
else {
return $status if ($last_data_value eq $data); return $status if ($last_data_value eq $data);
} }
} else { }
if (is_numeric($last_data_value)){ else {
if (is_numeric($last_data_value)) {
return $status if ($last_data_value != $data); return $status if ($last_data_value != $data);
} else { }
else {
return $status if ($last_data_value ne $data); return $status if ($last_data_value ne $data);
} }
} }
@ -362,7 +380,7 @@ sub pandora_evaluate_alert ($$$$$$$;$$$) {
return $status if ($alert->{'type'} eq "equal" && $data != $alert->{'value'}); return $status if ($alert->{'type'} eq "equal" && $data != $alert->{'value'});
return $status if ($alert->{'type'} eq "not_equal" && $data == $alert->{'value'}); return $status if ($alert->{'type'} eq "not_equal" && $data == $alert->{'value'});
if ($alert->{'type'} eq "regex") { if ($alert->{'type'} eq "regex") {
# Make sure the regexp is valid # Make sure the regexp is valid
eval { eval {
local $SIG{'__DIE__'}; local $SIG{'__DIE__'};
@ -372,14 +390,15 @@ sub pandora_evaluate_alert ($$$$$$$;$$$) {
logger ($pa_config, "Error evaluating alert '" . safe_output($alert->{'name'}) . "' for agent '" . safe_output($agent->{'nombre'}) . "': '" . $alert->{'value'} . "' is not a valid regular expression.", 10); logger ($pa_config, "Error evaluating alert '" . safe_output($alert->{'name'}) . "' for agent '" . safe_output($agent->{'nombre'}) . "': '" . $alert->{'value'} . "' is not a valid regular expression.", 10);
return $status; return $status;
} }
if ($alert->{'matches_value'} == 1) { if ($alert->{'matches_value'} == 1) {
return $status if ($data !~ m/$alert->{'value'}/i); return $status if ($data !~ m/$alert->{'value'}/i);
} else { }
else {
return $status if ($data =~ m/$alert->{'value'}/i); return $status if ($data =~ m/$alert->{'value'}/i);
} }
} }
return $status if ($last_status != 1 && $alert->{'type'} eq 'critical'); return $status if ($last_status != 1 && $alert->{'type'} eq 'critical');
return $status if ($last_status != 2 && $alert->{'type'} eq 'warning'); return $status if ($last_status != 2 && $alert->{'type'} eq 'warning');
return $status if ($last_status != 3 && $alert->{'type'} eq 'unknown'); return $status if ($last_status != 3 && $alert->{'type'} eq 'unknown');
@ -388,15 +407,16 @@ sub pandora_evaluate_alert ($$$$$$$;$$$) {
elsif (defined ($alert->{'id_agent'})) { elsif (defined ($alert->{'id_agent'})) {
return $status if (pandora_evaluate_compound_alert($pa_config, $alert->{'id'}, $alert->{'name'}, $dbh) == 0); return $status if (pandora_evaluate_compound_alert($pa_config, $alert->{'id'}, $alert->{'name'}, $dbh) == 0);
# Event alert # Event alert
} else { }
else {
my $rc = enterprise_hook ('evaluate_event_alert', [$pa_config, $dbh, $alert, $events, $event]); my $rc = enterprise_hook ('evaluate_event_alert', [$pa_config, $dbh, $alert, $events, $event]);
return $status unless (defined ($rc) && $rc == 1); return $status unless (defined ($rc) && $rc == 1);
} }
# Check min and max alert limits # Check min and max alert limits
return 2 if (($alert->{'internal_counter'} < $alert->{'min_alerts'}) || return 2 if (($alert->{'internal_counter'} < $alert->{'min_alerts'}) ||
($alert->{'times_fired'} >= $alert->{'max_alerts'})); ($alert->{'times_fired'} >= $alert->{'max_alerts'}));
return 0; #Launch the alert return 0; #Launch the alert
} }
@ -897,20 +917,20 @@ sub pandora_process_module ($$$$$$$$$;$) {
return; return;
} }
} }
# Process data # Process data
my $processed_data = process_data ($pa_config, $data_object, $module, $module_type, $utimestamp, $dbh); my $processed_data = process_data ($pa_config, $data_object, $module, $module_type, $utimestamp, $dbh);
if (! defined ($processed_data)) { if (! defined ($processed_data)) {
logger($pa_config, "Received invalid data '" . $data_object->{'data'} . "' from agent '" . $agent->{'nombre'} . "' module '" . $module->{'nombre'} . "' agent " . (defined ($agent) ? "'" . $agent->{'nombre'} . "'" : 'ID ' . $module->{'id_agente'}) . ".", 3); logger($pa_config, "Received invalid data '" . $data_object->{'data'} . "' from agent '" . $agent->{'nombre'} . "' module '" . $module->{'nombre'} . "' agent " . (defined ($agent) ? "'" . $agent->{'nombre'} . "'" : 'ID ' . $module->{'id_agente'}) . ".", 3);
pandora_update_module_on_error ($pa_config, $module, $dbh); pandora_update_module_on_error ($pa_config, $module, $dbh);
return; return;
} }
$timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime($utimestamp)) if (! defined ($timestamp) || $timestamp eq ''); $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime($utimestamp)) if (! defined ($timestamp) || $timestamp eq '');
# Export data # Export data
export_module_data ($pa_config, $processed_data, $agent, $module, $module_type, $timestamp, $dbh); export_module_data ($pa_config, $processed_data, $agent, $module, $module_type, $timestamp, $dbh);
# Get previous status # Get previous status
my $agent_status = get_db_single_row ($dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module->{'id_agente_modulo'}); my $agent_status = get_db_single_row ($dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module->{'id_agente_modulo'});
if (! defined ($agent_status)) { if (! defined ($agent_status)) {
@ -922,10 +942,10 @@ sub pandora_process_module ($$$$$$$$$;$) {
my $status = $agent_status->{'estado'} == 3 ? $last_status : $agent_status->{'estado'}; my $status = $agent_status->{'estado'} == 3 ? $last_status : $agent_status->{'estado'};
my $status_changes = $agent_status->{'status_changes'}; my $status_changes = $agent_status->{'status_changes'};
my $last_data_value = $agent_status->{'datos'}; my $last_data_value = $agent_status->{'datos'};
# Get new status # Get new status
my $new_status = get_module_status ($processed_data, $module, $module_type); my $new_status = get_module_status ($processed_data, $module, $module_type);
# Calculate the current interval # Calculate the current interval
my $current_interval = ($module->{'module_interval'} == 0 ? $agent->{'intervalo'} : $module->{'module_interval'}); my $current_interval = ($module->{'module_interval'} == 0 ? $agent->{'intervalo'} : $module->{'module_interval'});
@ -937,49 +957,54 @@ sub pandora_process_module ($$$$$$$$$;$) {
$status_changes = $module->{'min_ff_event'} if ($status_changes > $module->{'min_ff_event'}); $status_changes = $module->{'min_ff_event'} if ($status_changes > $module->{'min_ff_event'});
$status_changes++; $status_changes++;
} else { }
else {
$status_changes = 0; $status_changes = 0;
} }
# Active ff interval # Active ff interval
if ($module->{'module_ff_interval'} != 0 && $status_changes < $module->{'min_ff_event'}) { if ($module->{'module_ff_interval'} != 0 && $status_changes < $module->{'min_ff_event'}) {
$current_interval = $module->{'module_ff_interval'}; $current_interval = $module->{'module_ff_interval'};
} }
# Change status # Change status
if ($status_changes == $module->{'min_ff_event'} && $status != $new_status) { if ($status_changes == $module->{'min_ff_event'} && $status != $new_status) {
generate_status_event ($pa_config, $processed_data, $agent, $module, $new_status, $status, $dbh); generate_status_event ($pa_config, $processed_data, $agent, $module, $new_status, $status, $dbh);
$status = $new_status; $status = $new_status;
} }
$last_status = $new_status; $last_status = $new_status;
# Generate alerts # Generate alerts
if (pandora_inhibit_alerts ($pa_config, $agent, $dbh, 0) == 0) { if (pandora_inhibit_alerts ($pa_config, $agent, $dbh, 0) == 0) {
pandora_generate_alerts ($pa_config, $processed_data, $status, $agent, $module, $utimestamp, $dbh, $timestamp, $extra_macros, $last_data_value); pandora_generate_alerts ($pa_config, $processed_data, $status, $agent, $module, $utimestamp, $dbh, $timestamp, $extra_macros, $last_data_value);
} else { }
else {
logger($pa_config, "Alerts inhibited for agent '" . $agent->{'nombre'} . "'.", 10); logger($pa_config, "Alerts inhibited for agent '" . $agent->{'nombre'} . "'.", 10);
} }
# tagente_estado.last_try defaults to NULL, should default to '1970-01-01 00:00:00' # tagente_estado.last_try defaults to NULL, should default to '1970-01-01 00:00:00'
$agent_status->{'last_try'} = '1970-01-01 00:00:00' unless defined ($agent_status->{'last_try'}); $agent_status->{'last_try'} = '1970-01-01 00:00:00' unless defined ($agent_status->{'last_try'});
# Do we have to save module data? # Do we have to save module data?
if ($agent_status->{'last_try'} !~ /(\d+)\-(\d+)\-(\d+) +(\d+):(\d+):(\d+)/) { if ($agent_status->{'last_try'} !~ /(\d+)\-(\d+)\-(\d+) +(\d+):(\d+):(\d+)/) {
logger($pa_config, "Invalid last try timestamp '" . $agent_status->{'last_try'} . "' for agent '" . $agent->{'nombre'} . "' not found while processing module '" . $module->{'nombre'} . "'.", 3); logger($pa_config, "Invalid last try timestamp '" . $agent_status->{'last_try'} . "' for agent '" . $agent->{'nombre'} . "' not found while processing module '" . $module->{'nombre'} . "'.", 3);
pandora_update_module_on_error ($pa_config, $module, $dbh); pandora_update_module_on_error ($pa_config, $module, $dbh);
return; return;
} }
my $last_try = ($1 == 0) ? 0 : timelocal($6, $5, $4, $3, $2 - 1, $1 - 1900); my $last_try = ($1 == 0) ? 0 : timelocal($6, $5, $4, $3, $2 - 1, $1 - 1900);
my $save = ($module->{'history_data'} == 1 && ($agent_status->{'datos'} ne $processed_data || $last_try < ($utimestamp - 86400))) ? 1 : 0; my $save = ($module->{'history_data'} == 1 && ($agent_status->{'datos'} ne $processed_data || $last_try < ($utimestamp - 86400))) ? 1 : 0;
db_do ($dbh, 'UPDATE tagente_estado SET datos = ?, estado = ?, last_status = ?, status_changes = ?, utimestamp = ?, timestamp = ?, db_do ($dbh, 'UPDATE tagente_estado
id_agente = ?, current_interval = ?, running_by = ?, last_execution_try = ?, last_try = ? SET datos = ?, estado = ?, last_status = ?,
status_changes = ?, utimestamp = ?, timestamp = ?,
id_agente = ?, current_interval = ?, running_by = ?,
last_execution_try = ?, last_try = ?
WHERE id_agente_modulo = ?', $processed_data, $status, $last_status, $status_changes, WHERE id_agente_modulo = ?', $processed_data, $status, $last_status, $status_changes,
$current_utimestamp, $timestamp, $module->{'id_agente'}, $current_interval, $server_id, $current_utimestamp, $timestamp, $module->{'id_agente'}, $current_interval, $server_id,
$utimestamp, ($save == 1) ? $timestamp : $agent_status->{'last_try'}, $module->{'id_agente_modulo'}); $utimestamp, ($save == 1) ? $timestamp : $agent_status->{'last_try'}, $module->{'id_agente_modulo'});
# Save module data. Async and log4x modules are not compressed. # Save module data. Async and log4x modules are not compressed.
if ($module_type =~ m/(async)|(log4x)/ || $save == 1) { if ($module_type =~ m/(async)|(log4x)/ || $save == 1) {
save_module_data ($data_object, $module, $module_type, $utimestamp, $dbh); save_module_data ($data_object, $module, $module_type, $utimestamp, $dbh);
@ -996,22 +1021,22 @@ Update planned downtimes.
sub pandora_planned_downtime ($$) { sub pandora_planned_downtime ($$) {
my ($pa_config, $dbh) = @_; my ($pa_config, $dbh) = @_;
my $utimestamp = time(); my $utimestamp = time();
# Start pending downtimes (disable agents) # Start pending downtimes (disable agents)
my @downtimes = get_db_rows($dbh, 'SELECT * FROM tplanned_downtime WHERE executed = 0 AND date_from <= ? AND date_to >= ?', $utimestamp, $utimestamp); my @downtimes = get_db_rows($dbh, 'SELECT * FROM tplanned_downtime WHERE executed = 0 AND date_from <= ? AND date_to >= ?', $utimestamp, $utimestamp);
foreach my $downtime (@downtimes) { foreach my $downtime (@downtimes) {
if (!defined($downtime->{'description'})){ if (!defined($downtime->{'description'})){
$downtime->{'description'} = "N/A"; $downtime->{'description'} = "N/A";
} }
if (!defined($downtime->{'name'})){ if (!defined($downtime->{'name'})){
$downtime->{'name'} = "N/A"; $downtime->{'name'} = "N/A";
} }
logger($pa_config, "Starting planned downtime '" . $downtime->{'name'} . "'.", 10); logger($pa_config, "Starting planned downtime '" . $downtime->{'name'} . "'.", 10);
db_do($dbh, 'UPDATE tplanned_downtime SET executed = 1 WHERE id = ?', $downtime->{'id'}); db_do($dbh, 'UPDATE tplanned_downtime SET executed = 1 WHERE id = ?', $downtime->{'id'});
pandora_event ($pa_config, "Server ".$pa_config->{'servername'}." started planned downtime: ".$downtime->{'description'}, 0, 0, 1, 0, 0, 'system', 0, $dbh); pandora_event ($pa_config, "Server ".$pa_config->{'servername'}." started planned downtime: ".$downtime->{'description'}, 0, 0, 1, 0, 0, 'system', 0, $dbh);
@ -1025,26 +1050,26 @@ sub pandora_planned_downtime ($$) {
} }
} }
} }
# Stop executed downtimes (enable agents) # Stop executed downtimes (enable agents)
@downtimes = get_db_rows($dbh, 'SELECT * FROM tplanned_downtime WHERE executed = 1 AND date_to <= ?', $utimestamp); @downtimes = get_db_rows($dbh, 'SELECT * FROM tplanned_downtime WHERE executed = 1 AND date_to <= ?', $utimestamp);
foreach my $downtime (@downtimes) { foreach my $downtime (@downtimes) {
logger($pa_config, "Ending planned downtime '" . $downtime->{'name'} . "'.", 10); logger($pa_config, "Ending planned downtime '" . $downtime->{'name'} . "'.", 10);
db_do($dbh, 'UPDATE tplanned_downtime SET executed = 0 WHERE id = ?', $downtime->{'id'}); db_do($dbh, 'UPDATE tplanned_downtime SET executed = 0 WHERE id = ?', $downtime->{'id'});
pandora_event ($pa_config, 'Server ' . $pa_config->{'servername'} . ' stopped planned downtime: ' . $downtime->{'description'}, 0, 0, 1, 0, 0, 'system', 0, $dbh); pandora_event ($pa_config, 'Server ' . $pa_config->{'servername'} . ' stopped planned downtime: ' . $downtime->{'description'}, 0, 0, 1, 0, 0, 'system', 0, $dbh);
my @downtime_agents = get_db_rows($dbh, 'SELECT * FROM tplanned_downtime_agents WHERE id_downtime = ' . $downtime->{'id'}); my @downtime_agents = get_db_rows($dbh, 'SELECT * FROM tplanned_downtime_agents WHERE id_downtime = ' . $downtime->{'id'});
foreach my $downtime_agent (@downtime_agents) { foreach my $downtime_agent (@downtime_agents) {
if ($downtime->{'only_alerts'} == 0) { if ($downtime->{'only_alerts'} == 0) {
db_do ($dbh, 'UPDATE tagente SET disabled = 0 WHERE id_agente = ?', $downtime_agent->{'id_agent'}); db_do ($dbh, 'UPDATE tagente SET disabled = 0 WHERE id_agente = ?', $downtime_agent->{'id_agent'});
} else { } else {
db_do ($dbh, 'UPDATE talert_template_modules SET disabled = 0 WHERE id_agent_module IN (SELECT id_agente_modulo FROM tagente_modulo WHERE id_agente = ?)', $downtime_agent->{'id_agent'}); db_do ($dbh, 'UPDATE talert_template_modules SET disabled = 0 WHERE id_agent_module IN (SELECT id_agente_modulo FROM tagente_modulo WHERE id_agente = ?)', $downtime_agent->{'id_agent'});
} }
} }
} }
} }
@ -1058,7 +1083,7 @@ Reset the status of all server types for the current server.
########################################################################## ##########################################################################
sub pandora_reset_server ($$) { sub pandora_reset_server ($$) {
my ($pa_config, $dbh) = @_; my ($pa_config, $dbh) = @_;
db_do ($dbh, 'UPDATE tserver SET status = 0, threads = 0, queued_modules = 0 WHERE name = ?', $pa_config->{'servername'}); db_do ($dbh, 'UPDATE tserver SET status = 0, threads = 0, queued_modules = 0 WHERE name = ?', $pa_config->{'servername'});
} }
@ -1297,11 +1322,11 @@ sub pandora_module_keep_alive ($$$$$) {
my ($pa_config, $id_agent, $agent_name, $server_id, $dbh) = @_; my ($pa_config, $id_agent, $agent_name, $server_id, $dbh) = @_;
logger($pa_config, "Updating keep_alive module for agent '" . safe_output($agent_name) . "'.", 10); logger($pa_config, "Updating keep_alive module for agent '" . safe_output($agent_name) . "'.", 10);
# Update keepalive module # Update keepalive module
my $module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente = ? AND delete_pending = 0 AND id_tipo_modulo = 100', $id_agent); my $module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente = ? AND delete_pending = 0 AND id_tipo_modulo = 100', $id_agent);
return unless defined ($module); return unless defined ($module);
my %data = ('data' => 1); my %data = ('data' => 1);
pandora_process_module ($pa_config, \%data, '', $module, 'keep_alive', '', time(), $server_id, $dbh); pandora_process_module ($pa_config, \%data, '', $module, 'keep_alive', '', time(), $server_id, $dbh);
} }
@ -1316,7 +1341,7 @@ Create an internal Pandora incident.
sub pandora_create_incident ($$$$$$$$;$) { sub pandora_create_incident ($$$$$$$$;$) {
my ($pa_config, $dbh, $title, $text, my ($pa_config, $dbh, $title, $text,
$priority, $status, $origin, $id_group, $owner) = @_; $priority, $status, $origin, $id_group, $owner) = @_;
logger($pa_config, "Creating incident '$text' source '$origin'.", 8); logger($pa_config, "Creating incident '$text' source '$origin'.", 8);
# Initialize default parameters # Initialize default parameters
@ -1579,25 +1604,35 @@ Generate an event.
sub pandora_event ($$$$$$$$$$;$$$$$) { sub pandora_event ($$$$$$$$$$;$$$$$) {
my ($pa_config, $evento, $id_grupo, $id_agente, $severity, my ($pa_config, $evento, $id_grupo, $id_agente, $severity,
$id_alert_am, $id_agentmodule, $event_type, $event_status, $dbh, $source, $user_name, $comment, $id_extra, $tags) = @_; $id_alert_am, $id_agentmodule, $event_type, $event_status, $dbh, $source, $user_name, $comment, $id_extra, $tags) = @_;
my $agent = get_db_single_row ($dbh, 'SELECT *
FROM tagente WHERE id_agente = ?', $id_agente);
if ($agent->{'quiet'} == 1) {
logger($pa_config, "Generate Event. The agent '" . $agent->{'nombre'} . "' is in quiet mode.", 10);
return;
}
logger($pa_config, "Generating event '$evento' for agent ID $id_agente module ID $id_agentmodule.", 10); logger($pa_config, "Generating event '$evento' for agent ID $id_agente module ID $id_agentmodule.", 10);
# Get module tags # Get module tags
my $module_tags = ''; my $module_tags = '';
if (defined ($tags) && ($tags ne '')) { if (defined ($tags) && ($tags ne '')) {
$module_tags = $tags $module_tags = $tags
} else { }
else {
if (defined ($id_agentmodule) && $id_agentmodule > 0) { if (defined ($id_agentmodule) && $id_agentmodule > 0) {
$module_tags = pandora_get_module_tags ($pa_config, $dbh, $id_agentmodule); $module_tags = pandora_get_module_tags ($pa_config, $dbh, $id_agentmodule);
} }
} }
# Set default values for optional parameters # Set default values for optional parameters
$source = 'Pandora' unless defined ($source); $source = 'Pandora' unless defined ($source);
$comment = '' unless defined ($comment); $comment = '' unless defined ($comment);
$id_extra = '' unless defined ($id_extra); $id_extra = '' unless defined ($id_extra);
$user_name = '' unless defined ($user_name); $user_name = '' unless defined ($user_name);
my $utimestamp = time (); my $utimestamp = time ();
my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime ($utimestamp)); my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime ($utimestamp));
$id_agentmodule = 0 unless defined ($id_agentmodule); $id_agentmodule = 0 unless defined ($id_agentmodule);
@ -2711,23 +2746,23 @@ sub pandora_self_monitoring ($$) {
$xml_output .=" <type>generic_data</type>"; $xml_output .=" <type>generic_data</type>";
$xml_output .=" <data>$load_average</data>"; $xml_output .=" <data>$load_average</data>";
$xml_output .=" </module>"; $xml_output .=" </module>";
$xml_output .=" <module>"; $xml_output .=" <module>";
$xml_output .=" <name>Free_RAM</name>"; $xml_output .=" <name>Free_RAM</name>";
$xml_output .=" <type>generic_data</type>"; $xml_output .=" <type>generic_data</type>";
$xml_output .=" <data>$free_mem</data>"; $xml_output .=" <data>$free_mem</data>";
$xml_output .=" </module>"; $xml_output .=" </module>";
$xml_output .=" <module>"; $xml_output .=" <module>";
$xml_output .=" <name>FreeDisk_SpoolDir</name>"; $xml_output .=" <name>FreeDisk_SpoolDir</name>";
$xml_output .=" <type>generic_data</type>"; $xml_output .=" <type>generic_data</type>";
$xml_output .=" <data>$free_disk_spool</data>"; $xml_output .=" <data>$free_disk_spool</data>";
$xml_output .=" </module>"; $xml_output .=" </module>";
$xml_output .= "</agent_data>"; $xml_output .= "</agent_data>";
my $filename = $pa_config->{"incomingdir"}."/".$pa_config->{'servername'}.".".$utimestamp.".data"; my $filename = $pa_config->{"incomingdir"}."/".$pa_config->{'servername'}.".".$utimestamp.".data";
open (XMLFILE, ">> $filename") or die "[FATAL] Could not open internal monitoring XML file for deploying monitorization at '$filename'"; open (XMLFILE, ">> $filename") or die "[FATAL] Could not open internal monitoring XML file for deploying monitorization at '$filename'";
print XMLFILE $xml_output; print XMLFILE $xml_output;
close (XMLFILE); close (XMLFILE);
@ -2742,34 +2777,37 @@ Set the status of unknown modules.
########################################################################## ##########################################################################
sub pandora_module_unknown ($$) { sub pandora_module_unknown ($$) {
my ($pa_config, $dbh) = @_; my ($pa_config, $dbh) = @_;
my @modules = get_db_rows ($dbh, 'SELECT tagente_modulo.*, tagente_estado.id_agente_estado my @modules = get_db_rows ($dbh, 'SELECT tagente_modulo.*,
FROM tagente_modulo, tagente_estado, tagente tagente_estado.id_agente_estado
WHERE tagente.id_agente = tagente_estado.id_agente FROM tagente_modulo, tagente_estado, tagente
AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo WHERE tagente.id_agente = tagente_estado.id_agente
AND tagente.disabled = 0 AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo
AND tagente_modulo.disabled = 0 AND tagente.disabled = 0
AND tagente_estado.estado <> 3 AND tagente_modulo.disabled = 0
AND tagente_modulo.id_tipo_modulo NOT IN (21, 22, 23, 100) AND tagente_estado.estado <> 3
AND (tagente_estado.current_interval = 0 OR (tagente_estado.current_interval * 2) + tagente_estado.utimestamp < UNIX_TIMESTAMP())'); AND tagente_modulo.id_tipo_modulo NOT IN (21, 22, 23, 100)
AND (tagente_estado.current_interval = 0
OR (tagente_estado.current_interval * 2) + tagente_estado.utimestamp < UNIX_TIMESTAMP())');
foreach my $module (@modules) { foreach my $module (@modules) {
# Set the module state to unknown # Set the module state to unknown
logger ($pa_config, "Module " . $module->{'nombre'} . " is going to UNKNOWN", 10); logger ($pa_config, "Module " . $module->{'nombre'} . " is going to UNKNOWN", 10);
db_do ($dbh, 'UPDATE tagente_estado SET last_status = estado, estado = 3 WHERE id_agente_estado = ?', $module->{'id_agente_estado'}); db_do ($dbh, 'UPDATE tagente_estado SET last_status = estado, estado = 3 WHERE id_agente_estado = ?', $module->{'id_agente_estado'});
# Get agent information # Get agent information
my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE id_agente = ?', $module->{'id_agente'}); my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE id_agente = ?', $module->{'id_agente'});
if (! defined ($agent)) { if (! defined ($agent)) {
logger($pa_config, "Agent ID " . $module->{'id_agente'} . " not found while executing unknown alerts for module '" . $module->{'nombre'} . "'.", 3); logger($pa_config, "Agent ID " . $module->{'id_agente'} . " not found while executing unknown alerts for module '" . $module->{'nombre'} . "'.", 3);
return; return;
} }
# Generate alerts # Generate alerts
if (pandora_inhibit_alerts ($pa_config, $agent, $dbh, 0) == 0) { if (pandora_inhibit_alerts ($pa_config, $agent, $dbh, 0) == 0) {
pandora_generate_alerts ($pa_config, 0, 3, $agent, $module, time (), $dbh, undef, undef, 0, 'unknown'); pandora_generate_alerts ($pa_config, 0, 3, $agent, $module, time (), $dbh, undef, undef, 0, 'unknown');
} else { }
else {
logger($pa_config, "Alerts inhibited for agent '" . $agent->{'nombre'} . "'.", 10); logger($pa_config, "Alerts inhibited for agent '" . $agent->{'nombre'} . "'.", 10);
} }
} }
@ -2784,7 +2822,7 @@ Get a list of module tags in the format: |tag|tag| ... |tag|
########################################################################## ##########################################################################
sub pandora_get_module_tags ($$$) { sub pandora_get_module_tags ($$$) {
my ($pa_config, $dbh, $id_agentmodule) = @_; my ($pa_config, $dbh, $id_agentmodule) = @_;
my @tags = get_db_rows ($dbh, 'SELECT ' . db_concat('ttag.name', 'ttag.url') . ' name_url FROM ttag, ttag_module my @tags = get_db_rows ($dbh, 'SELECT ' . db_concat('ttag.name', 'ttag.url') . ' name_url FROM ttag, ttag_module
WHERE ttag.id_tag = ttag_module.id_tag WHERE ttag.id_tag = ttag_module.id_tag
AND ttag_module.id_agente_modulo = ?', $id_agentmodule); AND ttag_module.id_agente_modulo = ?', $id_agentmodule);

View File

@ -36,30 +36,30 @@ our @ServerSuffixes;
# Server class constructor. # Server class constructor.
######################################################################################## ########################################################################################
sub new ($$$;$) { sub new ($$$;$) {
my $class = shift; my $class = shift;
my $self = { my $self = {
_pa_config => shift, _pa_config => shift,
_server_id => 0, _server_id => 0,
_server_type => shift, _server_type => shift,
_dbh => shift, _dbh => shift,
_num_threads => 1, _num_threads => 1,
_threads => [], _threads => [],
_queue_size => 0, _queue_size => 0,
_errstr => '' _errstr => ''
}; };
# Share variables that may be set from different threads # Share variables that may be set from different threads
share ($self->{'_queue_size'}); share ($self->{'_queue_size'});
share ($self->{'_errstr'}); share ($self->{'_errstr'});
# Thread kill signal handler # Thread kill signal handler
#$SIG{'KILL'} = sub { #$SIG{'KILL'} = sub {
# threads->exit() if threads->can('exit'); # threads->exit() if threads->can('exit');
# exit(); # exit();
#}; #};
bless $self, $class; bless $self, $class;
return $self; return $self;
} }
######################################################################################## ########################################################################################