Merge branch 'handle-unknown-properly' of https://github.com/uchida/pandorafms into uchida-handle-unknown-properly

This commit is contained in:
Ramon Novoa 2016-07-28 12:50:58 +02:00
commit 798fa8e952
10 changed files with 314 additions and 26 deletions

View File

@ -15,6 +15,8 @@ ALTER TABLE tserver ADD COLUMN `server_keepalive` int(11) DEFAULT 0;
-- ----------------------------------------------------------------------
ALTER TABLE tagente_estado MODIFY `status_changes` tinyint(4) unsigned default 0;
ALTER TABLE tagente_estado CHANGE `last_known_status` `known_status` tinyint(4) default 0;
ALTER TABLE tagente_estado ADD COLUMN `last_known_status` tinyint(4) default 0;
-- ---------------------------------------------------------------------
-- Table `talert_actions`

View File

@ -10,6 +10,13 @@ ALTER TABLE talert_templates ADD COLUMN min_alerts_reset_counter NUMBER(5, 0) DE
ALTER TABLE tserver ADD COLUMN server_keepalive NUMBER(10, 0) DEFAULT 0;
-- ----------------------------------------------------------------------
-- Table `tagente_estado`
-- ----------------------------------------------------------------------
ALTER TABLE tagente_estado RENAME COLUMN last_known_status TO known_status;
ALTER TABLE tagente_estado ADD COLUMN last_known_status NUMBER(10, 0) DEFAULT 0;
-- ---------------------------------------------------------------------
-- Table `talert_actions`
-- ---------------------------------------------------------------------

View File

@ -0,0 +1,6 @@
-- ----------------------------------------------------------------------
-- Table `tagente_estado`
-- ----------------------------------------------------------------------
ALTER TABLE tagente_estado RENAME COLUMN last_known_status TO known_status;
ALTER TABLE tagente_estado ADD COLUMN last_known_status NUMBER(10, 0) DEFAULT 0;

View File

