2012-01-03 Ramon Novoa <rnovoa@artica.es>

* pandora_windows_service.h,
	  modules/pandora_module.h,
	  modules/pandora_module_factory.cc,
	  modules/pandora_module.cc,
	  pandora_windows_service.cc: Added support for intensive modules.



git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@5318 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
Ramon Novoa 2012-01-03 17:23:23 +00:00
parent e726c32455
commit f6818a7277
6 changed files with 541 additions and 268 deletions

View File

@ -1,3 +1,11 @@
2012-01-03 Ramon Novoa <rnovoa@artica.es>
* pandora_windows_service.h,
modules/pandora_module.h,
modules/pandora_module_factory.cc,
modules/pandora_module.cc,
pandora_windows_service.cc: Added support for intensive modules.
2011-12-14 Ramon Novoa <rnovoa@artica.es>
* modules/pandora_module_perfcounter.cc,

View File

@ -61,6 +61,10 @@ Pandora_Module::Pandora_Module (string name) {
this->max_warning = "";
this->disabled = "";
this->min_ff_event = "";
this->intensive_condition_list = NULL;
this->intensive_interval = 1;
this->timestamp = 0;
this->intensive_match = 0;
}
/**
@ -70,9 +74,9 @@ Pandora_Module::Pandora_Module (string name) {
*/
Pandora_Module::~Pandora_Module () {
Condition *cond = NULL;
Precondition *precond = NULL;
Condition *precond = NULL;
list<Condition *>::iterator iter;
list<Precondition *>::iterator iter_pre;
list<Condition *>::iterator iter_pre;
/* Clean data lists */
this->cleanDataList ();
@ -110,6 +114,23 @@ Pandora_Module::~Pandora_Module () {
delete (this->condition_list);
this->condition_list = NULL;
}
/* Clean intensive_condition list */
if (this->intensive_condition_list != NULL && this->intensive_condition_list->size () > 0) {
iter = this->intensive_condition_list->begin ();
for (iter = this->intensive_condition_list->begin ();
iter != this->intensive_condition_list->end ();
iter++) {
/* Free regular expressions */
cond = *iter;
if (cond->string_value != "") {
regfree (&(cond->regexp));
}
delete (*iter);
}
delete (this->intensive_condition_list);
this->intensive_condition_list = NULL;
}
/* Clean the module cron */
if (this->cron != NULL) {
@ -414,6 +435,7 @@ Pandora_Module::setOutput (string output, SYSTEMTIME *system_time) {
*/
void
Pandora_Module::setNoOutput () {
this->cleanDataList ();
this->has_output = false;
}
@ -430,9 +452,8 @@ Pandora_Module::setNoOutput () {
void
Pandora_Module::run () {
/* Check the interval */
if (this->executions % this->module_interval != 0) {
pandoraDebug ("%s: Interval is not fulfilled",
this->module_name.c_str ());
if (this->executions % this->intensive_interval != 0) {
pandoraDebug ("%s: Interval is not fulfilled", this->module_name.c_str ());
this->executions++;
has_output = false;
throw Interval_Not_Fulfilled ();
@ -489,12 +510,10 @@ Pandora_Module::getXml () {
}
/* Interval */
if (this->module_interval > 1) {
module_interval << this->module_interval;
module_xml += "\t<module_interval><![CDATA[";
module_xml += module_interval.str ();
module_xml += "]]></module_interval>\n";
}
module_interval << this->module_interval;
module_xml += "\t<module_interval><![CDATA[";
module_xml += module_interval.str ();
module_xml += "]]></module_interval>\n";
/* Min */
if (this->has_min) {
@ -752,6 +771,16 @@ Pandora_Module::setInterval (int interval) {
this->module_interval = interval;
}
/**
* Set the intensive interval.
*
* @param intensive_interval Intensive interval.
*/
void
Pandora_Module::setIntensiveInterval (int intensive_interval) {
this->intensive_interval = intensive_interval;
}
/**
* Set the execution timeout.
*
@ -778,6 +807,16 @@ Pandora_Module::getInterval () {
return this->module_interval;
}
/**
* Get the intensive interval.
*
* @return The intensive interval.
*/
int
Pandora_Module::getIntensiveInterval () {
return this->intensive_interval;
}
/**
* Get the execution timeout.
*
@ -819,75 +858,19 @@ Pandora_Module::getSave () {
}
/**
* Adds a new precondition to the module.
*
* @param precondition string.
*/
void
Pandora_Module::addPrecondition (string precondition) {
Precondition *precond;
char operation[256], string_value[1024], command[1024];
/* Create the precondition list if it does not exist */
if (this->precondition_list == NULL) {
this->precondition_list = new list<Precondition *> ();
}
/* Create the new precondition */
precond = new Precondition;
if (precond == NULL) {
return;
}
precond->value_1 = 0;
precond->value_2 = 0;
/* Numeric comparison */
if (sscanf (precondition.c_str (), "%255s %lf %1023[^\n]s", operation, &(precond->value_1), command) == 3) {
precond->operation = operation;
precond->command = command;
precond->command = "cmd.exe /c \"" + precond->command + "\"";
this->precondition_list->push_back (precond);
return;
/* Regular expression */
} else if (sscanf (precondition.c_str (), "=~ %1023s %1023[^\n]s", string_value, command) == 2) {
precond->operation = "=~";
precond->string_value = string_value;
precond->command = command;
if (regcomp (&(precond->regexp), string_value, 0) != 0) {
pandoraDebug ("Invalid regular expression %s", string_value);
delete (precond);
return;
}
this->precondition_list->push_back (precond);
/* Interval */
} else if (sscanf (precondition.c_str (), "(%lf , %lf) %1023[^\n]s", &(precond->value_1), &(precond->value_2), command) == 3) {
precond->operation = "()";
precond->command = command;
this->precondition_list->push_back (precond);
} else {
pandoraDebug ("Invalid module condition: %s", precondition.c_str ());
delete (precond);
return;
}
return;
}
/**
* Adds a new condition to the module.
* Adds a new condition to a condition list.
*
* @param condition Condition string.
* @param condition_list Pointer to the condition list.
*/
void
Pandora_Module::addCondition (string condition) {
Pandora_Module::addGenericCondition (string condition, list<Condition *> **condition_list) {
Condition *cond;
char operation[256], string_value[1024], command[1024];
/* Create the condition list if it does not exist */
if (this->condition_list == NULL) {
this->condition_list = new list<Condition *> ();
if (*condition_list == NULL) {
*condition_list = new list<Condition *> ();
}
/* Create the new condition */
@ -902,7 +885,7 @@ Pandora_Module::addCondition (string condition) {
if (sscanf (condition.c_str (), "%255s %lf %1023[^\n]s", operation, &(cond->value_1), command) == 3) {
cond->operation = operation;
cond->command = command;
this->condition_list->push_back (cond);
(*condition_list)->push_back (cond);
/* Regular expression */
} else if (sscanf (condition.c_str (), "=~ %1023s %1023[^\n]s", string_value, command) == 2) {
cond->operation = "=~";
@ -913,14 +896,82 @@ Pandora_Module::addCondition (string condition) {
delete (cond);
return;
}
this->condition_list->push_back (cond);
(*condition_list)->push_back (cond);
/* Interval */
} else if (sscanf (condition.c_str (), "(%lf , %lf) %1023[^\n]s", &(cond->value_1), &(cond->value_2), command) == 3) {
cond->operation = "()";
cond->command = command;
this->condition_list->push_back (cond);
(*condition_list)->push_back (cond);
} else {
pandoraDebug ("Invalid module condition: %s", condition.c_str ());
pandoraLog ("Invalid condition: %s", condition.c_str ());
delete (cond);
return;
}
}
/**
* Adds a new module condition.
*
* @param condition Condition string.
*/
void
Pandora_Module::addCondition (string condition) {
addGenericCondition (condition, &(this->condition_list));
}
/**
* Adds a new module pre-condition.
*
* @param condition Condition string.
*/
void
Pandora_Module::addPreCondition (string condition) {
addGenericCondition (condition, &(this->precondition_list));
}
/**
* Adds a new module intensive condition.
*
* @param condition Condition string.
*/
void
Pandora_Module::addIntensiveCondition (string condition) {
Condition *cond;
char operation[256], string_value[1024], command[1024];
/* Create the condition list if it does not exist */
if (this->intensive_condition_list == NULL) {
this->intensive_condition_list = new list<Condition *> ();
}
/* Create the new condition */
cond = new Condition;
if (cond == NULL) {
return;
}
cond->value_1 = 0;
cond->value_2 = 0;
/* Numeric comparison */
if (sscanf (condition.c_str (), "%255s %lf", operation, &(cond->value_1)) == 2) {
cond->operation = operation;
(this->intensive_condition_list)->push_back (cond);
/* Regular expression */
} else if (sscanf (condition.c_str (), "=~ %1023s", string_value) == 1) {
cond->operation = "=~";
cond->string_value = string_value;
if (regcomp (&(cond->regexp), string_value, 0) != 0) {
pandoraDebug ("Invalid regular expression %s", string_value);
delete (cond);
return;
}
(this->intensive_condition_list)->push_back (cond);
/* Interval */
} else if (sscanf (condition.c_str (), "(%lf , %lf)", &(cond->value_1), &(cond->value_2)) == 2) {
cond->operation = "()";
(this->intensive_condition_list)->push_back (cond);
} else {
pandoraDebug ("Invalid intensive condition: %s", condition.c_str ());
delete (cond);
return;
}
@ -937,11 +988,10 @@ Pandora_Module::evaluatePreconditions () {
SECURITY_ATTRIBUTES attributes;
HANDLE out, new_stdout, out_read, job;
string working_dir;
Precondition *precond = NULL;
float float_output;
list<Precondition *>::iterator iter;
Condition *precond = NULL;
double double_output;
list<Condition *>::iterator iter;
unsigned char run;
int exe = 1;
string output;
if (this->precondition_list != NULL && this->precondition_list->size () > 0) {
@ -1016,78 +1066,69 @@ Pandora_Module::evaluatePreconditions () {
}
ResumeThread (pi.hThread);
/*string output;*/
int tickbase = GetTickCount();
while ( (dwRet = WaitForSingleObject (pi.hProcess, 500)) != WAIT_ABANDONED ) {
PeekNamedPipe (out_read, buffer, BUFSIZE, &read, &avail, NULL);
if (avail > 0) {
ReadFile (out_read, buffer, BUFSIZE, &read, NULL);
buffer[read] = '\0';
output += (char *) buffer;
/*string output;*/
int tickbase = GetTickCount();
while ( (dwRet = WaitForSingleObject (pi.hProcess, 500)) != WAIT_ABANDONED ) {
PeekNamedPipe (out_read, buffer, BUFSIZE, &read, &avail, NULL);
if (avail > 0) {
ReadFile (out_read, buffer, BUFSIZE, &read, NULL);
buffer[read] = '\0';
output += (char *) buffer;
}
try {
double_output = Pandora_Strutils::strtodouble (output);
} catch (Pandora_Strutils::Invalid_Conversion e) {
double_output = 0;
}
if (dwRet == WAIT_OBJECT_0) {
break;
} else if(this->getTimeout() < GetTickCount() - tickbase) {
/* STILL_ACTIVE */
TerminateProcess(pi.hThread, STILL_ACTIVE);
pandoraLog ("evaluatePreconditions: %s timed out (retcode: %d)", this->module_name.c_str (), STILL_ACTIVE);
break;
}
float_output = atof(output.c_str());
if (dwRet == WAIT_OBJECT_0) {
break;
} else if(this->getTimeout() < GetTickCount() - tickbase) {
/* STILL_ACTIVE */
TerminateProcess(pi.hThread, STILL_ACTIVE);
pandoraLog ("evaluatePreconditions: %s timed out (retcode: %d)", this->module_name.c_str (), STILL_ACTIVE);
break;
}
}
GetExitCodeProcess (pi.hProcess, &retval);
if (retval != 0) {
if (! TerminateJobObject (job, 0)) {
pandoraLog ("evaluatePreconditions: TerminateJobObject failed. (error %d)",
GetLastError ());
GetExitCodeProcess (pi.hProcess, &retval);
if (retval != 0) {
if (! TerminateJobObject (job, 0)) {
pandoraLog ("evaluatePreconditions: TerminateJobObject failed. (error %d)",
GetLastError ());
}
if (retval != STILL_ACTIVE) {
pandoraLog ("evaluatePreconditions: %s did not executed well (retcode: %d)",
this->module_name.c_str (), retval);
}
/* Close job, process and thread handles. */
CloseHandle (job);
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
CloseHandle (new_stdout);
CloseHandle (out_read);
return 0;
}
if (retval != STILL_ACTIVE) {
pandoraLog ("evaluatePreconditions: %s did not executed well (retcode: %d)",
this->module_name.c_str (), retval);
}
/* Close job, process and thread handles. */
CloseHandle (job);
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
}
CloseHandle (new_stdout);
CloseHandle (out_read);
return 0;
}
/* Close job, process and thread handles. */
CloseHandle (job);
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
}
CloseHandle (new_stdout);
CloseHandle (out_read);
if ((precond->operation == ">" && float_output > precond->value_1) ||
(precond->operation == "<" && float_output < precond->value_1) ||
(precond->operation == "=" && float_output == precond->value_1) ||
(precond->operation == "!=" && float_output != precond->value_1) ||
(precond->operation == "=~" && regexec (&(precond->regexp), output.c_str(), 0, NULL, 0) == 0) ||
(precond->operation == "()" && float_output > precond->value_1 && float_output < precond->value_2)){
exe = 1;
} else {
exe = 0;
return exe;
if (evaluateCondition (output, double_output, precond) != 0) {
return 0;
}
CloseHandle (pi.hProcess);
}
}
return exe;
}
}
}
return 1;
}
/**
* Evaluates and executes module conditions.
@ -1129,13 +1170,8 @@ Pandora_Module::evaluateConditions () {
iter++) {
cond = *iter;
run = 0;
if ((cond->operation == ">" && double_value > cond->value_1) ||
(cond->operation == "<" && double_value < cond->value_1) ||
(cond->operation == "=" && double_value == cond->value_1) ||
(cond->operation == "!=" && double_value != cond->value_1) ||
(cond->operation == "=~" && regexec (&(cond->regexp), string_value.c_str (), 0, NULL, 0) == 0) ||
(cond->operation == "()" && double_value > cond->value_1 && double_value < cond->value_2)) {
if (evaluateCondition (string_value, double_value, cond) == 1) {
/* Run the condition command */
ZeroMemory (&si, sizeof (si));
ZeroMemory (&pi, sizeof (pi));
@ -1150,6 +1186,56 @@ Pandora_Module::evaluateConditions () {
}
}
/**
* Evaluates and executes intensive module conditions.
*/
int
Pandora_Module::evaluateIntensiveConditions () {
double double_value;
string string_value;
Condition *cond = NULL;
list<Condition *>::iterator iter;
PROCESS_INFORMATION pi;
STARTUPINFO si;
Pandora_Data *pandora_data = NULL;
regex_t regex;
/* Not an intensive module */
if (this->intensive_condition_list == NULL || this->intensive_condition_list->size () <= 0) {
return 1;
}
/* No data */
if ( (!this->has_output) || this->data_list == NULL) {
return 0;
}
/* Get the module data */
pandora_data = data_list->front ();
/* Get the string value of the data */
string_value = pandora_data->getValue ();
/* Get the double value of the data */
try {
double_value = Pandora_Strutils::strtodouble (string_value);
} catch (Pandora_Strutils::Invalid_Conversion e) {
double_value = 0;
}
iter = this->intensive_condition_list->begin ();
for (iter = this->intensive_condition_list->begin ();
iter != this->intensive_condition_list->end ();
iter++) {
cond = *iter;
if (evaluateCondition (string_value, double_value, cond) == 0) {
return 0;
}
}
return 1;
}
/**
* Checks the module cron. Returns 1 if the module should run, 0 if not.
*
@ -1280,6 +1366,8 @@ Pandora_Module::setCron (string cron_string) {
/**
* Sets the interval of the module cron.
*
* @param interval Module cron interval in seconds.
*/
void
Pandora_Module::setCronInterval (int interval) {
@ -1289,3 +1377,80 @@ Pandora_Module::setCronInterval (int interval) {
this->cron->interval = interval;
}
/**
* Evaluate a single condition. Returns 1 if the condition matches, 0
* otherwise.
*
* @param string_value String value.
* @param double_value Double value.
* @param condition Pointer to the condition.
*/
int Pandora_Module::evaluateCondition (string string_value, double double_value, Condition *condition) {
if ((condition->operation == ">" && double_value > condition->value_1) ||
(condition->operation == "<" && double_value < condition->value_1) ||
(condition->operation == "=" && double_value == condition->value_1) ||
(condition->operation == "!=" && double_value != condition->value_1) ||
(condition->operation == "=~" && regexec (&(condition->regexp), string_value.c_str(), 0, NULL, 0) == 0) ||
(condition->operation == "()" && double_value > condition->value_1 && double_value < condition->value_2)) {
return 1;
}
return 0;
}
/**
* Checks if a module has data.
*
* @return 1 if the module has data, 0 otherwise.
*/
int Pandora_Module::hasOutput () {
if (this->has_output == 1) {
return 1;
}
return 0;
}
/**
* Sets the module timestamp.
*
* @param timestamp Module timestamp in seconds.
*/
void
Pandora_Module::setTimestamp (time_t timestamp) {
this->timestamp = timestamp;
}
/**
* Gets the module timestamp.
*
* @return Module timestamp in seconds.
*/
time_t
Pandora_Module::getTimestamp () {
return this->timestamp;
}
/**
* Sets the value of intensive_match.
*
* @param intensive_match 0 or 1.
*/
void
Pandora_Module::setIntensiveMatch (unsigned char intensive_match) {
this->intensive_match = intensive_match;
}
/**
* Gets the value of intensive_match.
*
* @return The value of intensive match.
*/
unsigned char
Pandora_Module::getIntensiveMatch () {
return this->intensive_match;
}

View File

@ -91,18 +91,6 @@ namespace Pandora_Modules {
MODULE_SNMPGET /**< SNMP get module */
} Module_Kind;
/**
* Defines the structure that holds module preconditions.
*/
typedef struct {
double value_1;
double value_2;
string string_value;
string operation;
string command;
regex_t regexp;
} Precondition;
/**
* Defines the structure that holds module conditions.
*/
@ -182,8 +170,13 @@ namespace Pandora_Modules {
Module_Kind module_kind;
string save;
list<Condition *> *condition_list;
list<Precondition *> *precondition_list;
list<Condition *> *precondition_list;
Cron *cron;
list<Condition *> *intensive_condition_list;
time_t timestamp;
unsigned char intensive_match;
int intensive_interval;
protected:
@ -233,7 +226,9 @@ namespace Pandora_Modules {
parseModuleKindFromString (string kind);
void setInterval (int interval);
void setIntensiveInterval (int intensive_interval);
int getInterval ();
int getIntensiveInterval ();
void setTimeout (int timeout);
int getTimeout ();
string getSave ();
@ -273,14 +268,23 @@ namespace Pandora_Modules {
void setSave (string save);
void exportDataOutput ();
void addPrecondition ();
void addCondition (string condition);
void addPrecondition (string precondition);
void addGenericCondition (string condition, list<Condition *> **condition_list);
void addCondition (string precondition);
void addPreCondition (string precondition);
void addIntensiveCondition (string intensivecondition);
int evaluatePreconditions ();
void evaluateConditions ();
int checkCron ();
void setCron (string cron_string);
void setCronInterval (int interval);
int evaluateCondition (string string_value, double double_value, Condition *condition);
int evaluateIntensiveConditions ();
int hasOutput ();
void setTimestamp (time_t timestamp);
time_t getTimestamp ();
void setIntensiveMatch (unsigned char intensive_match);
unsigned char getIntensiveMatch ();
};
}

View File

@ -18,6 +18,7 @@
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "pandora_windows_service.h"
#include "pandora_module_factory.h"
#include "pandora_module.h"
#include "pandora_module_exec.h"
@ -104,7 +105,8 @@ using namespace Pandora_Strutils;
#define TOKEN_SNMPCOMMUNITY ("module_snmp_community ")
#define TOKEN_SNMPAGENT ("module_snmp_agent ")
#define TOKEN_SNMPOID ("module_snmp_oid ")
#define TOKEN_ADVANCEDOPTIONS ("module_advanced_options ")
#define TOKEN_ADVANCEDOPTIONS ("module_advanced_options ")
#define TOKEN_INTENSIVECONDITION ("module_intensive_condition ")
string
parseLine (string line, string token) {
@ -153,15 +155,14 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
string module_disabled, module_min_ff_event, module_noseekeof;
string module_ping, module_ping_count, module_ping_timeout;
string module_snmpget, module_snmp_version, module_snmp_community, module_snmp_agent, module_snmp_oid;
string module_advanced_options, module_cooked;
string module_advanced_options, module_cooked, module_intensive_condition;
Pandora_Module *module;
bool numeric;
Module_Type type;
long agent_interval;
list<string> condition_list;
list<string> precondition_list;
list<string>::iterator condition_iter;
list<string>::iterator precondition_iter;
list<string> condition_list, precondition_list, intensive_condition_list;
list<string>::iterator condition_iter, precondition_iter, intensive_condition_iter;
Pandora_Windows_Service *service = NULL;
module_name = "";
module_type = "";
@ -217,6 +218,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
module_snmp_oid = "";
module_advanced_options = "";
module_cooked = "";
module_intensive_condition = "";
stringtok (tokens, definition, "\n");
@ -419,6 +421,15 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
if (module_cooked == "") {
module_cooked = parseLine (line, TOKEN_COOKED);
}
if (module_intensive_condition == "") {
module_intensive_condition = parseLine (line, TOKEN_INTENSIVECONDITION);
/* Queue the condition and keep looking for more */
if (module_intensive_condition != "") {
intensive_condition_list.push_back (module_intensive_condition);
module_intensive_condition = "";
}
}
iter++;
}
@ -556,13 +567,13 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
module->setAsync (true);
}
/* Module precondition */
/* Module precondition */
if (precondition_list.size () > 0) {
precondition_iter = precondition_list.begin ();
for (precondition_iter = precondition_list.begin ();
precondition_iter != precondition_list.end ();
precondition_iter++) {
module->addPrecondition (*precondition_iter);
module->addPreCondition (*precondition_iter);
}
}
@ -576,6 +587,35 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
}
}
/* Set the module interval */
if (module_interval != "") {
int interval;
try {
interval = strtoint (module_interval);
module->setInterval (interval);
module->setIntensiveInterval (interval);
} catch (Invalid_Conversion e) {
pandoraLog ("Invalid interval value \"%s\" for module %s",
module_interval.c_str (),
module_name.c_str ());
}
}
/* Module intensive condition */
if (intensive_condition_list.size () > 0) {
intensive_condition_iter = intensive_condition_list.begin ();
for (intensive_condition_iter = intensive_condition_list.begin ();
intensive_condition_iter != intensive_condition_list.end ();
intensive_condition_iter++) {
module->addIntensiveCondition (*intensive_condition_iter);
}
/* Adjust the module interval for non-intensive modules */
} else {
service = Pandora_Windows_Service::getInstance ();
module->setIntensiveInterval (module->getInterval () * (service->getInterval () / service->getIntensiveInterval ()));
}
/* Module cron */
if (module_crontab != "") {
module->setCron (module_crontab);
@ -643,19 +683,6 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
}
}
if (module_interval != "") {
int interval;
try {
interval = strtoint (module_interval);
module->setInterval (interval);
} catch (Invalid_Conversion e) {
pandoraLog ("Invalid interval value \"%s\" for module %s",
module_interval.c_str (),
module_name.c_str ());
}
}
if (module_post_process != "") {
module->setPostProcess (module_post_process);
}

View File

@ -73,10 +73,11 @@ Pandora_Windows_Service::setValues (const char * svc_name,
this->modules = NULL;
this->conf = NULL;
this->interval = 60000;
this->transfer_interval = this->interval;
this->elapsed_transfer_time = 0;
this->timestamp = 0;
this->run_time = 0;
this->udp_server = NULL;
this->tentacle_proxy = false;
this->intensive_interval = 60000;
}
/**
@ -202,7 +203,7 @@ Pandora_Windows_Service::check_broker_agents(string *all_conf){
void
Pandora_Windows_Service::pandora_init () {
string conf_file, interval, debug, transfer_interval, util_dir, path, env;
string conf_file, interval, debug, intensive_interval, util_dir, path, env;
string udp_server_enabled, udp_server_port, udp_server_addr, udp_server_auth_addr;
string name_agent, name;
string proxy_mode, server_ip;
@ -210,8 +211,6 @@ Pandora_Windows_Service::pandora_init () {
int pos, num;
static unsigned char first_run = 1;
setPandoraDebug (true);
conf_file = Pandora::getPandoraInstallDir ();
conf_file += "pandora_agent.conf";
@ -223,6 +222,34 @@ Pandora_Windows_Service::pandora_init () {
if (this->modules != NULL) {
delete this->modules;
}
/* Get the interval value (in seconds) and set it to the service */
interval = conf->getValue ("interval");
intensive_interval = conf->getValue ("intensive_interval");
if (interval != "") {
try {
/* miliseconds */
this->interval_sec = strtoint (interval);
this->interval = this->interval_sec * 1000;
} catch (Invalid_Conversion e) {
}
}
// Set the intensive interval
if (intensive_interval != "") {
try {
/* miliseconds */
this->intensive_interval = strtoint (intensive_interval) * 1000;
} catch (Invalid_Conversion e) {
}
} else {
this->intensive_interval = this->interval;
}
this->setSleepTime (this->intensive_interval);
// Read modules
this->modules = new Pandora_Module_List (conf_file);
delete []all_conf;
@ -232,35 +259,10 @@ Pandora_Windows_Service::pandora_init () {
}
name_agent = "PANDORA_AGENT=" + name;
putenv(name_agent.c_str());
/* Get the interval value (in seconds) and set it to the service */
interval = conf->getValue ("interval");
transfer_interval = conf->getValue ("transfer_interval");
debug = conf->getValue ("debug");
setPandoraDebug (is_enabled (debug));
if (interval != "") {
try {
/* miliseconds */
this->interval = strtoint (interval) * 1000;
} catch (Invalid_Conversion e) {
}
}
if (transfer_interval == "") {
this->transfer_interval = this->interval;
} else {
try {
/* miliseconds */
this->transfer_interval = strtoint (transfer_interval) * 1000;
} catch (Invalid_Conversion e) {
this->transfer_interval = this->interval;
}
}
this->setSleepTime (this->interval);
/*Check if proxy mode is set*/
proxy_mode = conf->getValue ("proxy_mode");
if (proxy_mode != "" && this->tentacle_proxy == false) {
@ -1382,21 +1384,13 @@ Pandora_Windows_Service::pandora_run_broker (string config) {
string server_addr;
int startup_delay = 0;
static unsigned char delayed = 0;
int exe = 1;
int i;
unsigned char data_flag = 0;
unsigned char intensive_match;
pandoraDebug ("Run begin");
conf = this->getConf ();
/* Sleep if a startup delay was specified */
startup_delay = atoi (conf->getValue ("startup_delay").c_str ()) * 1000;
if (startup_delay > 0 && delayed == 0) {
delayed = 1;
pandoraLog ("Delaying startup %d miliseconds", startup_delay);
Sleep (startup_delay);
}
/* Check for configuration changes */
if (getPandoraDebug () == false) {
if (this->checkConfig (config) == 1) {
@ -1407,8 +1401,6 @@ Pandora_Windows_Service::pandora_run_broker (string config) {
server_addr = conf->getValue ("server_ip");
execution_number++;
if (this->modules != NULL) {
this->modules->goFirst ();
@ -1416,18 +1408,29 @@ Pandora_Windows_Service::pandora_run_broker (string config) {
Pandora_Module *module;
module = this->modules->getCurrentValue ();
/* Check preconditions */
if (module->evaluatePreconditions () == 0) {
pandoraDebug ("Preconditions not matched for module %s", module->getName ().c_str ());
module->setNoOutput ();
this->modules->goNext ();
continue;
}
exe = module->evaluatePreconditions ();
if (exe == 0) {
/* Check preconditions */
if (module->checkCron () == 0) {
pandoraDebug ("Cron not matched for module %s", module->getName ().c_str ());
module->setNoOutput ();
this->modules->goNext ();
continue;
}
pandoraDebug ("Run %s", module->getName ().c_str ());
if (module->checkCron () == 1) {
module->run ();
Sleep(10);
module->run ();
if (! module->hasOutput ()) {
module->setNoOutput ();
this->modules->goNext ();
continue;
}
/* Save module data to an environment variable */
@ -1435,22 +1438,37 @@ Pandora_Windows_Service::pandora_run_broker (string config) {
module->exportDataOutput ();
}
/* Evaluate intensive conditions */
intensive_match = module->evaluateIntensiveConditions ();
if (intensive_match == module->getIntensiveMatch () && module->getTimestamp () + module->getInterval () * this->interval_sec > this->run_time) {
module->setNoOutput ();
this->modules->goNext ();
continue;
}
module->setIntensiveMatch (intensive_match);
if (module->getTimestamp () + module->getInterval () * this->interval_sec <= this->run_time) {
module->setTimestamp (this->run_time);
}
/* Evaluate module conditions */
module->evaluateConditions ();
/* At least one module has data */
data_flag = 1;
this->modules->goNext ();
}
}
this->elapsed_transfer_time += this->interval;
if (this->elapsed_transfer_time >= this->transfer_interval) {
this->elapsed_transfer_time = 0;
if (!server_addr.empty ()) {
if (data_flag == 1 || this->timestamp + this->interval_sec <= this->run_time) {
this->sendXml (this->modules);
// Send the XML
if (!server_addr.empty ()) {
this->sendXml (this->modules);
}
}
}
return;
}
@ -1458,23 +1476,27 @@ void
Pandora_Windows_Service::pandora_run () {
Pandora_Agent_Conf *conf = NULL;
string server_addr, conf_file, *all_conf;
int startup_delay = 0;
static unsigned char delayed = 0;
int exe = 1;
int i, num;
int startup_delay = 0;
int i, num;
static unsigned char delayed = 0;
unsigned char data_flag = 0;
unsigned char intensive_match;
pandoraDebug ("Run begin");
conf = this->getConf ();
/* Sleep if a startup delay was specified */
startup_delay = atoi (conf->getValue ("startup_delay").c_str ()) * 1000;
if (startup_delay > 0 && delayed == 0) {
if (startup_delay > 0 && delayed == 0) {
delayed = 1;
pandoraLog ("Delaying startup %d miliseconds", startup_delay);
Sleep (startup_delay);
}
pandoraLog ("Delaying startup %d miliseconds", startup_delay);
Sleep (startup_delay);
}
/* Set the run time */
this->run_time = time (NULL);
/* Check for configuration changes */
if (getPandoraDebug () == false) {
conf_file = Pandora::getPandoraInstallDir ();
@ -1498,17 +1520,28 @@ Pandora_Windows_Service::pandora_run () {
module = this->modules->getCurrentValue ();
exe = module->evaluatePreconditions ();
if (exe == 0) {
/* Check preconditions */
if (module->evaluatePreconditions () == 0) {
pandoraDebug ("Preconditions not matched for module %s", module->getName ().c_str ());
module->setNoOutput ();
this->modules->goNext ();
continue;
}
/* Check preconditions */
if (module->checkCron () == 0) {
pandoraDebug ("Cron not matched for module %s", module->getName ().c_str ());
module->setNoOutput ();
this->modules->goNext ();
continue;
}
pandoraDebug ("Run %s", module->getName ().c_str ());
if (module->checkCron () == 1) {
module->run ();
Sleep(5);
module->run ();
if (! module->hasOutput ()) {
module->setNoOutput ();
this->modules->goNext ();
continue;
}
/* Save module data to an environment variable */
@ -1516,25 +1549,39 @@ Pandora_Windows_Service::pandora_run () {
module->exportDataOutput ();
}
/* Evaluate intensive conditions */
intensive_match = module->evaluateIntensiveConditions ();
if (intensive_match == module->getIntensiveMatch () && module->getTimestamp () + module->getInterval () * this->interval_sec > this->run_time) {
module->setNoOutput ();
this->modules->goNext ();
continue;
}
module->setIntensiveMatch (intensive_match);
if (module->getTimestamp () + module->getInterval () * this->interval_sec <= this->run_time) {
module->setTimestamp (this->run_time);
}
/* Evaluate module conditions */
module->evaluateConditions ();
/* At least one module has data */
data_flag = 1;
this->modules->goNext ();
}
}
this->elapsed_transfer_time += this->interval;
if (this->elapsed_transfer_time >= this->transfer_interval) {
this->elapsed_transfer_time = 0;
if (data_flag == 1 || this->timestamp + this->interval_sec <= this->run_time) {
// Send the XML
if (!server_addr.empty ()) {
this->sendXml (this->modules);
}
}
/* Get the interval value (in minutes) */
pandoraDebug ("Next execution on %d seconds", this->interval / 1000);
pandoraDebug ("Next execution on %d seconds", this->interval_sec);
/* Load and execute brokers */
num = count_broker_agents();
@ -1551,6 +1598,11 @@ Pandora_Windows_Service::pandora_run () {
pandora_init ();
}
/* Reset time reference if necessary */
if (this->timestamp + this->interval_sec <= this->run_time) {
this->timestamp = this->run_time;
}
return;
}
@ -1558,3 +1610,14 @@ Pandora_Agent_Conf *
Pandora_Windows_Service::getConf () {
return this->conf;
}
long
Pandora_Windows_Service::getInterval () {
return this->interval;
}
long
Pandora_Windows_Service::getIntensiveInterval () {
return this->intensive_interval;
}

View File

@ -22,6 +22,7 @@
#define __PANDORA_WINDOWS_SERVICE_H__
#include <list>
#include <time.h>
#include "windows_service.h"
#include "pandora_agent_conf.h"
#include "modules/pandora_module_list.h"
@ -43,8 +44,8 @@ namespace Pandora {
Pandora_Module_List *modules;
long execution_number;
string agent_name;
long elapsed_transfer_time;
long transfer_interval;
time_t timestamp;
time_t run_time;
bool started;
void *udp_server;
bool tentacle_proxy;
@ -91,6 +92,8 @@ namespace Pandora {
void pandora_init ();
long interval;
long interval_sec;
long intensive_interval;
public:
static Pandora_Windows_Service *getInstance ();
@ -101,9 +104,12 @@ namespace Pandora {
const char *svc_description);
void start ();
int sendXml (Pandora_Module_List *modules);
void sendBufferedXml (string path);
Pandora_Agent_Conf *getConf ();
int sendXml (Pandora_Module_List *modules);
void sendBufferedXml (string path);
Pandora_Agent_Conf *getConf ();
long getInterval ();
long getIntensiveInterval ();
};
}