Register accumulators on stat engine to centralize reports. TODO remove from engine...
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Fri, 9 Oct 2015 15:52:30 +0000 (17:52 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Fri, 9 Oct 2015 15:52:30 +0000 (17:52 +0200)
include/anna/diameter.comm/LocalServer.hpp
include/anna/diameter.comm/Server.hpp
include/anna/statistics/Engine.hpp
source/diameter.comm/LocalServer.cpp
source/diameter.comm/Server.cpp
source/diameter.comm/Session.cpp
source/statistics/Accumulator.cpp
source/statistics/Engine.cpp

index 734972d..e97fb20 100644 (file)
@@ -67,7 +67,7 @@ class LocalServer {
   // Statistics
   int a_processing_time__StatisticConceptId; // request from local server (dpr's, etc.)
   int a_received_message_size__StatisticConceptId;
-  anna::statistics::Accumulator a_statisticsAccumulator;
+  anna::statistics::Accumulator *a_statisticsAccumulator;
   void initializeStatisticConcepts() throw();
   void resetStatistics() throw();
 
@@ -412,4 +412,3 @@ protected:
 }
 
 #endif
-
index 15c29de..0484484 100644 (file)
@@ -73,7 +73,7 @@ class Server {
   // Statistics
   int a_processing_time__StatisticConceptId;
   int a_received_message_size__StatisticConceptId;
-  anna::statistics::Accumulator a_statisticsAccumulator;
+  anna::statistics::Accumulator *a_statisticsAccumulator;
   void initializeStatisticConcepts() throw();
   void resetStatistics() throw();
 
@@ -331,4 +331,3 @@ protected:
 }
 
 #endif
-
index bb376f8..8f59a2e 100644 (file)
 
 #include <anna/core/Singleton.hpp>
 #include <anna/core/util/Millisecond.hpp>
+#include <anna/core/mt/Mutex.hpp>
 
 // Standard
 #include <string>
+#include <vector>
 #include <map>
 
 // Local
@@ -45,6 +47,8 @@ typedef std::map <int, _concept_identification_t> _concept_identification_map_t;
 typedef std::map <int, _concept_identification_t>::const_iterator _concept_identification_map_iter;
 typedef std::map <int, _concept_identification_t>::iterator _concept_identification_map_nc_iter;
 
+typedef std::vector <Accumulator*> _accumulator_vector_t;
+typedef std::vector <Accumulator*>::const_iterator _accumulator_vector_it;
 
 
 /**
@@ -57,6 +61,9 @@ class Engine : public anna::Singleton <Engine> {
 
 public:
 
+  /** Destructor */
+  ~Engine();
+
   // Sets
 
   /**
@@ -130,6 +137,14 @@ public:
   */
   bool enabled(void) const throw() { return (a_enabled); }
 
+  /**
+  * There is an advantage creating Accumulators over the engine: the #asXML method will show all the controlled information
+  * easily. Anyway, you could allocate this class objects without using this. Then, this is a helper to create accumulators
+  * and centralize their reports.
+  *
+  * @return New allocated accumulator, to be used by the client
+  */
+  Accumulator *createAccumulator() throw();
 
   /**
   * Class string representation
@@ -154,8 +169,10 @@ private:
   Engine(); // private constructor
 
   _concept_identification_map_t a_concept_identification_map;
+  _accumulator_vector_t a_accumulators; // you could create accumulators regardless the engine, but this is easier and asXML will show all the information easily
   bool a_enabled;
   int a_sequence_concept_id;
+  anna::Mutex a_mutex; // for logSample
 
   bool logSample(const int & conceptId, const anna::Millisecond & unixTimestamp, const double & value) const throw();
 
index a14b3c6..67c35fc 100644 (file)
@@ -44,34 +44,37 @@ LocalServer::LocalServer() :
   a_lock(false),
   a_available(false),
   a_lastUsedResource(NULL) {
-  a_statisticsAccumulator.reset();
+  a_statisticsAccumulator = anna::statistics::Engine::instantiate().createAccumulator();
 }
 
 
 void LocalServer::initializeStatisticConcepts() throw() {
+  // Realm name
+  std::string realmName = a_engine ? a_engine->getRealm() : "unknown"; // it should be known (createServer)
+
   // Statistics:
   anna::statistics::Engine& statsEngine = anna::statistics::Engine::instantiate();
   // Concepts descriptions:
   std::string serverAsString = anna::functions::socketLiteralAsString(a_key.first, a_key.second);
-  std::string c1desc = "Diameter processing time (for requests) at clients connected to "; c1desc += serverAsString;
-  std::string c2desc = "Diameter message sizes received from clients connected to "; c2desc += serverAsString;
+  std::string c1desc = "Diameter processing time (for requests) at clients connected to "; c1desc += serverAsString; c1desc += " for realm '"; c1desc += realmName; c1desc += "'";
+  std::string c2desc = "Diameter message sizes received from clients connected to "; c2desc += serverAsString; c2desc += " for realm '"; c2desc += realmName; c2desc += "'";
   // Registering
   a_processing_time__StatisticConceptId = statsEngine.addConcept(c1desc.c_str(), "ms", true/* integer values */);
   a_received_message_size__StatisticConceptId = statsEngine.addConcept(c2desc.c_str(), "bytes", true/* integer values */);
 }
 
 void LocalServer::resetStatistics() throw() {
-  a_statisticsAccumulator.reset();
+  a_statisticsAccumulator->reset();
 }
 
 void LocalServer::updateProcessingTimeStatisticConcept(const double &value) throw() {
-  a_statisticsAccumulator.process(a_processing_time__StatisticConceptId, value);
-  LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator.asString(), ANNA_FILE_LOCATION));
+  a_statisticsAccumulator->process(a_processing_time__StatisticConceptId, value);
+  LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator->asString(), ANNA_FILE_LOCATION));
 }
 
 void LocalServer::updateReceivedMessageSizeStatisticConcept(const double &value) throw() {
-  a_statisticsAccumulator.process(a_received_message_size__StatisticConceptId, value);
-  //LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator.asString(), ANNA_FILE_LOCATION));
+  a_statisticsAccumulator->process(a_received_message_size__StatisticConceptId, value);
+  //LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator->asString(), ANNA_FILE_LOCATION));
 }
 
 
