2008-04-09 Esteban Sanchez <estebans@artica.es>

* modules/pandora_data.[cc,h]: Added to repository. Implements a
        Pandora_Data object, which holds a value and the timestamp when it
        was created.

        * modules/pandora_module.[cc,h]: It holds now a list of Pandora_Data
        objects. The XML is generated based on the size of this list. Output
        property has became obsolete and child modules must use setOutput().

        * modules/pandora_module_cpuusage.cc,
        modules/pandora_module_exec.cc,
        modules/pandora_module_freedisk.cc,
        modules/pandora_module_freememory.cc,
        modules/pandora_module_odbc.cc, modules/pandora_module_proc.cc,
        modules/pandora_module_service.cc: Updated to new Pandora_Module
        parent class.

        * modules/pandora_module_list.cc: Deleted debug output.

        * pandora.cc: Now uses SYSTEMTIME instead of old time_t.

        * pandora_windows_service.[cc,h]: Added Ramon Novoa to authors. Added
        a new configuration token transfer_interval which sets the interval
        where the data file will be sent to the server. If the current
        interval token is lower than this transfer interval, the data will be
        added into a data_list XML tag.

        * PandoraAgent.dev: Added new files.

        * bin/PandoraAgent.exe: Updated to last commit.



git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@803 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
esanchezm 2008-04-09 15:48:06 +00:00
parent a9c83a2f74
commit 9cc297d7a6
18 changed files with 451 additions and 155 deletions

View File

@ -1,3 +1,35 @@
2008-04-09 Esteban Sanchez <estebans@artica.es>
* modules/pandora_data.[cc,h]: Added to repository. Implements a
Pandora_Data object, which holds a value and the timestamp when it
was created.
* modules/pandora_module.[cc,h]: It holds now a list of Pandora_Data
objects. The XML is generated based on the size of this list. Output
property has became obsolete and child modules must use setOutput().
* modules/pandora_module_cpuusage.cc,
modules/pandora_module_exec.cc,
modules/pandora_module_freedisk.cc,
modules/pandora_module_freememory.cc,
modules/pandora_module_odbc.cc, modules/pandora_module_proc.cc,
modules/pandora_module_service.cc: Updated to new Pandora_Module
parent class.
* modules/pandora_module_list.cc: Deleted debug output.
* pandora.cc: Now uses SYSTEMTIME instead of old time_t.
* pandora_windows_service.[cc,h]: Added Ramon Novoa to authors. Added
a new configuration token transfer_interval which sets the interval
where the data file will be sent to the server. If the current
interval token is lower than this transfer interval, the data will be
added into a data_list XML tag.
* PandoraAgent.dev: Added new files.
* bin/PandoraAgent.exe: Updated to last commit.
2008-04-02 Esteban Sanchez <estebans@artica.es>
* pandora_agent_conf.[cc,h]: Object adapted to be a singleton so it

View File

@ -1,7 +1,7 @@
[Project]
FileName=PandoraAgent.dev
Name=PandoraAgent
UnitCount=71
UnitCount=73
Type=1
Ver=1
ObjFiles=
@ -757,3 +757,23 @@ Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit72]
FileName=modules\pandora_data.h
CompileCpp=1
Folder=Modules
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit73]
FileName=modules\pandora_data.cc
CompileCpp=1
Folder=Modules
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@ -0,0 +1,89 @@
/* Pandora data class to represent a value and a timestamp.
Copyright (C) 2006 Artica ST.
Written by Esteban Sanchez.
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; either version 2, or (at your option)
any later version.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "pandora_data.h"
using namespace Pandora;
/**
* Pandora_Data constructor.
*
* Set all attributes
*
* @param value Data value.
* @param timestamp Timeestamp value.
*/
Pandora_Data::Pandora_Data (string value) {
this->value = value;
GetSystemTime (&(this->timestamp));
}
/**
* Pandora_Data default constructor
*
* Set all parameters to blank
*/
Pandora_Data::Pandora_Data () {
this->value = "";
GetSystemTime (&(this->timestamp));
}
/**
* Destructor of Pandora_Data.
*/
Pandora_Data::~Pandora_Data () {
}
/**
* Get value property of Pandora_Data object
*
* @return Value property.
*/
string
Pandora_Data::getValue () const {
return this->value;
}
/**
* Get timestamp property of Pandora_Data object in a human readable format.
*
* @return Timestamp formatted.
*/
string
Pandora_Data::getTimestamp () const {
char strtime[20];
string retval;
sprintf (strtime, "%d-%02d-%02d %02d:%02d:%02d", this->timestamp.wYear, this->timestamp.wMonth, this->timestamp.wDay,
this->timestamp.wHour, this->timestamp.wMinute, this->timestamp.wSecond);
retval = strtime;
return retval;
}
/**
* Set value property of Pandora_Data object
*
* @param value Value to set.
*/
void
Pandora_Data::setValue (string value) {
this->value = value;
}

