2008-02-20 Sancho Lerena <slerena@gmail.com>

* 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
This commit is contained in:
slerena 2008-02-20 02:09:36 +00:00
parent 7bf9a6f027
commit bccfac8c73
8 changed files with 382 additions and 235 deletions

View File

@ -1,3 +1,79 @@
2008-02-20 Sancho Lerena <slerena@gmail.com>
* Merged latest changes on stable branch to trunk. Let's go to
1.4 version !!
2008-02-13 Sancho Lerena <slerena@gmail.com>
* 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 <slerena@gmail.com>
* 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 <slerena@gmail.com>
* lib/PandoraFMS/Config.pm, bin/pandora_network,
conf/pandora_server.conf: New options for tcp/snmp retries and timout
2008-01-21 Sancho Lerena <slerena@gmail.com>
* pandora_db.pl: Disable compactation until fix bug in compactation
function that currently delete data insted compacting it.
2008-01-14 Sancho Lerena <slerena@gmail.com>
* 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 <slerena@gmail.com>
* 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 <slerena@gmail.com>
* 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 <slerena@gmail.com>
* Config.pm: Updated version to 1.3.1-dev

View File

@ -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
# ----------

View File

@ -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'};

View File

@ -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);

View File

@ -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

View File

@ -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; }

View File

@ -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);
}
##########################################################################

View File

@ -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;
}