@@ -565,7 +568,7 @@ std::string LocalServer::asString() const throw() {
   result += " | Last Outgoing Activity Time: ";
   result += a_lastOutgoingActivityTime.asString();
 //   result += "\n";
-//   result += a_statisticsAccumulator.asString();
+//   result += a_statisticsAccumulator->asString();
   // ServerSessions only in xml
   return result += " }";
 }
@@ -590,7 +593,7 @@ anna::xml::Node* LocalServer::asXML(anna::xml::Node* parent) const throw() {
   result->createAttribute("LastOutgoingActivityTime", a_lastOutgoingActivityTime.asString());
   // Statistics
   anna::xml::Node* stats = result->createChild("Statistics");
-  a_statisticsAccumulator.asXML(stats);
+  a_statisticsAccumulator->asXML(stats);
   anna::xml::Node* serverSessions = result->createChild("ServerSessions"); // LocalServer.ServerSessions
 
   for(const_serverSession_iterator it = serverSession_begin(); it != serverSession_end(); it++)
@@ -625,4 +628,3 @@ void LocalServer::updateOutgoingActivityTime(void) throw() {
     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
   );
 }
-
index a751d48..758ac2d 100644 (file)
@@ -36,34 +36,37 @@ void Server::initialize() throw() {
   a_maxClientSessions = 1; // mono client connection
   a_lastIncomingActivityTime = (anna::Millisecond)0;
   a_lastOutgoingActivityTime = (anna::Millisecond)0;
-  a_statisticsAccumulator.reset();
+  a_statisticsAccumulator = anna::statistics::Engine::instantiate().createAccumulator();
   a_lastUsedResource = NULL;
 }
 
 void Server::initializeStatisticConcepts() throw() {
+  // Realm name
+  std::string realmName = a_engine ? a_engine->getRealm() : "unknown"; // it should be known (createServer)
+
   // Statistics:
   anna::statistics::Engine& statsEngine = anna::statistics::Engine::instantiate();
   // Concepts descriptions:
   std::string serverAsString = anna::functions::socketLiteralAsString(a_socket.first, a_socket.second);
-  std::string c1desc = "Diameter processing time (for requests) at servers on "; c1desc += serverAsString;
-  std::string c2desc = "Diameter message sizes received from servers on "; c2desc += serverAsString;
+  std::string c1desc = "Diameter processing time (for requests) at servers on "; c1desc += serverAsString; c1desc += " for realm '"; c1desc += realmName; c1desc += "'";
+  std::string c2desc = "Diameter message sizes received from servers on "; c2desc += serverAsString; c2desc += " for realm '"; c2desc += realmName; c2desc += "'";
   // Registering
   a_processing_time__StatisticConceptId = statsEngine.addConcept(c1desc.c_str(), "ms", true/* integer values */);
   a_received_message_size__StatisticConceptId = statsEngine.addConcept(c2desc.c_str(), "bytes", true/* integer values */);
 }
 
 void Server::resetStatistics() throw() {
-  a_statisticsAccumulator.reset();
+  a_statisticsAccumulator->reset();
 }
 
 void Server::updateProcessingTimeStatisticConcept(const double &value) throw() {
-  a_statisticsAccumulator.process(a_processing_time__StatisticConceptId, value);
-  LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator.asString(), ANNA_FILE_LOCATION));
+  a_statisticsAccumulator->process(a_processing_time__StatisticConceptId, value);
+  LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator->asString(), ANNA_FILE_LOCATION));
 }
 
 void Server::updateReceivedMessageSizeStatisticConcept(const double &value) throw() {
-  a_statisticsAccumulator.process(a_received_message_size__StatisticConceptId, value);
-  //LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator.asString(), ANNA_FILE_LOCATION));
+  a_statisticsAccumulator->process(a_received_message_size__StatisticConceptId, value);
+  //LOGDEBUG(anna::Logger::debug(a_statisticsAccumulator->asString(), ANNA_FILE_LOCATION));
 }
 
 
