// Authors: eduardo.ramos.testillano@gmail.com
// cisco.tierra@gmail.com
-
#include <fstream>
#include <iostream>
+#include <time.h>
+#include <sys/stat.h> // chmod
+#include <fcntl.h> // open / write
#include <string>
#include <map>
class MyCounterRecorder : public anna::oam::CounterRecorder {
- // pure virtual definitions:
- void open() throw(anna::RuntimeException) {;}
- void apply(const anna::oam::Counter& counter) throw(anna::RuntimeException) {;}
- void close() throw() {;}
- std::string asString() const throw() { return "Physical dump not implemented: see memory accumulations writting context (kill -10 <pid>)"; }
+ // attributes
+ int a_stream;
+ std::string a_fileNamePrefix;
+ std::string a_fileName;
+ time_t a_previousTime;
+ std::string a_fixedLine;
+
+ // pure virtual definitions:
+ void open() throw(anna::RuntimeException) {
+ static char str [256];
+
+ const time_t now = ::time (NULL);
+ struct tm tmNow;
+ struct tm tmPrevious;
+
+ anna_memcpy (&tmNow, localtime (&now), sizeof (tmNow));
+ anna_memcpy (&tmPrevious, localtime (&a_previousTime), sizeof (tmPrevious));
+
+ sprintf (
+ str,".Date%04d%02d%02d.Time%02d%02d%02d",
+ 1900 + (tmNow.tm_year), (tmNow.tm_mon) + 1,
+ tmNow.tm_mday, tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec);
+
+ a_fileName = a_fileNamePrefix;
+ a_fileName += str;
+
+ LOGDEBUG (
+ std::string msg ("Flush counters | ");
+ msg += a_fileName;
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+
+ if ((a_stream = ::open (a_fileName.c_str (), O_WRONLY | O_CREAT, S_IWUSR)) == -1)
+ throw RuntimeException (anna::functions::asString("Error opening file '%s'; errno = %d", a_fileName.c_str(), errno), ANNA_FILE_LOCATION);
+
+ sprintf (str, "%04d-%02d-%02d %02d:%02d|%04d-%02d-%02d %02d:%02d",
+ 1900 + (tmPrevious.tm_year), (tmPrevious.tm_mon) + 1,
+ tmPrevious.tm_mday, tmPrevious.tm_hour, tmPrevious.tm_min,
+ 1900 + (tmNow.tm_year), (tmNow.tm_mon) + 1,
+ tmNow.tm_mday, tmNow.tm_hour, tmNow.tm_min
+ );
+
+ a_fixedLine = str;
+ }
+
+
+ void apply(const anna::oam::Counter& counter) throw(anna::RuntimeException) {
+ static char line [356];
+ anna::oam::Counter::type_t value = counter;
+ sprintf (line, "%s|%06d|%07u|%s\n", a_fixedLine.c_str (), counter.getReference(), value, counter.getName ().c_str ());
+ if (write (a_stream, line, anna_strlen (line)) == -1)
+ throw RuntimeException (anna::functions::asString("Error writting to file '%s'; errno = %d", a_fileName.c_str(), errno), ANNA_FILE_LOCATION);
+ }
+
+ void close() throw() {
+ if (a_stream != -1) {
+ ::close (a_stream);
+ a_stream = -1;
+ }
+ chmod (a_fileName.c_str (), S_IWUSR | S_IRUSR);
+ a_previousTime = ::time (NULL);
+ }
+
+ std::string asString() const throw() {
+ std::string result = "Physical counters dump at file '";
+ result += a_fileName;
+ result += "'. Another way to see counters: context dump (kill -10 <pid>";
+ return result;
+ }
+
+ public:
+ MyCounterRecorder(const std::string &fnp) : a_stream(-1), a_fileNamePrefix(fnp) {
+ a_previousTime = ::time (NULL);
+ }
};
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
commandLine.add("detailedLog", anna::CommandLine::Argument::Optional, "Insert detailed information at log files. Should be disabled on automatic tests. Useful on '-balance' mode to know messages flow along the sockets", false);
commandLine.add("logStatisticSamples", anna::CommandLine::Argument::Optional, "Log statistics samples for the provided concept id list, over './sample.<concept id>.csv' files. For example: \"1,2\" will log concepts 1 and 2. Reserved word \"all\" activates all registered statistics concept identifiers. That ids are shown at context dump (see help to get it).");
commandLine.add("burstLog", anna::CommandLine::Argument::Optional, "Burst operations log file. By default 'launcher.burst'. Empty string or \"null\" name, to disable. Warning: there is no rotation for log files (use logrotate or whatever). Output: dot (.) for each burst message sent/pushed, cross (x) for popped ones, and order number when multiple of 1% of burst list size, plus OTA requests when changed.");
+ commandLine.add("cntDir", anna::CommandLine::Argument::Optional, "Counters directory. By default is the current execution directory. Warning: a counter file will be dump per record period; take care about the possible accumulation of files");
+ commandLine.add("cntRecordPeriod", anna::CommandLine::Argument::Optional, "Counters record procedure period in milliseconds. If missing, default value of 300000 (5 minutes) will be assigned. Value of 0 disables the record procedure.");
// Communications
commandLine.add("httpServer", anna::CommandLine::Argument::Optional, "HTTP Management interface address (using i.e. curl tool) in '<address>:<port>' format. For example: 10.20.30.40:8080");
commandLine.add("httpServerShared", anna::CommandLine::Argument::Optional, "Enables shared bind for HTTP Management interface address. It would be useful i.e. to allow a great amount of curl operations per second", false);
void Launcher::checkTimeMeasure(const char * commandLineParameter, bool optional) throw(anna::RuntimeException) {
CommandLine& cl(anna::CommandLine::instantiate());
- if (!cl.exists(commandLineParameter) && optional) return; // si fuese obligatorio daria error de arranque.
+ if (!cl.exists(commandLineParameter) && optional) return; // start error if mandatory
std::string parameter = cl.getValue(commandLineParameter);
// workMode = anna::comm::Communicator::WorkMode::Clone;
a_communicator = new MyCommunicator(workMode);
a_timeEngine = new anna::timex::Engine((anna::Millisecond)300000, (anna::Millisecond)150);
- a_counterRecorder = new MyCounterRecorder();
- a_counterRecorderClock = new MyCounterRecorderClock("Counters record procedure clock", Millisecond(10000));
- //a_counterRecorderClock = new MyCounterRecorderClock("Counters record procedure clock", Millisecond(300000));
+
+ // Counters record procedure:
+ anna::Millisecond cntRecordPeriod = (anna::Millisecond)300000; // ms
+ if (cl.exists("cntRecordPeriod")) cntRecordPeriod = cl.getIntegerValue("cntRecordPeriod");
+ if (cntRecordPeriod != 0) {
+ checkTimeMeasure("cntRecordPeriod");
+ a_counterRecorderClock = new MyCounterRecorderClock("Counters record procedure clock", cntRecordPeriod); // clock
+
+ std::string cntDir = ".";
+ if (cl.exists("cntDir")) cntDir = cl.getValue("cntDir");
+ a_counterRecorder = new MyCounterRecorder(cntDir + anna::functions::asString("/Counters.Pid%d", (int)getPid()));
+ }
}
void Launcher::run()
/////////////////////////////////
// Counter recorder associated //
/////////////////////////////////
- oamDiameterComm.setCounterRecorder(a_counterRecorder);
- oamDiameterCodec.setCounterRecorder(a_counterRecorder);
- a_timeEngine->activate(a_counterRecorderClock); // start clock
+ if (a_counterRecorderClock) {
+ oamDiameterComm.setCounterRecorder(a_counterRecorder);
+ oamDiameterCodec.setCounterRecorder(a_counterRecorder);
+ a_timeEngine->activate(a_counterRecorderClock); // start clock
+ }
// Checking command line parameters
if (cl.exists("sessionBasedModelsClientSocketSelection")) {