From 272ff3ec26a843cf40d6989a86451483c9bb6b8a Mon Sep 17 00:00:00 2001 From: Ramon Novoa Date: Thu, 31 Jan 2013 18:02:41 +0000 Subject: [PATCH] 2013-01-31 Ramon Novoa * bin/pandora_server, conf/pandora_server.conf, lib/PandoraFMS/Config.pm, lib/PandoraFMS/Core.pm, util/pandora_manage.pl: Added support for event storm protection and disabling auto event validation. * lib/PandoraFMS/Server.pm: Improved the server status update function to use run less queries. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7556 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f --- pandora_server/ChangeLog | 12 +++++ pandora_server/bin/pandora_server | 8 +-- pandora_server/conf/pandora_server.conf | 5 ++ pandora_server/lib/PandoraFMS/Config.pm | 7 +++ pandora_server/lib/PandoraFMS/Core.pm | 72 +++++++++++++++++-------- pandora_server/lib/PandoraFMS/Server.pm | 13 ++++- pandora_server/util/pandora_manage.pl | 23 ++++++++ 7 files changed, 114 insertions(+), 26 deletions(-) diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index 32a867952d..e64b620c15 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,15 @@ +2013-01-31 Ramon Novoa + + * bin/pandora_server, + conf/pandora_server.conf, + lib/PandoraFMS/Config.pm, + lib/PandoraFMS/Core.pm, + util/pandora_manage.pl: Added support for event storm protection and + disabling auto event validation. + + * lib/PandoraFMS/Server.pm: Improved the server status update function + to use run less queries. + 2013-01-28 Miguel de Dios * util/pandora_xml_stress.pl: fixed the typo messages error that diff --git a/pandora_server/bin/pandora_server b/pandora_server/bin/pandora_server index 3398fb4dcd..9751db1049 100755 --- a/pandora_server/bin/pandora_server +++ b/pandora_server/bin/pandora_server @@ -198,8 +198,8 @@ sub pandora_start_netflow_daemon () { # Check if netflow is enabled if ($Config{'activate_netflow'} != 1) { - logger (\%Config, "[*] Netflow daemon disabled.", 1); - print_message (\%Config, "[*] Netflow daemon disabled.", 1); + logger (\%Config, " [*] Netflow daemon disabled.", 1); + print_message (\%Config, " [*] Netflow daemon disabled.", 1); return; } @@ -331,7 +331,9 @@ while (1) { # Set the status of unknown modules pandora_module_unknown (\%Config, $DBH); - + + # Set event storm protection + pandora_set_event_storm_protection (pandora_get_tconfig_token ($DBH, 'event_storm_protection', 0)); } # TASKS DONE EACH 60 SECONDS (Low latency tasks) diff --git a/pandora_server/conf/pandora_server.conf b/pandora_server/conf/pandora_server.conf index 4e503a5107..f6e62b3efe 100755 --- a/pandora_server/conf/pandora_server.conf +++ b/pandora_server/conf/pandora_server.conf @@ -362,3 +362,8 @@ policy_manager 1 # If set to 1, the event replicate process is enabled. 0 by default. (PANDORA FMS ENTERPRISE ONLY) # WARNING: This process doesn't do anything if is not properly configured from the console setup event_replication 1 + +# If set to 1, new events validate older event for the same module. This will +# affect the performance of the server. +event_auto_validation 1 + diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 9994c4828f..6a5efd7569 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -290,6 +290,9 @@ sub pandora_load_config { # Event replication process $pa_config->{"event_replication"} = 0; # 5.0 + # Event auto-validation + $pa_config->{"event_auto_validation"} = 1; # 5.0 + # ------------------------------------------------------------------------- # This values are not stored in .conf files. # This values should be stored in database, not in .conf files! @@ -298,6 +301,7 @@ sub pandora_load_config { $pa_config->{"realtimestats"} = 0; $pa_config->{"stats_interval"} = 300; $pa_config->{"agentaccess"} = 1; + $pa_config->{"event_storm_protection"} = 0; # ------------------------------------------------------------------------- # Check for UID0 @@ -636,6 +640,9 @@ sub pandora_load_config { elsif ($parametro =~ m/^event_replication\s+([0-1])/i) { $pa_config->{'event_replication'}= clean_blank($1); } + elsif ($parametro =~ m/^event_auto_validation\s+([0-1])/i) { + $pa_config->{'event_auto_validation'}= clean_blank($1); + } } # end of loop for parameter # # Set to RDBMS' standard port diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 21462cc879..3521d6765c 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -106,6 +106,8 @@ use XML::Simple; use HTML::Entities; use Time::Local; use POSIX qw(strftime); +use threads; +use threads::shared; # Force XML::Simple to use XML::Parser instead SAX to manage XML # due a bug processing some XML with blank spaces. @@ -172,6 +174,7 @@ our @EXPORT = qw( pandora_process_module pandora_reset_server pandora_server_keep_alive + pandora_set_event_storm_protection pandora_update_agent pandora_update_agent_address pandora_update_config_token @@ -187,6 +190,7 @@ our @EXPORT = qw( get_agent_from_addr get_agent_from_name @ServerTypes + $EventStormProtection ); # Some global variables @@ -194,6 +198,8 @@ our @DayNames = qw(sunday monday tuesday wednesday thursday friday saturday); our @ServerTypes = qw (dataserver networkserver snmpconsole reconserver pluginserver predictionserver wmiserver exportserver inventoryserver webserver eventserver icmpserver snmpserver); our @AlertStatus = ('Execute the alert', 'Do not execute the alert', 'Do not execute the alert, but increment its internal counter', 'Cease the alert', 'Recover the alert', 'Reset internal counter'); +# Event storm protection (no alerts or events) +our $EventStormProtection :shared = 0; ########################################################################## # Return the agent given the IP address. @@ -231,6 +237,11 @@ Generate alerts for a given I<$module>. ########################################################################## sub pandora_generate_alerts ($$$$$$$$;$$$) { my ($pa_config, $data, $status, $agent, $module, $utimestamp, $dbh, $timestamp, $extra_macros, $last_data_value, $alert_type) = @_; + + # No alerts when event storm protection is enabled + if ($EventStormProtection == 1) { + return; + } if ($agent->{'quiet'} == 1) { logger($pa_config, "Generate Alert. The agent '" . $agent->{'nombre'} . "' is in quiet mode.", 10); @@ -1735,7 +1746,7 @@ sub pandora_reset_server ($$) { } ########################################################################## -=head2 C<< pandora_update_server (I<$pa_config>, I<$dbh>, I<$server_name>, I<$status>, I<$server_type>, I<$num_threads>, I<$queue_size>) >> +=head2 C<< pandora_update_server (I<$pa_config>, I<$dbh>, I<$server_name>, I<$server_id>, I<$status>, I<$server_type>, I<$num_threads>, I<$queue_size>) >> Update server status: 0 dataserver @@ -1748,40 +1759,41 @@ Update server status: =cut ########################################################################## -sub pandora_update_server ($$$$$;$$) { - my ($pa_config, $dbh, $server_name, $status, +sub pandora_update_server ($$$$$$;$$) { + my ($pa_config, $dbh, $server_name, $server_id, $status, $server_type, $num_threads, $queue_size) = @_; $num_threads = 0 unless defined ($num_threads); $queue_size = 0 unless defined ($queue_size); - my $server = get_db_single_row ($dbh, 'SELECT * FROM tserver WHERE name = ? AND server_type = ?', $server_name, $server_type); my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime()); - - # Create an entry in tserver - if (! defined ($server)){ - my $server_id = db_insert ($dbh, 'id_server', 'INSERT INTO tserver (name, server_type, description, version, threads, queued_modules) + + # First run + if ($server_id == 0) { + + # Create an entry in tserver if needed + my $server = get_db_single_row ($dbh, 'SELECT id_server FROM tserver WHERE name = ? AND server_type = ?', $server_name, $server_type); + if (! defined ($server)) { + $server_id = db_insert ($dbh, 'id_server', 'INSERT INTO tserver (name, server_type, description, version, threads, queued_modules) VALUES (?, ?, ?, ?, ?, ?)', $server_name, $server_type, 'Autocreated at startup', $pa_config->{'version'} . ' (P) ' . $pa_config->{'build'}, $num_threads, $queue_size); - $server = get_db_single_row ($dbh, 'SELECT * FROM tserver WHERE id_server = ?', $server_id); - if (! defined ($server)) { - logger($pa_config, "Server '" . $pa_config->{'servername'} . "' not found.", 3); - return; + + $server = get_db_single_row ($dbh, 'SELECT status FROM tserver WHERE id_server = ?', $server_id); + if (! defined ($server)) { + logger($pa_config, "Server '" . $pa_config->{'servername'} . "' not found.", 3); + return; + } } - } - - # Server going up - if ($server->{'status'} == 0) { + my $version = $pa_config->{'version'} . ' (P) ' . $pa_config->{'build'}; - db_do ($dbh, 'UPDATE tserver SET status = ?, keepalive = ?, master = ?, laststart = ?, version = ?, threads = ?, queued_modules = ? WHERE id_server = ?', - $status, $timestamp, $pa_config->{'pandora_master'}, $timestamp, $version, $num_threads, $queue_size, $server->{'id_server'}); + 1, $timestamp, $pa_config->{'pandora_master'}, $timestamp, $version, $num_threads, $queue_size, $server_id); return; } db_do ($dbh, 'UPDATE tserver SET status = ?, keepalive = ?, master = ?, threads = ?, queued_modules = ? - WHERE id_server = ?', $status, $timestamp, $pa_config->{'pandora_master'}, $num_threads, $queue_size, $server->{'id_server'}); + WHERE id_server = ?', $status, $timestamp, $pa_config->{'pandora_master'}, $num_threads, $queue_size, $server_id); } ########################################################################## @@ -2904,7 +2916,7 @@ sub get_module_status ($$$) { ########################################################################## sub pandora_validate_event ($$$) { my ($pa_config, $id_agentmodule, $dbh) = @_; - if (!defined($id_agentmodule)){ + if (!defined($id_agentmodule) || $pa_config->{"event_auto_validation"} == 0) { return; } @@ -2921,11 +2933,22 @@ sub generate_status_event ($$$$$$$$) { my ($event_type, $severity); my $description = "Module " . safe_output($module->{'nombre'}) . " (".safe_output($data).") is "; + # No events when event storm protection is enabled + if ($EventStormProtection == 1) { + return; + } + # Mark as "validated" any previous event for this module pandora_validate_event ($pa_config, $module->{'id_agente_modulo'}, $dbh); # Normal if ($status == 0) { + + # Do not generate an event when a module goes from notinit no normal + if ($last_known_status == 4) { + return; + } + ($event_type, $severity) = ('going_down_normal', 2); $description .= "going to NORMAL"; # Critical @@ -2936,7 +2959,7 @@ sub generate_status_event ($$$$$$$$) { } elsif ($status == 2) { # From normal - if ($last_known_status == 0) { + if ($last_known_status == 0 || $last_known_status == 4) { ($event_type, $severity) = ('going_up_warning', 3); $description .= "going to WARNING"; @@ -3727,6 +3750,13 @@ sub update_module_status_count ($$$$) { db_do ($dbh, "UPDATE tagente SET $query_sub, $query_add WHERE id_agente=?", $agent->{'id_agente'}); } +########################################################################## +# Set or unset silent mode. +########################################################################## +sub pandora_set_event_storm_protection ($) { + $EventStormProtection = shift; +} + # End of function declaration # End of defined Code diff --git a/pandora_server/lib/PandoraFMS/Server.pm b/pandora_server/lib/PandoraFMS/Server.pm index b33eb33260..3c04845e12 100644 --- a/pandora_server/lib/PandoraFMS/Server.pm +++ b/pandora_server/lib/PandoraFMS/Server.pm @@ -190,6 +190,15 @@ sub getErrStr ($) { return $self->{'_errstr'}; } +######################################################################################## +# Set event storm protection. +######################################################################################## +sub setEventStormProtection ($) { + my ($self, $event_storm_protection) = @_; + + $PandoraFMS::Core::EventStormProtection = $event_storm_protection; +} + ######################################################################################## # Add a thread to the server thread list. ######################################################################################## @@ -258,7 +267,7 @@ sub update ($) { my $self = shift; eval { - pandora_update_server ($self->{'_pa_config'}, $self->{'_dbh'}, $self->{'_pa_config'}->{'servername'}, + pandora_update_server ($self->{'_pa_config'}, $self->{'_dbh'}, $self->{'_pa_config'}->{'servername'}, $self->{'_server_id'}, 1, $self->{'_server_type'}, $self->{'_num_threads'}, $self->{'_queue_size'}); }; } @@ -271,7 +280,7 @@ sub stop ($) { eval { # Update server status - pandora_update_server ($self->{'_pa_config'}, $self->{'_dbh'}, $self->{'_pa_config'}->{'servername'}, + pandora_update_server ($self->{'_pa_config'}, $self->{'_dbh'}, $self->{'_pa_config'}->{'servername'}, $self->{'_server_id'}, 0, $self->{'_server_type'}, 0, 0); }; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 55539a9b2b..c84db2ffdb 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -157,6 +157,8 @@ sub help_screen{ help_screen_line('--create_netflow_filter', ' ', 'Create a new netflow filter'); print "TOOLS:\n\n" unless $param ne ''; help_screen_line('--exec_from_file', ' ', 'Execute any CLI option with macros from CSV file'); + print "SETUP:\n\n" unless $param ne ''; + help_screen_line('--set_event_storm_protection', '', 'Enable (1) or disable (0) event storm protection'); print "\n"; exit; @@ -3210,6 +3212,23 @@ sub cli_module_get_data () { exit; } +############################################################################## +# Enable or disable event flow protection +# Related option: --create_netflow_filter +############################################################################## +sub cli_set_event_storm_protection () { + my $value = @ARGV[2]; + + # Check for a valid value + if ($value != 0 && $value != 1) { + print_log "[ERROR] Invalid value: $value. Value must be either 0 or 1\n\n"; + return; + } + + # Set the value of event + db_do ($dbh, 'UPDATE tconfig SET value=? WHERE token=?', $value, 'event_storm_protection'); +} + ############################################################################## # Return event name given a event id ############################################################################## @@ -3524,6 +3543,10 @@ sub pandora_manage_main ($$$) { param_check($ltotal, 5); cli_create_netflow_filter(); } + elsif ($param eq '--set_event_storm_protection') { + param_check($ltotal, 1); + cli_set_event_storm_protection(); + } else { print_log "[ERROR] Invalid option '$param'.\n\n"; $param = '';