View File

@ -0,0 +1,50 @@
/* Pandora data class to represent a value and a timestamp.
Copyright (C) 2006 Artica ST.
Written by Esteban Sanchez.
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; either version 2, or (at your option)
any later version.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __PANDORA_DATA_H__
#define __PANDORA_DATA_H__
#include <string>
#include <windows.h>
using namespace std;
namespace Pandora {
/**
* Class to implement the Pandora Windows service.
*/
class Pandora_Data {
private:
string value;
SYSTEMTIME timestamp;
public:
Pandora_Data ();
Pandora_Data (string value);
~Pandora_Data ();
string getValue () const;
string getTimestamp () const;
void setValue (string value);
};
}
#endif

View File

@ -37,10 +37,10 @@ Pandora_Module::Pandora_Module (string name) {
this->module_name = name;
this->executions = 0;
this->module_interval = 1;
this->output = "";
this->max = 0;
this->min = 0;
this->has_limits = false;
this->data_list = NULL;
}
/**
@ -49,6 +49,28 @@ Pandora_Module::Pandora_Module (string name) {
* Should be redefined by child classes.
*/
Pandora_Module::~Pandora_Module () {
this->cleanDataList ();
}
void
Pandora_Module::cleanDataList () {
Pandora_Data *data;
list<Pandora_Data *>::iterator iter;
if (this->data_list) {
if (this->data_list->size () > 0) {
iter = this->data_list->begin ();
for (iter = this->data_list->begin ();
iter != this->data_list->end ();
iter++) {
data = *iter;
delete data;
}
}
delete this->data_list;
this->data_list = NULL;
}
}
/**
@ -174,31 +196,51 @@ Pandora_Module::getModuleType () const {
* the interval range.
*/
string
Pandora_Module::getOutput () const {
switch (this->module_type) {
case TYPE_GENERIC_DATA:
case TYPE_GENERIC_DATA_INC:
case TYPE_GENERIC_PROC:
Pandora_Module::getDataOutput (Pandora_Data *data) {
int value;
if (this->module_type == TYPE_GENERIC_DATA_STRING) {
return data->getValue ();
}
try {
value = Pandora_Strutils::strtoint (this->output);
value = Pandora_Strutils::strtoint (data->getValue ());
} catch (Pandora_Strutils::Invalid_Conversion e) {
pandoraLog ("Output error on module %s",
this->module_name.c_str ());
throw Output_Error ();
}
if (this->has_limits) {
if (value >= this->max || value <= this->min) {
pandoraLog ("The returned value was not in the interval on module %s",
this->module_name.c_str ());
throw Value_Error ();
}
}
return Pandora_Strutils::inttostr (value);
default:
return this->output;
}
/**
* Set the output of the module.
*
* If the function is called more than once before calling getXML, the
* output will be accumulated and added to a <datalist> tag.
*
* @param output Output to add.
*/
void
Pandora_Module::setOutput (string output) {
Pandora_Data *data;
if (this->data_list == NULL)
this->data_list = new list<Pandora_Data *> ();
data = new Pandora_Data (output);
this->data_list->push_back (data);
}
/**
* Run the module and generates the output.
*
@ -211,9 +253,6 @@ Pandora_Module::getOutput () const {
*/
void
Pandora_Module::run () {
this->output = "";
/* Check the interval */
if (this->executions % this->module_interval != 0) {
pandoraDebug ("%s: Interval is not fulfilled",
@ -248,29 +287,18 @@ Pandora_Module::run () {
*/
TiXmlElement *
Pandora_Module::getXml () {
string data;
TiXmlElement *root;
TiXmlElement *element;
TiXmlElement *data_list_element;
TiXmlElement *data_element;
TiXmlText *text;
string item_str, data_str, desc_str;
string item_clean, data_clean, desc_clean;
Pandora_Data *data;
pandoraDebug ("%s getXML begin", module_name.c_str ());
if (!this->has_output) {
return NULL;
}
try {
data = this->getOutput ();
} catch (Output_Error e) {
pandoraLog ("Output error on module %s",
this->module_name.c_str ());
return NULL;
} catch (Value_Error e) {
pandoraLog ("The returned value was not in the interval on module %s",
this->module_name.c_str ());
if (!this->has_output || (this->data_list && this->data_list->size () < 1)) {
return NULL;
}
@ -290,13 +318,47 @@ Pandora_Module::getXml () {
delete element;
delete text;
if (this->data_list && this->data_list->size () > 1) {
list<Pandora_Data *>::iterator iter;
data_list_element = new TiXmlElement ("data_list");
iter = this->data_list->begin ();
for (iter = this->data_list->begin ();
iter != this->data_list->end ();
iter++) {
data = *iter;
data_element = new TiXmlElement ("data");
element = new TiXmlElement ("value");
data_clean = strreplace (this->getDataOutput (data), "%", "%%" );
text = new TiXmlText (data_clean);
element->InsertEndChild (*text);
data_element->InsertEndChild (*element);
delete text;
delete element;
element = new TiXmlElement ("timestamp");
text = new TiXmlText (data->getTimestamp ());
element->InsertEndChild (*text);
data_element->InsertEndChild (*element);
delete text;
delete element;
data_list_element->InsertEndChild (*data_element);
}
root->InsertEndChild (*data_list_element);
delete data_list_element;
} else {
data = data_list->front ();
element = new TiXmlElement ("data");
data_str = strreplace (data, "%", "%%" );
text = new TiXmlText (data_str);
data_clean = strreplace (this->getDataOutput (data), "%", "%%" );
text = new TiXmlText (data_clean);
element->InsertEndChild (*text);
root->InsertEndChild (*element);
delete text;
delete element;
}
element = new TiXmlElement ("description");
text = new TiXmlText (this->module_description);
@ -305,6 +367,7 @@ Pandora_Module::getXml () {
delete text;
delete element;
this->cleanDataList ();
pandoraDebug ("%s getXML end", module_name.c_str ());
return root;
}

View File

@ -22,10 +22,13 @@
#define __PANDORA_MODULE_H__
#include "../pandora.h"
#include "pandora_data.h"
#include "../tinyxml/tinyxml.h"
#include <list>
#include <string>
using namespace Pandora;
/**
* Definition of Pandora modules.
*/
@ -112,11 +115,11 @@ namespace Pandora_Modules {
Module_Type module_type;
string module_kind_str;
Module_Kind module_kind;
list<Pandora_Data *> *data_list;
string getDataOutput (Pandora_Data *data);
void cleanDataList ();
protected:
/**
* Module output generated at execution.
*/
string output;
/**
* Indicates if the module generated output in
* his last execution.
@ -146,7 +149,7 @@ namespace Pandora_Modules {
virtual void run ();
virtual string getOutput () const;
virtual void setOutput (string output);
string getName () const;
string getDescription () const;

View File

@ -54,7 +54,7 @@ Pandora_Module_Cpuusage::run () {
try {
res = Pandora_Wmi::getCpuUsagePercentage (this->cpu_id);
this->output = inttostr (res);
this->setOutput (inttostr (res));
} catch (Pandora_Wmi::Pandora_Wmi_Exception e) {
this->has_output = false;
}

View File

@ -140,12 +140,14 @@ Pandora_Module_Exec::run () {
PeekNamedPipe (out_read, buffer, BUFSIZE, &read, &avail, NULL);
/* Read from the stdout */
if (read != 0) {
string output;
do {
ReadFile (out_read, buffer, BUFSIZE, &read,
NULL);
buffer[read] = '\0';
this->output += (char *) buffer;
output += (char *) buffer;
} while (read >= BUFSIZE);
this->setOutput (output);
}
/* Close job, process and thread handles. */

View File

@ -59,7 +59,7 @@ Pandora_Module_Freedisk::run () {
try {
res = Pandora_Wmi::getDiskFreeSpace (this->disk_id);
this->output = longtostr (res);
this->setOutput (longtostr (res));
} catch (Pandora_Wmi::Pandora_Wmi_Exception e) {
this->has_output = false;
}

View File

@ -51,7 +51,7 @@ Pandora_Module_Freememory::run () {
try {
res = Pandora_Wmi::getFreememory ();
this->output = longtostr (res);
this->setOutput (longtostr (res));
} catch (Pandora_Wmi::Pandora_Wmi_Exception e) {
this->has_output = false;
}

View File

@ -156,10 +156,8 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition)
case MODULE_ODBC:
module_odbc = (Pandora_Module_Odbc *) module;
modules->push_back (module_odbc);
cout << "ASDS" << endl;
break;
default:
cout << "NONE" << endl;
break;
}
}

View File

@ -154,13 +154,16 @@ Pandora_Module_Odbc::doQuery () {
if (results->next ()) {
if (this->getTypeInt () == TYPE_GENERIC_DATA_STRING) {
string output;
for (int i = 1; i <= columns; i++) {
this->output += results->getString (i);
output += results->getString (i);
if (i + 1 <= columns)
this->output += " | ";
output += " | ";
}
this->setOutput (output);
} else {
this->output = longtostr (results->getLong (1));
this->setOutput (longtostr (results->getLong (1)));
}
}
}

View File

@ -56,5 +56,5 @@ Pandora_Module_Proc::run () {
res = Pandora_Wmi::isProcessRunning (this->process_name);
this->output = inttostr (res);
this->setOutput (inttostr (res));
}

View File

@ -57,5 +57,5 @@ Pandora_Module_Service::run () {
}
res = Pandora_Wmi::isServiceRunning (this->service_name);
this->output = inttostr (res);
this->setOutput (inttostr (res));
}

View File

@ -101,12 +101,11 @@ pandoraWriteLog (string filename, string line) {
char str_time[25];
FILE *file;
string filepath;
time_t now;
struct tm *gmtime;
SYSTEMTIME st;
now = time (0);
gmtime = localtime (&now);
strftime (str_time, 25, "%m-%d-%y %H:%M:%S: ", gmtime);
GetSystemTime(&st);
sprintf (str_time, "%d-%02d-%02d %02d:%02d:%02d ", st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
buffer = (char *) str_time;
buffer += line;

View File

@ -1,7 +1,7 @@
/* Pandora agents service for Win32.
Copyright (C) 2006 Artica ST.
Written by Esteban Sanchez.
Written by Esteban Sanchez, Ramon Novoa.
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
@ -56,9 +56,13 @@ Pandora_Windows_Service::Pandora_Windows_Service (const char * svc_name,
&Pandora_Windows_Service::pandora_init);
this->setRunFunction ((void (Windows_Service::*) ())
&Pandora_Windows_Service::pandora_run);
execution_number = 0;
this->modules = NULL;
this->conf = NULL;
this->interval = 60000;
this->transfer_interval = this->interval;
this->elapsed_transfer_time = 0;
}
/**
@ -94,8 +98,7 @@ is_enabled (string value) {
void
Pandora_Windows_Service::pandora_init () {
int interval_ms = 60000;
string conf_file, interval, debug;
string conf_file, interval, debug, transfer_interval;
setPandoraDebug (true);
@ -106,8 +109,9 @@ Pandora_Windows_Service::pandora_init () {
this->conf->setFile (conf_file);
this->modules = new Pandora_Module_List (conf_file);
/* Get the interval value (in minutes) and set it to the service */
/* 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));
@ -115,13 +119,25 @@ Pandora_Windows_Service::pandora_init () {
if (interval != "") {
try {
/* miliseconds */
interval_ms = strtoint (interval) * 1000;
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;
}
}
cout << "trans: " << this->transfer_interval << endl;
srand ((unsigned) time (0));
this->setSleepTime (interval_ms);
this->setSleepTime (this->interval);
pandoraLog ("Pandora agent started");
}
@ -363,13 +379,11 @@ Pandora_Windows_Service::pandora_run () {
TiXmlDocument *doc;
TiXmlElement *local_xml, *agent;
string xml_filename, random_integer;
string tmp_filename, tmp_filepath, interval;
string tmp_filename, tmp_filepath;
bool saved;
pandoraDebug ("Run begin");
agent = getXmlHeader ();
execution_number++;
if (this->modules != NULL) {
@ -377,13 +391,29 @@ Pandora_Windows_Service::pandora_run () {
while (! this->modules->isLast ()) {
Pandora_Module *module;
string result;
module = this->modules->getCurrentValue ();
pandoraDebug ("Run %s", module->getName ().c_str ());
module->run ();
this->modules->goNext ();
}
}
this->elapsed_transfer_time += interval;
cout << "interval time: " << interval << " transfer time:" << this->transfer_interval << " time passed: " << this->elapsed_transfer_time << endl;
if (this->elapsed_transfer_time >= this->transfer_interval) {
agent = getXmlHeader ();
if (this->modules != NULL) {
this->modules->goFirst ();
while (! this->modules->isLast ()) {
Pandora_Module *module;
module = this->modules->getCurrentValue ();
local_xml = module->getXml ();
if (local_xml != NULL) {
agent->InsertEndChild (*local_xml);
@ -394,6 +424,8 @@ Pandora_Windows_Service::pandora_run () {
}
}
this->elapsed_transfer_time = 0;
/* Generate temporal filename */
random_integer = inttostr (rand());
tmp_filename = conf->getValue ("agent_name");
if (tmp_filename == "") {
@ -407,7 +439,7 @@ Pandora_Windows_Service::pandora_run () {
}
tmp_filepath = xml_filename + tmp_filename;
/* Copy the XML to a temporal file */
/* Copy the XML to temporal file */
pandoraDebug ("Copying XML on %s", tmp_filepath.c_str ());
doc = new TiXmlDocument (tmp_filepath);
doc->InsertEndChild (*agent);
@ -421,6 +453,7 @@ Pandora_Windows_Service::pandora_run () {
return;
}
/* Only send if debug is not activated */
if (getPandoraDebug () == false) {
this->copyDataFile (tmp_filename);
@ -429,10 +462,10 @@ Pandora_Windows_Service::pandora_run () {
} catch (Pandora_File::Delete_Error e) {
}
}
}
/* Get the interval value (in minutes) */
interval = conf->getValue ("interval");
pandoraDebug ("Next execution on %s seconds", interval.c_str ());
pandoraDebug ("Next execution on %d seconds", this->interval / 1000);
return;
}

View File

@ -29,6 +29,7 @@
#include "ssh/pandora_ssh_client.h"
using namespace std;
using namespace Pandora_Modules;
namespace Pandora {
/**
@ -37,9 +38,12 @@ namespace Pandora {
class Pandora_Windows_Service : public Windows_Service {
private:
Pandora_Agent_Conf *conf;
Pandora_Modules::Pandora_Module_List *modules;
Pandora_Module_List *modules;
long execution_number;
string agent_name;
long interval;
long elapsed_transfer_time;
long transfer_interval;
TiXmlElement *getXmlHeader ();
void copyDataFile (string filename);
@ -51,7 +55,7 @@ namespace Pandora {
void copyFtpDataFile (string host,
string remote_path,
string filename);
public:
void pandora_run ();
void pandora_init ();
public: