From f128742b02f68b5fb11ad6ec46ee2c86022607ba Mon Sep 17 00:00:00 2001 From: slerena Date: Wed, 20 Feb 2008 02:09:36 +0000 Subject: [PATCH] 2008-02-20 Sancho Lerena * Merged latest changes on stable branch to trunk. Let's go to 1.4 version !! git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@722 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f --- pandora_server/ChangeLog | 76 +++++++ pandora_server/bin/pandora_network | 257 ++++++++++++------------ pandora_server/bin/pandora_server | 34 ++-- pandora_server/bin/pandora_snmpconsole | 7 +- pandora_server/conf/pandora_server.conf | 31 ++- pandora_server/lib/PandoraFMS/Config.pm | 88 +++++--- pandora_server/lib/PandoraFMS/DB.pm | 122 ++++++----- pandora_server/util/pandora_db.pl | 2 +- 8 files changed, 382 insertions(+), 235 deletions(-) diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index 8e791be4ad..6b1eb7f811 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,79 @@ + +2008-02-20 Sancho Lerena + + * Merged latest changes on stable branch to trunk. Let's go to + 1.4 version !! + +2008-02-13 Sancho Lerena + + * pandora_server.conf: Added default entry for + snmp_proc_deadresponse + + * pandora_network: Fixed problems for snmp_proc module. Tested on + heavy load systems. Now works very fine. + +2008-02-10 Sancho Lerena + + * Config.pm: Added support for new config token: + snmp_proc_deadresponse. Used to report bad monitor status from + snmp if a snmp monitor request have errors (timeout or unknown OID) + + * pandora_network: Fixed bug for float data in snmp_data modules and + negative values. Code cleanup and trying a new method (more fast and + simple) to get SNMP data (using get method instead getnext). Better + error detection and reporting. Pending to test in heavy loaded envi- + ronment locking mechanism for session contruction. + +2008-01-25 Sancho Lerena + + * lib/PandoraFMS/Config.pm, bin/pandora_network, + conf/pandora_server.conf: New options for tcp/snmp retries and timout + +2008-01-21 Sancho Lerena + + * pandora_db.pl: Disable compactation until fix bug in compactation + function that currently delete data insted compacting it. + +2008-01-14 Sancho Lerena + + * conf/pandora_server.conf: New token for activate alert recovery: + alert_recovery 1/0 (disabled by default to retain compatibility). + + * Config.pm: Support for new alert_recovery option. + + * DB.pm: Implementation for alert_recovery option. Added flag to pass + to execute_alert function to do not create event on alert firing due + event is previously generated on calculate_alert function. Changes for + management of data_proc type. If data is invalid (void or "") now this + situation is managed as "invalid data" or "cannot get data" and set to + "BAD" status and data 0 to have the same behaviour that icmp_proc and + tcp_proc (snmp_proc behaviour is also changed in pandora_network on this + commit also). + + * pandora_snmpconsole: Fixes call for execute_alert (added flag to 1). + + * pandora_network: snmp_proc returns 0 value and bad status if cannot + contact or cannot set SNMP session (read above). + +2008-01-11 Sancho Lerena + + * DB.pm: Fixed alert management for KeepAlive module. (Optional) Code for + notify on alert recovery. + + * pandora_network: Better management of thread locking. This should fix + latests problems reported. + +2008-01-10 Sancho Lerena + + * Config.pm: Version number update. + + * DB.pm: Support to manage keepalive modules in the correct way (more fixes) + + * pandora_server: Minimal improvement on zero data files, and new keepalive + mamagement (more fixes over yesterday code). + + This is the first 1.3.1 version commit (Server) + 2008-01-08 Sancho Lerena * Config.pm: Updated version to 1.3.1-dev diff --git a/pandora_server/bin/pandora_network b/pandora_server/bin/pandora_network index 75c9b75a59..244d3b0c14 100755 --- a/pandora_server/bin/pandora_network +++ b/pandora_server/bin/pandora_network @@ -2,8 +2,8 @@ ########################################################################## # Pandora FMS Network Server ########################################################################## -# Copyright (c) 2006-2007 Sancho Lerena, slerena@gmail.com -# (c) 2006-2007 Artica Soluciones Tecnologicas S.L +# Copyright (c) 2006-2008 Sancho Lerena, slerena@gmail.com +# (c) 2006-2008 Artica Soluciones Tecnologicas S.L # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 @@ -25,7 +25,7 @@ use Time::Local; # DateTime basic manipulation use Net::Ping; # For ICMP latency use Time::HiRes; # For high precission timedate functions (Net::Ping) use IO::Socket; # For TCP/UDP access -use SNMP; # For SNMP access (libsnmp-perl PACKAGE!) +use SNMP; # For SNMP access (libsnmp-perl PACKAGE!) use threads; use threads::shared; @@ -45,8 +45,11 @@ my %pending_task_hash : shared; my %current_task_hash : shared; my $snmp_lock : shared; my $icmp_lock : shared; +my $queue_lock : shared; $ENV{'MIBS'}="ALL"; #Load all available MIBs only once +&SNMP::initMib(); + $SIG{'TERM'} = 'pandora_shutdown'; $SIG{'INT'} = 'pandora_shutdown'; @@ -136,11 +139,9 @@ sub pandora_network_consumer ($$) { # Insert this element on the current task hash if (scalar(@pending_task) > 0){ { - lock @pending_task; + lock $queue_lock; $data_id_agent_module = shift(@pending_task); - lock %pending_task_hash; delete($pending_task_hash{$data_id_agent_module}); - lock %current_task_hash; $current_task_hash{$data_id_agent_module}=1; } @@ -157,7 +158,7 @@ sub pandora_network_consumer ($$) { # Remove from queue. If catch an error, probably data is # not been processed, but has been freed from task queue { - lock %current_task_hash; + lock $queue_lock; delete($current_task_hash{$data_id_agent_module}); } $counter = 0; @@ -239,9 +240,8 @@ sub pandora_network_producer ($) { } # Locking scope, do not remove redundant { } { - lock @pending_task; + lock $queue_lock; push (@pending_task, $data_id_agente_modulo); - lock %pending_task_hash; $pending_task_hash {$data_id_agente_modulo}=1; } } @@ -336,77 +336,86 @@ sub pandora_query_tcp (%$$$$$$$) { my $tcp_send = $_[5]; my $tcp_rcv = $_[6]; my $id_tipo_modulo = $_[7]; - - my $temp; my $temp2; - my $tam; - my $handle=IO::Socket::INET->new( - Proto=>"tcp", - PeerAddr=>$ip_target, - Timeout=>$pa_config->{'networktimeout'}, - PeerPort=>$tcp_port, - Blocking=>0 ); # Non blocking !!, very important ! - - if (defined($handle)){ - if ($tcp_send ne ""){ # its Expected to sending data ? - # Send data - $handle->autoflush(1); - $tcp_send =~ s/\^M/\r\n/g; - # Replace Carriage rerturn and line feed - $handle->send($tcp_send); - } - # we expect to receive data ? (non proc types) - if (($tcp_rcv ne "") || ($id_tipo_modulo == 10) || ($id_tipo_modulo ==8) || ($id_tipo_modulo == 11)) { - # Receive data, non-blocking !!!! (VERY IMPORTANT!) - $temp2 = ""; - for ($tam=0; $tam<($pa_config->{'networktimeout'}); $tam++){ - $handle->recv($temp,16000,0x40); - $temp2 = $temp2.$temp; - if ($temp ne ""){ - $tam++; # If doesnt receive data, increase counter - } - sleep(1); - } - if ($id_tipo_modulo == 9){ # only for TCP Proc - if ($temp2 =~ /$tcp_rcv/i){ # String match ! - $$module_data = 1; - $$module_result = 0; - } else { - $$module_data = 0; - $$module_result = 0; - } - } elsif ($id_tipo_modulo == 10 ){ # TCP String (no int conversion)! - $$module_data = $temp2; - $$module_result =0; - } else { # TCP Data numeric (inc or data) - if ($temp2 ne ""){ - if ($temp2 =~ /[A-Za-z\.\,\-\/\\\(\)\[\]]/){ - $$module_result = 1; - $$module_data = 0; # invalid data - } else { - $$module_data = int($temp2); - $$module_result = 0; # Successful - } - } else { - $$module_result = 1; - $$module_data = 0; # invalid data - } - } - } else { # No expected data to receive, if connected and tcp_proc type successful - if ($id_tipo_modulo == 9){ # TCP Proc - $$module_result = 0; - $$module_data = 1; - } - } - $handle->close(); - undef ($handle); - } else { # Cannot connect (open sock failed) - $$module_result = 1; # Fail - if ($id_tipo_modulo == 9){ # TCP Proc - $$module_result = 0; - $$module_data = 0; # Failed, but data exists - } - } + my $counter; + for ($counter =0; $counter < $pa_config->{'tcp_checks'}; $counter++){ + my $temp; my $temp2; + my $tam; + my $handle=IO::Socket::INET->new( + Proto=>"tcp", + PeerAddr=>$ip_target, + Timeout=>$pa_config->{'tcp_timeout'}, + PeerPort=>$tcp_port, + Blocking=>0 ); # Non blocking !!, very important ! + + if (defined($handle)){ + if ($tcp_send ne ""){ # its Expected to sending data ? + # Send data + $handle->autoflush(1); + $tcp_send =~ s/\^M/\r\n/g; + # Replace Carriage rerturn and line feed + $handle->send($tcp_send); + } + # we expect to receive data ? (non proc types) + if (($tcp_rcv ne "") || ($id_tipo_modulo == 10) || ($id_tipo_modulo ==8) || ($id_tipo_modulo == 11)) { + # Receive data, non-blocking !!!! (VERY IMPORTANT!) + $temp2 = ""; + for ($tam=0; $tam<($pa_config->{'tcp_timeout'}); $tam++){ + $handle->recv($temp,16000,0x40); + $temp2 = $temp2.$temp; + if ($temp ne ""){ + $tam++; # If doesnt receive data, increase counter + } + sleep(1); + } + if ($id_tipo_modulo == 9){ # only for TCP Proc + if ($temp2 =~ /$tcp_rcv/i){ # String match ! + $$module_data = 1; + $$module_result = 0; + $counter = $pa_config->{'tcp_checks'}; + } else { + $$module_data = 0; + $$module_result = 0; + $counter = $pa_config->{'tcp_checks'}; + } + } elsif ($id_tipo_modulo == 10 ){ # TCP String (no int conversion)! + $$module_data = $temp2; + $$module_result =0; + } else { # TCP Data numeric (inc or data) + if ($temp2 ne ""){ + if ($temp2 =~ /[A-Za-z\.\,\-\/\\\(\)\[\]]/){ + $$module_result = 1; + $$module_data = 0; # invalid data + $counter = $pa_config->{'tcp_checks'}; + } else { + $$module_data = int($temp2); + $$module_result = 0; # Successful + $counter = $pa_config->{'tcp_checks'}; + } + } else { + $$module_result = 1; + $$module_data = 0; # invalid data + $counter = $pa_config->{'tcp_checks'}; + } + } + } else { # No expected data to receive, if connected and tcp_proc type successful + if ($id_tipo_modulo == 9){ # TCP Proc + $$module_result = 0; + $$module_data = 1; + $counter = $pa_config->{'tcp_checks'}; + } + } + $handle->close(); + undef ($handle); + } else { # Cannot connect (open sock failed) + $$module_result = 1; # Fail + if ($id_tipo_modulo == 9){ # TCP Proc + $$module_result = 0; + $$module_data = 0; # Failed, but data exists + $counter = $pa_config->{'tcp_checks'}; + } + } + } } ########################################################################## @@ -420,51 +429,39 @@ sub pandora_query_snmp (%$$$$) { my $snmp_target = $_[3]; # $_[4] contains error var. - my $output =""; - my $snmp_timeout = 1000 * 1000 * $pa_config->{"networktimeout"}; - my $SESSION = new SNMP::Session (DestHost => $snmp_target, + my $output =""; + my $snmp_timeout = 1000 * 1000 * $pa_config->{"snmp_timeout"}; + my $snmp_retries = $pa_config->{'snmp_checks'}; + my $SESSION; + # Locking for SNMP call. SNMP is not thread safe !! + { + lock $snmp_lock; + $SESSION = new SNMP::Session (DestHost => $snmp_target, Timeout => $snmp_timeout, - Retries => 0, + Retries => $snmp_retries, Community => $snmp_community, Version => 1); - if ( (!defined($SESSION)) && ($snmp_target ne "") && ($snmp_community ne "") && ($snmp_oid ne "")) { - logger($pa_config, "SNMP ERROR SESSION for Target $snmp_target ", 2); - $_[4] = "1"; - } else { - # Perl uses different OID syntax than SNMPWALK or PHP's SNMP - # for example: - # SNMPv2-MIB::sysDescr for PERL SNMP - # is equivalent to SNMPv2-MIB::sysDescr.0 in SNMP and PHP/SNMP - # So we parse last byte and cut off if = 0 and delete 1 if != 0 - my $perl_oid = $snmp_oid; - if ($perl_oid =~ m/(.*)\.([0-9]*)\z/){ - my $local_oid = $1; - my $local_oid_idx = $2; - if ($local_oid_idx == 0){ - $perl_oid = $local_oid; # Strip .0 from orig. OID - } else { - $local_oid_idx--; - $perl_oid = $local_oid.".".$local_oid_idx; - } - } - # Locking for SNMP call. SNMP is not thread safe !! - my $OIDLIST = new SNMP::VarList([$perl_oid]); - { - lock $snmp_lock; - # Pass the VarList to getnext building an array of the output - my @OIDINFO = $SESSION->getnext($OIDLIST); - $output = $OIDINFO[0]; - undef ($OIDLIST); - - } - if ((!defined($output)) || ($output eq "")){ - $_[4] = "1"; - return 0; - } else { - $_[4] = "0"; - } - undef ($SESSION); } + if ($SESSION->{ErrorStr}) { + logger($pa_config, "SNMP ERROR SESSION for Target $snmp_target ".$SESSION->{ErrorStr}, 2); + $_[4] = "1"; + undef ($SESSION); + return 0; + } + my $oid = SNMP::translateObj($snmp_oid); + # Locking for SNMP call. SNMP is not thread safe !! + { + lock $snmp_lock; + $output = $SESSION->get($oid); + } + if ((!defined($SESSION)) || (!defined($output)) || ($output eq "") || ($SESSION->{ErrorStr})) { + logger($pa_config, "SNMP ERROR SNMPGET for Target $snmp_target ".$SESSION->{ErrorStr}, 2); + $_[4] = "1"; + undef ($SESSION); + return 0; + } + $_[4] = "0"; + undef ($SESSION); return $output; } @@ -560,6 +557,8 @@ sub exec_network_module { $module_result = 0; # SNMP_DATA_PROC if ($id_tipo_modulo == 18){ #snmp_data_proc + # RFC1213-MIB where it says that: SYNTAX INTEGER { up(1), down(2), testing(3), + # unknown(4), dormant(5), notPresent(6), lowerLayerDown(7) } if ($temp2 != 1){ # up state is 1, down state in SNMP is 2 .... $temp2 = 0; } @@ -567,17 +566,27 @@ sub exec_network_module { } # SNMP_DATA and SNMP_DATA_INC elsif (($id_tipo_modulo == 15) || ($id_tipo_modulo == 16) ){ - if ($temp2 =~ /[A-Za-z\.\,\-\/\\\(\)\[\]]/){ - $module_result = 1; # Alphanumeric data, not numeric + if (!is_numeric($temp2)){ + $module_result = 1; } else { - $module_data = $temp2; # Float values are also valid + $module_data = $temp2; } } else { # String SNMP $module_data = $temp2; } } else { # Failed SNMP-GET $module_data = 0; - $module_result = 1; # No data, cannot connect + if ($id_tipo_modulo == 18){ # snmp_proc + # Feature from 10Feb08. If snmp_proc_deadresponse = 1 and cannot contact by an error + # this is a fail monitor + if ($pa_config->{"snmp_proc_deadresponse"} eq "1"){ + $module_result = 0; + } else { + $module_result = 1; + } + } else { + $module_result = 1; # No data, cannot connect + } } # TCP Module # ---------- diff --git a/pandora_server/bin/pandora_server b/pandora_server/bin/pandora_server index e8e9e55c53..5b1c23d537 100755 --- a/pandora_server/bin/pandora_server +++ b/pandora_server/bin/pandora_server @@ -2,8 +2,8 @@ ########################################################################## # Pandora Data Server ########################################################################## -# Copyright (c) 2004-2007 Sancho Lerena, slerena@gmail.com -# Copyright (c) 2005-2006 Artica Soluciones Tecnologicas S.L +# Copyright (c) 2004-2008 Sancho Lerena, slerena@gmail.com +# Copyright (c) 2005-2008 Artica Soluciones Tecnologicas S.L # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -36,7 +36,7 @@ use PandoraFMS::Tools; use PandoraFMS::DB; # FLUSH in each IO, only for DEBUG, very slow ! -$| = 1; +$| = 0; my %pa_config; @@ -69,7 +69,6 @@ sub pandora_dataserver { my $file_data; my $file_md5; my @file_list; - my $file_size; my $onefile; # Each item of incoming directory my $agent_filename; my $dbh = DBI->connect("DBI:mysql:$pa_config->{'dbname'}:$pa_config->{'dbhost'}:3306",$pa_config->{"dbuser"}, $pa_config->{"dbpass"},{ RaiseError => 1, AutoCommit => 1 }); @@ -167,13 +166,10 @@ sub pandora_keepalived { ########################################################################## sub keep_alive_check { - # Search of any defined alert for any agent/module table entry my $pa_config = $_[0]; my $dbh = $_[1]; - my $timestamp = &UnixDate ("today", "%Y-%m-%d %H:%M:%S"); my $utimestamp = &UnixDate ("today", "%s"); - my $query_idag = "SELECT tagente_modulo.id_agente_modulo, tagente_estado.utimestamp, tagente_estado.id_agente, tagente.intervalo, tagente.nombre, tagente_modulo.nombre FROM tagente_modulo, talerta_agente_modulo, tagente_estado, tagente WHERE tagente_modulo.id_agente_modulo = talerta_agente_modulo.id_agente_modulo AND talerta_agente_modulo.disable = 0 AND tagente_modulo.id_tipo_modulo = 100 AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.datos != 0"; my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; @@ -212,18 +208,18 @@ sub keep_alive_check { ## param_1 : XML datafile name sub procesa_datos { - my $pa_config = $_[0]; - my $datos = $_[1]; - my $dbh = $_[2]; - - my $tipo_modulo; - my $agent_name; - my $timestamp; - my $interval; - my $os_version; - my $agent_version; - my $id_agente; - my $module_name; + my $pa_config = $_[0]; + my $datos = $_[1]; + my $dbh = $_[2]; + + my $tipo_modulo; + my $agent_name; + my $timestamp; + my $interval; + my $os_version; + my $agent_version; + my $id_agente; + my $module_name; $agent_name = $datos->{'agent_name'}; $timestamp = $datos->{'timestamp'}; diff --git a/pandora_server/bin/pandora_snmpconsole b/pandora_server/bin/pandora_snmpconsole index d643340bef..0208dab135 100755 --- a/pandora_server/bin/pandora_snmpconsole +++ b/pandora_server/bin/pandora_snmpconsole @@ -2,8 +2,8 @@ ########################################################################## # Pandora Server. SNMP Console ########################################################################## -# Copyright (c) 2004-2006 Sancho Lerena, slerena@gmail.com -# Copyright (c) 2005-2006 Artica Soluciones Tecnologicas S.L +# Copyright (c) 2004-2008 Sancho Lerena, slerena@gmail.com +# Copyright (c) 2005-2008 Artica Soluciones Tecnologicas S.L # #This program is free software; you can redistribute it and/or #modify it under the terms of the GNU General Public License @@ -256,7 +256,8 @@ sub calcula_alerta_snmp { $internal_counter++; # ---------> EXECUTE ALERT <--------------- logger($pa_config,"Executing SNMP Trap alert for $agent - $alert_data",2); - execute_alert ($pa_config, $id_alert, $field1, $field2, $field3, $trap_agente, $timestamp, $alert_data, "", "", "", $dbh); + execute_alert ($pa_config, $id_alert, $field1, $field2, $field3, +$trap_agente, $timestamp, $alert_data, "", "", "", 1, $dbh); # Now update the new value for times_fired, alert_fired, internal_counter and last_fired for this alert. my $query_idag2 = "update talert_snmp set times_fired = $times_fired, last_fired = '$ahora_mysql', internal_counter = $internal_counter where id_as = $id_as "; $dbh->do($query_idag2); diff --git a/pandora_server/conf/pandora_server.conf b/pandora_server/conf/pandora_server.conf index 205be27406..6692fddfe0 100755 --- a/pandora_server/conf/pandora_server.conf +++ b/pandora_server/conf/pandora_server.conf @@ -1,9 +1,9 @@ -################################################################################### +############################################################################# # Pandora Server Parameters, please change it for your setup needs -################################################################################### +############################################################################# # Servername: Name of this server -# if not given, it takes localhost. It's preferable to setup one +# if not given, it takes hostname. It's preferable to setup one # because machine name could change by some reason. #servername endor @@ -98,3 +98,28 @@ network_threads 5 # icmp_checks x : defines number of pings for each icmp_proc module type. at least one of that ping should be 1 to report 1 icmp_checks 2 + +# alert_recovery 1 | 0 : Defines if Pandora FMS launch another alert when alert condition is recovered. It +# has the same field1, but adds "[RECOVER]" to field2 and field3. Is disabled by default. + +alert_recovery 1 + +# tcp specific options : +# tcp_checks: number of tcp retries if first attempt fails. +# tcp_timeout: specific timeout for tcp connections + +tcp_checks 2 +tcp_timeout 30 + +# snmp specific options : +# snmp_checks: number of snmp request retries if first attempt fails. +# snmp_timeout: specific timeout for snmp request. + +snmp_checks 4 +snmp_timeout 10 + +# snmp_proc_deadresponse 1 (default): Return DOWN if cannot contact +# or receive NULL from a SNMP PROC module. + +snmp_proc_deadresponse 1 + diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 88a0f16277..7f0f660ad4 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -2,8 +2,8 @@ package PandoraFMS::Config; ########################################################################## # Pandora Config package ########################################################################## -# Copyright (c) 2004-2007 Sancho Lerena, slerena@gmail.com -# Copyright (c) 2005-2007 Artica Soluciones Tecnologicas S.L +# Copyright (c) 2004-2008 Sancho Lerena, slerena@gmail.com +# Copyright (c) 2005-2008 Artica Soluciones Tecnologicas S.L # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -34,8 +34,8 @@ our @EXPORT = qw( pandora_help_screen # There is no global vars, all variables (setup) passed as hash reference # version: Defines actual version of Pandora Server for this module only -my $pandora_version = "1.3.1dev"; -my $pandora_build="PS080108"; +my $pandora_version = "1.4-dev"; +my $pandora_build="PS080220"; our $VERSION = $pandora_version." ".$pandora_build; # Setup hash @@ -66,7 +66,7 @@ sub help_screen { sub pandora_init { my $pa_config = $_[0]; my $init_string = $_[1]; - printf "\n$init_string $pandora_version Build $pandora_build Copyright (c) 2004-2007 ArticaST\n"; + printf "\n$init_string $pandora_version Build $pandora_build Copyright (c) 2004-2008 ArticaST\n"; printf "This program is Free Software, licensed under the terms of GPL License v2.\n"; printf "You can download latest versions and documentation at http://pandora.sourceforge.net. \n\n"; @@ -116,41 +116,48 @@ sub pandora_loadconfig { # Default values $pa_config->{'version'} = $pandora_version; $pa_config->{'build'} = $pandora_build; - $pa_config->{"dbuser"} ="pandora"; + $pa_config->{"dbuser"} = "pandora"; $pa_config->{"dbpass"} = "pandora"; $pa_config->{"dbhost"} = "localhost"; $pa_config->{"dbname"} = "pandora"; - $pa_config->{"basepath"}=$pa_config->{'pandora_path'}; # Compatibility with Pandora 1.1 - $pa_config->{"incomingdir"}="/var/spool/pandor/data_in"; - $pa_config->{"server_threshold"}=30; - $pa_config->{"alert_threshold"}=60; - $pa_config->{"logfile"}="/var/log/pandora_server.log"; - $pa_config->{"errorlogfile"}="/var/log/pandora_server.error"; - $pa_config->{"networktimeout"}=15; # By default, not in config file yet - $pa_config->{"pandora_master"}=1; # on by default - $pa_config->{"pandora_check"}=0; # on by default - $pa_config->{"snmpconsole"}=0; # off by default - $pa_config->{"version"}=$pandora_version; - $pa_config->{"build"}=$pandora_build; - $pa_config->{"servername"}=`hostname`; - $pa_config->{"servername"}=~ s/\s//g; # Replace ' ' chars - $pa_config->{"networkserver"}=0; - $pa_config->{"dataserver"}=0; - $pa_config->{"icmp_checks"}=1; # Introduced on 1.3.1 - $pa_config->{"reconserver"}=0; - $pa_config->{"servermode"}=""; - $pa_config->{'snmp_logfile'}="/var/log/pandora/pandora_snmptrap.log"; - $pa_config->{"network_threads"}=5; # Fixed default - $pa_config->{"keepalive"}=60; # 60 Seconds initially for server keepalive + $pa_config->{"basepath"} = $pa_config->{'pandora_path'}; # Compatibility with Pandora 1.1 + $pa_config->{"incomingdir"} = "/var/spool/pandora/data_in"; + $pa_config->{"server_threshold"} = 30; + $pa_config->{"alert_threshold"} = 60; + $pa_config->{"logfile"} = "/var/log/pandora_server.log"; + $pa_config->{"errorlogfile"} = "/var/log/pandora_server.error"; + $pa_config->{"networktimeout"} = 15; # By default, not in config file yet + $pa_config->{"pandora_master"} = 1; # on by default + $pa_config->{"pandora_check"} = 0; # on by default + $pa_config->{"snmpconsole"} = 0; # off by default + $pa_config->{"version"} = $pandora_version; + $pa_config->{"build"} = $pandora_build; + $pa_config->{"servername"} = `hostname`; + $pa_config->{"servername"} =~ s/\s//g; # Replace ' ' chars + $pa_config->{"networkserver"} = 0; + $pa_config->{"dataserver"} = 0; + $pa_config->{"icmp_checks"} = 1; # Introduced on 1.3.1 + $pa_config->{"reconserver"} = 0; + $pa_config->{"servermode"} = ""; + $pa_config->{'snmp_logfile'} = "/var/log/pandora/pandora_snmptrap.log"; + $pa_config->{"network_threads"} = 5; # Fixed default + $pa_config->{"keepalive"} = 60; # 60 Seconds initially for server keepalive $pa_config->{"keepalive_orig"} = $pa_config->{"keepalive"}; + $pa_config->{"alert_recovery"} = 0; # Introduced on 1.3.1 + $pa_config->{"snmp_checks"} = 1; # Introduced on 1.3.1 + $pa_config->{"snmp_timeout"} = 8; # Introduced on 1.3.1 + $pa_config->{"tcp_checks"} = 1; # Introduced on 1.3.1 + $pa_config->{"tcp_timeout"} = 20; # Introduced on 1.3.1 + $pa_config->{"snmp_proc_deadresponse"} = 0; # Introduced on 1.3.1 10 Feb08 # Check for UID0 if ($> == 0){ - printf " [W] It is not a good idea running Pandora FMS Server as root user, please DON'T DO IT!\n"; + printf " [W] Not all Pandora FMS components need to be executed as root\n"; + printf " please consider starting it with a non-privileged user.\n"; } # Check for file if ( ! -e $archivo_cfg ) { printf "\n[ERROR] Cannot open configuration file at $archivo_cfg. \n"; - printf " Please specify a valid Pandora FMS Home Directory in command line. \n"; + printf " Please specify a valid Pandora FMS configuration file in command line. \n"; exit 1; } # Collect items from config file and put in an array @@ -159,7 +166,7 @@ sub pandora_loadconfig { $buffer_line = $_; if ($buffer_line =~ /^[a-zA-Z]/){ # begins with letters if ($buffer_line =~ m/([\w\-\_\.]+)\s([0-9\w\-\_\.\/\?\&\=\)\(\_\-\!\*\@\#\%\$\~\"\']+)/){ - push @command_line,$buffer_line; + push @command_line, $buffer_line; } } } @@ -215,6 +222,9 @@ sub pandora_loadconfig { elsif ($parametro =~ m/^dataserver\s([0-9]*)/i) { $pa_config->{'dataserver'}= $1; } + elsif ($parametro =~ m/^snmp_proc_deadresponse\s([0-9]*)/i) { + $pa_config->{"snmp_proc_deadresponse"} = $1; + } elsif ($parametro =~ m/^reconserver\s([0-9]*)/i) { $pa_config->{'reconserver'}= $1; } @@ -232,6 +242,22 @@ sub pandora_loadconfig { elsif ($parametro =~ m/^snmpconsole\s([0-9])/i) { $pa_config->{"snmpconsole"} = $1; } + elsif ($parametro =~ m/^alert_recovery\s([0-9])/i) { + $pa_config->{"alert_recovery"} = $1; + } + elsif ($parametro =~ m/^snmp_checks\s([0-9])/i) { + $pa_config->{"snmp_checks"} = $1; + } + elsif ($parametro =~ m/^snmp_timeout\s([0-9])/i) { + $pa_config->{"snmp_timeout"} = $1; + } + elsif ($parametro =~ m/^tcp_checks\s([0-9])/i) { + $pa_config->{"tcp_checks"} = $1; + } + elsif ($parametro =~ m/^tcp_timeout\s([0-9])/i) { + $pa_config->{"tcp_timeout"} = $1; + } + elsif ($parametro =~ m/^verbosity\s([0-9]*)/i) { $pa_config->{"verbosity"} = $1; } elsif ($parametro =~ m/^server_threshold\s([0-9]*)/i) { $pa_config->{"server_threshold"} = $1; } elsif ($parametro =~ m/^alert_threshold\s([0-9]*)/i) { $pa_config->{"alert_threshold"} = $1; } diff --git a/pandora_server/lib/PandoraFMS/DB.pm b/pandora_server/lib/PandoraFMS/DB.pm index 77ee0373c1..51e3565a2f 100644 --- a/pandora_server/lib/PandoraFMS/DB.pm +++ b/pandora_server/lib/PandoraFMS/DB.pm @@ -2,19 +2,19 @@ package PandoraFMS::DB; ########################################################################## # Pandora FMS Database Package ########################################################################## -# Copyright (c) 2004-2007 Sancho Lerena, slerena@gmail.com -# Copyright (c) 2005-2007 Artica Soluciones Tecnologicas S.L +# Copyright (c) 2004-2008 Sancho Lerena, slerena@gmail.com +# Copyright (c) 2005-2008 Artica Soluciones Tecnologicas S.L # -#This program is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public License -#as published by the Free Software Foundation; version 2 -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. -#You should have received a copy of the GNU General Public License -#along with this program; if not, write to the Free Software -#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; version 2 +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ########################################################################## use warnings; @@ -215,7 +215,8 @@ sub pandora_calcula_alerta (%$$$$$$) { my $nombre_agente = dame_nombreagente_agentemodulo ($pa_config, $id_agente_modulo, $dbh); # -------------------------------------- # Now call to execute_alert to real exec - execute_alert ($pa_config, $id_alerta, $campo1, $campo2, $campo3, $nombre_agente, $timestamp, $datos, $comando, $alert_name, $descripcion, $dbh); + execute_alert ($pa_config, $id_alerta, $campo1, $campo2, $campo3, +$nombre_agente, $timestamp, $datos, $comando, $alert_name, $descripcion, 1, $dbh); # -------------------------------------- } else { # Alert is in valid timegap but has too many alerts @@ -258,6 +259,16 @@ sub pandora_calcula_alerta (%$$$$$$) { if ($times_fired > 0){ my $evt_descripcion = "Alert ceased - Recovered ($descripcion)"; pandora_event ($pa_config, $evt_descripcion, $id_grupo, $id_agente, $dbh); + # Specific patch for F. Corona + # This enable alert recovery notification by using the same alert definition but + # inserting WORD "RECOVERED" in second and third field of + # alert. To activate setup your .conf with new token + # "alert_recovery" and set to 1 (disabled by default) + if ($pa_config->{"alert_recovery"} eq "1"){ + execute_alert ($pa_config, $id_alerta, $campo1, +"[RECOVERED ] - ".$campo2, "[ALERT CEASED - RECOVERED] - ".$campo3, $nombre_agente, $timestamp, $datos, $comando, +$alert_name, $descripcion, 0, $dbh); + } } } if (($times_fired > 0) || ($internal_counter > 0)){ @@ -278,11 +289,12 @@ sub pandora_calcula_alerta (%$$$$$$) { } ########################################################################## -## SUB execute_alert (id_alert, field1, field2, field3, agent, timestamp, data) +## SUB execute_alert (id_alert, field1, field2, field3, agent, timestamp, data, +## command, $alert_name, $alert_description, create_event, dbh) ## Do a execution of given alert with this parameters ########################################################################## -sub execute_alert (%$$$$$$$$$$$) { +sub execute_alert (%$$$$$$$$$$$$) { my $pa_config = $_[0]; my $id_alert = $_[1]; my $field1 = $_[2]; @@ -294,7 +306,8 @@ sub execute_alert (%$$$$$$$$$$$) { my $command = $_[8]; my $alert_name = $_[9]; my $alert_description = $_[10]; - my $dbh = $_[11]; + my $create_event = $_[11]; + my $dbh = $_[12]; if (($command eq "") && ($alert_name eq "")){ # Get values for commandline, reading from talerta. @@ -341,9 +354,12 @@ sub execute_alert (%$$$$$$$$$$$) { $field1 =~ s/_data_/$data/ig; pandora_audit ($pa_config, $field1, $agent, "Alert ($alert_description)", $dbh); } - my $evt_descripcion = "Alert fired ($alert_description)"; - my $id_agente = dame_agente_id ($pa_config, $agent, $dbh); - pandora_event ($pa_config, $evt_descripcion, dame_grupo_agente($pa_config, $id_agente, $dbh), $id_agente, $dbh); + if ($create_event == 1){ + my $evt_descripcion = "Alert fired ($alert_description)"; + my $id_agente = dame_agente_id ($pa_config, $agent, $dbh); + pandora_event ($pa_config, $evt_descripcion, dame_grupo_agente($pa_config, $id_agente, $dbh), +$id_agente, $dbh); + } } @@ -382,6 +398,7 @@ sub pandora_writestate (%$$$$$$$) { if (($id_agente == -1) || ($id_agente_modulo == -1)) { goto fin_pandora_writestate; } + # Seek for agent_interval or module_interval my $query_idag = "SELECT * FROM tagente_modulo WHERE id_agente = $id_agente AND id_agente_modulo = " . $id_agente_modulo;; my $s_idag = $dbh->prepare($query_idag); @@ -397,7 +414,6 @@ sub pandora_writestate (%$$$$$$$) { $module_interval = dame_intervalo ($pa_config, $id_agente, $dbh); } $s_idag->finish(); - # Check alert subroutine eval { pandora_calcula_alerta ($pa_config, $timestamp, $nombre_agente, $tipo_modulo, $nombre_modulo, $datos, $dbh); @@ -421,7 +437,7 @@ sub pandora_writestate (%$$$$$$$) { @data = $s_idages->fetchrow_array(); # Se supone que $data[5](estado) ( nos daria el estado ANTERIOR # For xxxx_PROC type (boolean / monitor), create an event if state has changed - if (( $data[5] != $estado) && ($tipo_modulo =~ /proc/) ) { + if (( $data[5] != $estado) && ( ($tipo_modulo =~/keep_alive/) || ($tipo_modulo =~ /proc/)) ) { # Cambio de estado detectado ! $cambio = 1; # Este seria el momento oportuno de probar a saltar la alerta si estuviera definida @@ -510,16 +526,15 @@ sub pandora_accessupdate (%$$) { my $query2 = "insert into tagent_access (id_agent, timestamp) VALUES ($id_agent,'$timestamp')"; $dbh->do($query2); logger($pa_config,"Updating tagent_access for agent id $id_agent",9); - - } - # Update keepalive module (if present) + + # Update keepalive module (if present, if there is more than one, only updates first one!). my $id_agent_module = give_db_free ("SELECT id_agente_modulo FROM tagente_modulo WHERE id_agente = $id_agent AND id_tipo_modulo = 100", $dbh); if ($id_agent_module ne -1){ - my $utimestamp = &UnixDate ("today", "%s"); - # Status = 0 is monitor OK - $query2 = "UPDATE tagente_estado SET datos = 1, estado = 0, timestamp = '$timestamp', cambio = 0, last_try= '$timestamp', utimestamp = $utimestamp WHERE id_agente_modulo = $id_agent_module"; - $dbh->do ($query2); + my $agent_name = give_db_free ("SELECT nombre FROM tagente WHERE id_agente = $id_agent", $dbh); + my $module_typename = "keep_alive"; + my $module_name = give_db_free ("SELECT nombre FROM tagente_modulo WHERE id_agente_modulo = $id_agent_module", $dbh); + pandora_writestate ($pa_config, $agent_name, $module_typename, $module_name, 1, 0, $dbh, 1); } } } @@ -545,34 +560,33 @@ sub module_generic_proc (%$$$$$) { # Leemos datos de la estructura my $a_datos = $datos->{data}->[0]; - if ((ref($a_datos) ne "HASH")){ - $a_datos = sprintf("%.2f", $a_datos); # Two decimal float. We cannot store more - # to change this, you need to change mysql structure - $a_datos =~ s/\,/\./g; # replace "," by "." avoiding locale problems - my $a_name = $datos->{name}->[0]; - my $a_desc = $datos->{description}->[0]; - my $a_max = $datos->{max}->[0]; - my $a_min = $datos->{min}->[0]; - - if (ref($a_max) eq "HASH") { - $a_max = ""; - } - if (ref($a_min) eq "HASH") { - $a_min = ""; - } - pandora_writedata($pa_config, $a_timestamp,$agent_name,$module_type,$a_name,$a_datos,$a_max,$a_min,$a_desc,$dbh, \$bUpdateDatos); - - # Check for status: <1 state 1 (Bad), >= 1 state 0 (Good) - # Calculamos su estado - if ( $datos->{'data'}->[0] < 1 ) { - $estado = 1; - } else { - $estado=0; - } - pandora_writestate ($pa_config, $agent_name,$module_type,$a_name,$a_datos,$estado,$dbh, $bUpdateDatos); + if ((ref($a_datos) eq "HASH")){ + $a_datos = 0; # If get bad data, then this is bad value, not "unknown" (> 1.3 version) } else { - logger ($pa_config, "(proc) Invalid data received from agent $agent_name", 2); + $a_datos = sprintf("%.2f", $a_datos); # Two decimal float. We cannot store more + } # to change this, you need to change mysql structure + $a_datos =~ s/\,/\./g; # replace "," by "." avoiding locale problems + my $a_name = $datos->{name}->[0]; + my $a_desc = $datos->{description}->[0]; + my $a_max = $datos->{max}->[0]; + my $a_min = $datos->{min}->[0]; + + if (ref($a_max) eq "HASH") { + $a_max = ""; } + if (ref($a_min) eq "HASH") { + $a_min = ""; + } + pandora_writedata($pa_config, $a_timestamp,$agent_name,$module_type,$a_name,$a_datos,$a_max,$a_min,$a_desc,$dbh, \$bUpdateDatos); + + # Check for status: <1 state 1 (Bad), >= 1 state 0 (Good) + # Calculamos su estado + if ( $a_datos >= 1 ) { + $estado = 0; + } else { + $estado = 1; + } + pandora_writestate ($pa_config, $agent_name, $module_type, $a_name, $a_datos, $estado, $dbh, $bUpdateDatos); } ########################################################################## diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index efc86941fe..85e864c494 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -507,7 +507,7 @@ sub help_screen{ sub pandoradb_main { pandora_purgedb ($config_days_purge, $dbname, $dbuser, $dbpass, $dbhost); pandora_checkdb_consistency ($dbname, $dbuser, $dbpass, $dbhost); - pandora_compactdb ($config_days_compact, $dbname, $dbuser, $dbpass, $dbhost); + # pandora_compactdb ($config_days_compact, $dbname, $dbuser, $dbpass, $dbhost); print "\n"; exit; }