@ -534,6 +534,7 @@ function modules_create_agent_module ($id_agent, $name, $values = false, $disabl
'datos' => 0,
'timestamp' => '01-01-1970 00:00:00',
'estado' => $status,
'known_status' => $status,
'id_agente' => (int) $id_agent,
'utimestamp' => 0,
'status_changes' => 0,
@ -547,6 +548,7 @@ function modules_create_agent_module ($id_agent, $name, $values = false, $disabl
'datos' => 0,
'timestamp' => null,
'estado' => $status,
'known_status' => $status,
'id_agente' => (int) $id_agent,
'utimestamp' => 0,
'status_changes' => 0,
@ -560,6 +562,7 @@ function modules_create_agent_module ($id_agent, $name, $values = false, $disabl
'datos' => 0,
'timestamp' => '#to_date(\'1970-01-01 00:00:00\', \'YYYY-MM-DD HH24:MI:SS\')',
'estado' => $status,
'known_status' => $status,
'id_agente' => (int) $id_agent,
'utimestamp' => 0,
'status_changes' => 0,
@ -1558,7 +1561,7 @@ function modules_get_agentmodule_status($id_agentmodule = 0, $without_alerts = f
function modules_get_agentmodule_last_status($id_agentmodule = 0) {
$status_row = db_get_row ("tagente_estado", "id_agente_modulo", $id_agentmodule);
return $status_row['last_known_status'];
return $status_row['known_status'];
}
/**

View File

@ -178,6 +178,7 @@ CREATE TABLE tagente_estado (
datos CLOB DEFAULT '',
timestamp TIMESTAMP DEFAULT NULL,
estado NUMBER(10, 0) DEFAULT 0,
known_status NUMBER(10, 0) DEFAULT 0,
id_agente NUMBER(10, 0) DEFAULT 0,
last_try TIMESTAMP DEFAULT NULL,
utimestamp NUMBER(19, 0) DEFAULT 0,

View File

@ -148,6 +148,7 @@ CREATE TABLE "tagente_estado" (
"datos" text NOT NULL default '',
"timestamp" TIMESTAMP without time zone default '1970-01-01 00:00:00',
"estado" INTEGER NOT NULL default 0,
"known_status" INTEGER default 0,
"id_agente" INTEGER NOT NULL default 0,
"last_try" TIMESTAMP without time zone default '1970-01-01 00:00:00',
"utimestamp" BIGINT NOT NULL default 0,

View File

@ -144,6 +144,7 @@ CREATE TABLE IF NOT EXISTS `tagente_estado` (
`datos` text NOT NULL,
`timestamp` datetime NOT NULL default '1970-01-01 00:00:00',
`estado` int(4) NOT NULL default '0',
`known_status` tinyint(4) default 0,
`id_agente` int(10) NOT NULL default '0',
`last_try` datetime default NULL,
`utimestamp` bigint(20) NOT NULL default '0',

View File

@ -1338,6 +1338,7 @@ sub pandora_process_module ($$$$$$$$$;$) {
}
my $last_status = $agent_status->{'last_status'};
my $status = $agent_status->{'estado'};
my $known_status = $agent_status->{'known_status'};
my $status_changes = $agent_status->{'status_changes'};
my $last_data_value = $agent_status->{'datos'};
my $last_known_status = $agent_status->{'last_known_status'};
@ -1371,8 +1372,7 @@ sub pandora_process_module ($$$$$$$$$;$) {
$min_ff_event = $module->{'min_ff_event_warning'} if ($new_status == 2);
}
if ($last_status == $new_status || $last_status == 3) {
if ($last_known_status == $new_status) {
# Avoid overflows
$status_changes = $min_ff_event if ($status_changes > $min_ff_event);
@ -1393,10 +1393,9 @@ sub pandora_process_module ($$$$$$$$$;$) {
}
# Change status
if ($status_changes >= $min_ff_event && $status != $new_status) {
generate_status_event ($pa_config, $processed_data, $agent, $module, $new_status, $status, $last_known_status, $dbh);
if ($status_changes >= $min_ff_event && $known_status != $new_status) {
generate_status_event ($pa_config, $processed_data, $agent, $module, $new_status, $status, $known_status, $dbh);
$status = $new_status;
$last_status = $new_status;
# Update module status count.
$mark_for_update = 1;
@ -1404,24 +1403,19 @@ sub pandora_process_module ($$$$$$$$$;$) {
# Set not-init modules to normal status even if min_ff_event is not matched the first time they receive data.
# if critical or warning status, just pass through here and wait the time min_ff_event will be matched.
elsif ($status == 4) {
generate_status_event ($pa_config, $processed_data, $agent, $module, 0, $status, $last_known_status, $dbh);
generate_status_event ($pa_config, $processed_data, $agent, $module, 0, $status, $known_status, $dbh);
$status = 0;
$last_status = $new_status;
# Update module status count.
$mark_for_update = 1;
}
# If unknown modules receive data, restore status even if min_ff_event is not matched.
elsif ($status == 3) {
$last_status = $new_status; # Set last_status before forcing the module's new status to its last known status.
$new_status = $last_known_status; # Set the module to its last known status.
generate_status_event ($pa_config, $processed_data, $agent, $module, $new_status, $status, $last_known_status, $dbh);
$status = $last_known_status;
generate_status_event ($pa_config, $processed_data, $agent, $module, $known_status, $status, $known_status, $dbh);
$status = $known_status;
# Update module status count.
$mark_for_update = 1;
} else {
$last_status = $new_status;
}
# tagente_estado.last_try defaults to NULL, should default to '1970-01-01 00:00:00'
@ -1443,12 +1437,12 @@ sub pandora_process_module ($$$$$$$$$;$) {
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 = ?, last_known_status = ?,
SET datos = ?, estado = ?, known_status = ?, last_status = ?, last_known_status = ?,
status_changes = ?, utimestamp = ?, timestamp = ?,
id_agente = ?, current_interval = ?, running_by = ?,
last_execution_try = ?, last_try = ?, last_error = ?,
ff_start_utimestamp = ?
WHERE id_agente_modulo = ?', $processed_data, $status, $last_status, $status, $status_changes,
WHERE id_agente_modulo = ?', $processed_data, $status, $status, $new_status, $new_status, $status_changes,
$current_utimestamp, $timestamp, $module->{'id_agente'}, $current_interval, $server_id,
$utimestamp, ($save == 1) ? $timestamp : $agent_status->{'last_try'}, $last_error, $ff_start_utimestamp, $module->{'id_agente_modulo'});
@ -2569,9 +2563,9 @@ sub pandora_create_module ($$$$$$$$$$) {
'INSERT INTO tagente_modulo (id_agente, id_tipo_modulo, nombre, max, min, post_process, descripcion, module_interval, id_modulo, critical_instructions, warning_instructions, unknown_instructions, disabled_types_event, module_macros)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, \'\', \'\', \'\', \'\', \'\')',
$agent_id, $module_type_id, safe_input($module_name), $max, $min, $post_process, $description, $interval);
db_do ($dbh, 'INSERT INTO tagente_estado (id_agente_modulo, id_agente, estado, last_status, last_known_status, last_try, datos)
VALUES (?, ?, ?, ?, ?, \'1970-01-01 00:00:00\', \'\')',
$module_id, $agent_id, $status, $status, $status);
db_do ($dbh, 'INSERT INTO tagente_estado (id_agente_modulo, id_agente, estado, known_status, last_status, last_known_status, last_try, datos)
VALUES (?, ?, ?, ?, ?, ?, \'1970-01-01 00:00:00\', \'\')',
$module_id, $agent_id, $status, $status, $status, $status);
# Update the module status count. When the module is created disabled dont do it
pandora_mark_agent_for_module_update ($dbh, $agent_id);
@ -2703,7 +2697,7 @@ sub pandora_create_module_from_hash ($$$) {
$status = 0;
}
db_do ($dbh, 'INSERT INTO tagente_estado (id_agente_modulo, id_agente, estado, last_status, last_known_status, last_try, datos) VALUES (?, ?, ?, ?, ?, \'1970-01-01 00:00:00\', \'\')', $module_id, $parameters->{'id_agente'}, $status, $status, $status);
db_do ($dbh, 'INSERT INTO tagente_estado (id_agente_modulo, id_agente, estado, known_status, last_status, last_known_status, last_try, datos) VALUES (?, ?, ?, ?, ?, ?, \'1970-01-01 00:00:00\', \'\')', $module_id, $parameters->{'id_agente'}, $status, $status, $status, $status);
# Update the module status count. When the module is created disabled dont do it
pandora_mark_agent_for_module_update ($dbh, $parameters->{'id_agente'});
@ -3810,7 +3804,7 @@ sub pandora_validate_event ($$$) {
# Generates an event according to the change of status of a module.
##########################################################################
sub generate_status_event ($$$$$$$$) {
my ($pa_config, $data, $agent, $module, $status, $last_status, $last_known_status, $dbh) = @_;
my ($pa_config, $data, $agent, $module, $status, $last_status, $known_status, $dbh) = @_;
my ($event_type, $severity);
my $description = '';
@ -3831,7 +3825,7 @@ sub generate_status_event ($$$$$$$$) {
}
# disable event just recovering from 'Unknown' without status change
if($last_status == 3 && $status == $last_known_status && $module->{'disabled_types_event'} ) {
if($last_status == 3 && $status == $known_status && $module->{'disabled_types_event'} ) {
my $disabled_types_event;
eval {
local $SIG{__DIE__};
@ -3850,7 +3844,7 @@ sub generate_status_event ($$$$$$$$) {
if ($status == 0) {
# Do not generate an event when a module goes from notinit no normal
if ($last_known_status == 4) {
if ($known_status == 4) {
return;
}
@ -3864,7 +3858,7 @@ sub generate_status_event ($$$$$$$$) {
} elsif ($status == 2) {
# From critical
if ($last_known_status == 1) {
if ($known_status == 1) {
($event_type, $severity) = ('going_down_warning', 3);
$description = $pa_config->{"text_going_down_warning"};
}

View File

@ -0,0 +1,273 @@
use strict;
use warnings;
use Test::More;
use Scope::Guard;
use File::Basename;
use Data::Dumper;
use PandoraFMS::Core;
use PandoraFMS::Config;
use PandoraFMS::DB;
no lib '/usr/lib/perl5'; # disable @INC for system perl, because travis uses http://perlbrew.pl/.
my $conf;
my $dbh;
my $agent;
my $module;
my $module_with_ff;
my $ok = {data => 1};
my $ng = {data => 0};
BEGIN {
diag "startup\n";
$conf = {
quiet => 0, verbosity => 1, daemon => 0, PID => "",
pandora_path => dirname(__FILE__) . "/../conf/pandora_server.conf.new",
};
pandora_load_config($conf);
$dbh = db_connect (
'mysql', $conf->{'dbname'}, $conf->{'dbhost'},
$conf->{'dbport'}, $conf->{'dbuser'}, $conf->{'dbpass'}
);
my $agent_id = pandora_create_agent($conf, $conf->{servername}, "test", "", 10, 0, 1, '', 300, $dbh);
$agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE tagente.id_agente = ?', $agent_id);
}
END {
diag "shutdown\n";
pandora_delete_agent($dbh, $agent->{id_agente}, $conf);
}
sub teardown {
diag "teardown\n";
pandora_delete_module ($dbh, $module->{id_agente_modulo}, $conf);
pandora_delete_module ($dbh, $module_with_ff->{id_agente_modulo}, $conf);
}
sub setup {
diag "setup\n";
my $module_id = pandora_create_module_from_hash(
$conf,
{
id_agente => $agent->{id_agente}, id_tipo_modulo => 2,
nombre => "test", module_interval => 300, id_module_group => 1
},
$dbh
);
$module = get_db_single_row(
$dbh, 'SELECT * FROM tagente_modulo WHERE tagente_modulo.id_agente_modulo = ?', $module_id
);
pandora_process_module(
$conf, $ok, $agent, $module, '', '', time(), $conf->{servername}, $dbh
);
my $module_with_ff_id = pandora_create_module_from_hash(
$conf,
{
id_agente => $agent->{id_agente}, id_tipo_modulo => 2,
nombre => "test with FF", module_interval => 300, id_module_group => 1,
each_ff => 1, min_ff_event_normal => 0, min_ff_event_warning => 0, min_ff_event_critical => 2,
},
$dbh
);
$module_with_ff = get_db_single_row(
$dbh, 'SELECT * FROM tagente_modulo WHERE tagente_modulo.id_agente_modulo = ?', $module_with_ff_id
);
pandora_process_module(
$conf, $ok, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
return Scope::Guard->new(\&teardown);
}
subtest 'OK -> NG, finally status changes' => sub {
my $guard = setup();
my $status;
# OK
pandora_process_module(
$conf, $ok, $agent, $module, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status goes normal');
# NG
pandora_process_module(
$conf, $ng, $agent, $module, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module->{id_agente_modulo}
);
ok($status->{estado} == 1, 'status goes critical');
};
subtest 'OK -> UN -> NG, finally status changes' => sub {
my $guard = setup();
my $status;
# OK
pandora_process_module(
$conf, $ok, $agent, $module, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status goes normal');
# UNKNOWN
db_do(
$dbh, 'UPDATE tagente_estado SET last_status = 3, estado = 3 WHERE id_agente_modulo = ?', $module->{id_agente_modulo}
);
# NG
pandora_process_module(
$conf, $ng, $agent, $module, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module->{id_agente_modulo}
);
ok($status->{estado} == 1, 'status goes critical');
};
subtest 'with FF, OK -> NG -> NG -> NG, finally status changes' => sub {
my $guard = setup();
my $status;
# OK
pandora_process_module(
$conf, $ok, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status goes normal');
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status keeps normal due to FF');
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status keeps normal due to FF');
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 1, 'status goes critical, crossing the Rubicon');
};
subtest 'with FF, OK -> UN -> NG -> NG -> NG, status changes finally' => sub {
my $guard = setup();
my $status;
# OK
pandora_process_module(
$conf, $ok, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status goes normal');
# UNKNOWN
db_do(
$dbh, 'UPDATE tagente_estado SET last_status = 3, estado = 3 WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status keeps normal due to FF');
ok($status->{status_changes} == 0, 'status counter equal to 0');
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status keeps normal due to FF');
ok($status->{status_changes} == 1, 'status counter equal to 1');
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 1, 'status goes critical, crossing the Rubicon');
ok($status->{status_changes} == 2, 'status counter equal to 2');
};
subtest 'with FF, OK -> NG -> UN -> NG -> NG, status changes finally' => sub {
my $guard = setup();
my $status;
# OK
pandora_process_module(
$conf, $ok, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status goes normal');
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status keeps normal due to FF');
ok($status->{status_changes} == 0, 'status counter equal to 0');
# UNKNOWN
db_do(
$dbh, 'UPDATE tagente_estado SET last_status = 3, estado = 3 WHERE id_agente_estado = ?', $module_with_ff->{id_agente_modulo}
);
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 0, 'status keeps normal due to FF');
ok($status->{status_changes} == 1, 'status counter equal to 1');
# NG
pandora_process_module(
$conf, $ng, $agent, $module_with_ff, '', '', time(), $conf->{servername}, $dbh
);
$status = get_db_single_row(
$dbh, 'SELECT * FROM tagente_estado WHERE id_agente_modulo = ?', $module_with_ff->{id_agente_modulo}
);
ok($status->{estado} == 1, 'status goes critical, crossing the Rubicon');
ok($status->{status_changes} == 2, 'status counter equal to 1');
};
done_testing;

View File

@ -3482,8 +3482,8 @@ sub cli_create_synthetic() {
[$dbh,int($id_module), @filterdata]);
if ($result) {
db_do ($dbh, 'INSERT INTO tagente_estado (id_agente_modulo, id_agente, estado,
last_status, last_known_status, last_try, datos)
VALUES (?, ?, ?, ?, ?, \'1970-01-01 00:00:00\', \'\')', $id_module, $id_agent, 4, 4, 4);
known_status, last_status, last_known_status, last_try, datos)
VALUES (?, ?, ?, ?, ?, ?, \'1970-01-01 00:00:00\', \'\')', $id_module, $id_agent, 4, 4, 4, 4);
# Update the module status count. When the module is created disabled dont do it
pandora_mark_agent_for_module_update ($dbh, $id_agent);
print("[OK] The modules are creating ID: $id_module \n\n");