@@ -280,7 +283,7 @@ std::string Server::asString() const throw() {
   result += " | Hidden: ";
   result += (hidden() ? "yes" : "no");
   result += "\n";
-  result += a_statisticsAccumulator.asString();
+  result += a_statisticsAccumulator->asString();
 
   for(std::vector<ClientSession*>::const_iterator it = begin(); it != end(); it++) {
     result += "\n";
@@ -304,7 +307,7 @@ anna::xml::Node* Server::asXML(anna::xml::Node* parent) const throw() {
   result->createAttribute("Hidden", hidden() ? "yes" : "no");
   // Statistics
   anna::xml::Node* stats = result->createChild("Statistics");
-  a_statisticsAccumulator.asXML(stats);
+  a_statisticsAccumulator->asXML(stats);
   anna::xml::Node* clientSessions = result->createChild("Server.ClientSessions");
 
   for(std::vector<ClientSession*>::const_iterator it = begin(); it != end(); it++)
@@ -438,4 +441,3 @@ void Server::updateOutgoingActivityTime(void) throw() {
   );
   a_parent->updateOutgoingActivityTime();
 }
-
index 06bec4b..11fe035 100644 (file)
@@ -496,4 +496,3 @@ void Session::updateOutgoingActivityTime(void) throw() {
     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
   );
 }
-
index 3753ed7..1644700 100644 (file)
@@ -145,7 +145,7 @@ void Accumulator::process(const int & conceptId, const double & value) throw(ann
   _concept_data_t *ptr_auxConceptData = getConcept(conceptId);
   anna::Millisecond current = anna::Millisecond::getTime();
   // Optional sample file dump:
-  Engine::instantiate().logSample(conceptId, current, value);
+  Engine::instantiate().logSample(conceptId, current, value); // Accumulator is friend of Engine
 
   // Statistics calculations
   if(ptr_auxConceptData->Size == ULLONG_MAX)  // Statistics is better during processing until reset
index b6e1ee1..b90b609 100644 (file)
@@ -9,7 +9,7 @@
 // Local
 #include <anna/statistics/Engine.hpp>
 #include <anna/statistics/internal/sccs.hpp>
-
+#include <anna/core/mt/Guard.hpp>
 #include <anna/core/functions.hpp>
 #include <anna/xml/xml.hpp>
 
@@ -24,6 +24,10 @@ using namespace anna::statistics;
 //******************************************************************************
 //----------------------------------------------------------------------- Engine
 //******************************************************************************
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------- Engine::Engine()
+//------------------------------------------------------------------------------
 Engine::Engine() {
   statistics::sccs::activate();
   a_enabled = false;
@@ -31,6 +35,15 @@ Engine::Engine() {
 }
 
 
+//------------------------------------------------------------------------------
+//------------------------------------------------------------ Engine::~Engine()
+//------------------------------------------------------------------------------
+Engine::~Engine() {
+  for (_accumulator_vector_it it = a_accumulators.begin(); it != a_accumulators.end(); it++)
+    delete (*it);
+}
+
+
 //------------------------------------------------------------------------------
 //--------------------------------------------------------- Engine::addConcept()
 //------------------------------------------------------------------------------
@@ -119,6 +132,8 @@ bool Engine::disableSampleLog(const int & id) throw() {
 //--------------------------------------------------- Engine::disableSampleLog()
 //------------------------------------------------------------------------------
 bool Engine::logSample(const int & conceptId, const anna::Millisecond & unixTimestamp, const double & value) const throw() {
+  anna::Guard guard(a_mutex);
+
   _concept_identification_map_iter it = a_concept_identification_map.find(conceptId);
 
   if(it == a_concept_identification_map.end()) return false;
@@ -139,6 +154,19 @@ bool Engine::logSample(const int & conceptId, const anna::Millisecond & unixTime
   return true;
 }
 
+
+//------------------------------------------------------------------------------
+//----------------------------------------------------------- Engine::asString()
+//------------------------------------------------------------------------------
+Accumulator *Engine::createAccumulator() throw() {
+  Accumulator *result;
+
+  result = new Accumulator();
+  a_accumulators.push_back(result);
+  return result;
+}
+
+
 //------------------------------------------------------------------------------
 //----------------------------------------------------------- Engine::asString()
 //------------------------------------------------------------------------------
@@ -201,6 +229,11 @@ anna::xml::Node* Engine::asXML(anna::xml::Node* parent, const int & numberOfDeci
     concept->createAttribute("IntegerNatureSample", (*iter).second.IntegerNatureSample ? "yes" : "no");
   }
 
+  // Accumulators:
+  for (_accumulator_vector_it it = a_accumulators.begin(); it != a_accumulators.end(); it++) {
+    anna::xml::Node* accumulators = result->createChild("anna.statistics.Accumulators");
+    (*it)->asXML(accumulators);
+  }
+
   return result;
 }
-