]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
[EDF29150] : monitoring of CPU and memory is integrated into log info of containers.
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 2 Jan 2024 14:11:09 +0000 (15:11 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 2 Jan 2024 14:11:09 +0000 (15:11 +0100)
idl/SALOME_Component.idl
idl/SALOME_ContainerManager.idl
src/Container/Container_i.cxx
src/Container/SALOME_Container.py
src/Container/SALOME_ContainerHelper.py
src/Container/SALOME_ContainerManager.cxx
src/Container/SALOME_ContainerManager.hxx
src/Container/SALOME_Container_i.hxx
src/Container/SALOME_PyNode.py

index bcce8b7790c3a395d4f454f9c71ec3b0e76a4761..5de8850057272948b0c92869d0635532b9a29c62 100644 (file)
@@ -182,6 +182,9 @@ module Engines
     
     //!  name of the %container log file
     attribute string locallogfilename ;
+
+    //! interval of time between two measures of CPU/time process container
+    attribute long monitoringtimeresms;
     
     void verbosity(out boolean activated, out string level);
 
index 474d51642a6adde5eededc1542a2ea0ce5b85c96..3a58f620b554c800e74475f065d4eba98e567dd6 100644 (file)
@@ -96,6 +96,10 @@ interface ContainerManager
   long GetDeltaTimeBetweenNSLookupAtLaunchTimeInMilliSecond();
 
   void SetDeltaTimeBetweenNSLookupAtLaunchTimeInMilliSecond(in long timeInMS);
+  
+  long GetDeltaTimeBetweenCPUMemMeasureInMilliSecond();
+
+  void SetDeltaTimeBetweenCPUMemMeasureInMilliSecond(in long timeInMS);
 
   void SetOverrideEnvForContainers(in KeyValDict env);
 
index 9b71def0b5a04e887abd88dab413e06dbc4a5434..b7e084ac76b8987c74eea2a9ee62b0405597a8db 100644 (file)
@@ -110,6 +110,8 @@ extern "C" {void SigIntHandler( int ) ; }
 #define SLASH '/'
 #endif
 
+const int Abstract_Engines_Container_i::DFT_TIME_INTERVAL_BTW_MEASURE = 500;
+
 std::map<std::string, int> Abstract_Engines_Container_i::_cntInstances_map;
 std::map<std::string, void *> Abstract_Engines_Container_i::_library_map;
 std::map<std::string, void *> Abstract_Engines_Container_i::_toRemove_map;
@@ -211,11 +213,9 @@ Abstract_Engines_Container_i::Abstract_Engines_Container_i (CORBA::ORB_ptr orb,
     // pycont = SALOME_Container.SALOME_Container_i(containerIORStr)
 
     CORBA::String_var sior =  _orb->object_to_string(pCont);
-    std::string myCommand="pyCont = SALOME_Container.SALOME_Container_i('";
-    myCommand += _containerName + "','";
-    myCommand += sior;
-    myCommand += "')\n";
-    SCRUTE(myCommand);
+    std::ostringstream myCommand;
+    myCommand << "pyCont = SALOME_Container.SALOME_Container_i('" << _containerName << "','" << sior << "','" <<  DFT_TIME_INTERVAL_BTW_MEASURE << "')\n";
+    SCRUTE(myCommand.str());
 
     //[RNV]: Comment the PyEval_AcquireLock() and PyEval_ReleaseLock() because this 
     //approach leads to the deadlock of the main thread of the application on Windows platform
@@ -241,7 +241,7 @@ Abstract_Engines_Container_i::Abstract_Engines_Container_i (CORBA::ORB_ptr orb,
       PyRun_SimpleString("sys.path = sys.path[1:]\n");
 #endif
       PyRun_SimpleString("import SALOME_Container\n");
-      PyRun_SimpleString((char*)myCommand.c_str());
+      PyRun_SimpleString((char*)myCommand.str().c_str());
       PyObject *mainmod = PyImport_AddModule("__main__");
       PyObject *globals = PyModule_GetDict(mainmod);
       _pyCont = PyDict_GetItemString(globals, "pyCont");
@@ -326,6 +326,34 @@ void Abstract_Engines_Container_i::locallogfilename(const char *name)
   _localfilename = name;
 }
 
+CORBA::Long Abstract_Engines_Container_i::monitoringtimeresms()
+{
+  AutoGIL gstate;
+  PyObject *result = PyObject_CallMethod(_pyCont,(char*)"monitoringtimeresms",nullptr);
+  if (PyErr_Occurred())
+  {
+    std::string error("can not retrieve time interval between 2 measures");
+    PyErr_Print();
+    THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
+  }
+  CORBA::Long ret = PyLong_AsLong( result );
+  Py_XDECREF(result);
+  return ret;
+}
+
+void Abstract_Engines_Container_i::monitoringtimeresms(CORBA::Long intervalInMs)
+{
+  AutoGIL gstate;
+  PyObject *result = PyObject_CallMethod(_pyCont,(char*)"SetMonitoringtimeresms","i",intervalInMs,nullptr);
+  if (PyErr_Occurred())
+  {
+    std::string error("can not set time interval between 2 measures");
+    PyErr_Print();
+    THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
+  }
+  Py_XDECREF(result);
+}
+
 void Abstract_Engines_Container_i::verbosity(bool& activated, CORBA::String_out level)
 {
   activated = SALOME::VerbosityActivated();
index e9ad62f99132fb7ae9a3740e778b9c3c4461aa61..61ed8bff42e62bcb1553c8f189e1d63f5492f630 100644 (file)
@@ -60,7 +60,7 @@ class SALOME_Container_i:
 
     #-------------------------------------------------------------------------
 
-    def __init__(self ,containerName, containerIORStr):
+    def __init__(self ,containerName, containerIORStr, dftTimeIntervalInMs):
         MESSAGE( "SALOME_Container_i::__init__" )
         try:
           argv = sys.argv
@@ -73,6 +73,7 @@ class SALOME_Container_i:
         self._poa = self._orb.resolve_initial_references("RootPOA")
         self._containerName = containerName
         self._dbg_info = []
+        self._timeIntervalInMs = dftTimeIntervalInMs
         if verbose(): print("SALOME_Container.SALOME_Container_i : _containerName ",self._containerName)
         self._container = self._orb.string_to_object(containerIORStr)
 
@@ -180,3 +181,9 @@ class SALOME_Container_i:
     def getAllInfo(self):
         import pickle
         return pickle.dumps( self._dbg_info )
+    
+    def monitoringtimeresms(self):
+        return self._timeIntervalInMs
+    
+    def SetMonitoringtimeresms(self , value):
+        self._timeIntervalInMs = value
index 439be02155b99a674af246099d13ba756cbf37bd..0d38486d0f485684f3c8438e71df851f7b87623f 100644 (file)
@@ -48,6 +48,7 @@ class ScriptExecInfo:
       return "{} {}".format(m,UNITS[3])
 
     def __init__(self):
+      self._cpu_mem_during_exec = None
       self._start_exec_time = None
       self._end_exec_time = None
       self._start_input_time = None
@@ -58,6 +59,20 @@ class ScriptExecInfo:
       self._input_hdd_mem = None
       self._output_mem = 0
       self._output_hdd_mem = None
+      
+    @property
+    def CPUMemDuringExec(self):
+      return self._cpu_mem_during_exec
+    
+    @CPUMemDuringExec.setter
+    def CPUMemDuringExec(self,value):
+      self._cpu_mem_during_exec = value
+
+    @property
+    def CPUMemDuringExecStr(self):
+      cpu = self._cpu_mem_during_exec[::2]
+      mem_rss = self._cpu_mem_during_exec[1::2]
+      return [(a,ScriptExecInfo.MemRepr(b)) for a,b in self._cpu_mem_during_exec]
 
     @property
     def inputMem(self):
@@ -175,6 +190,7 @@ class ScriptExecInfo:
       return """start exec time = {self.startExecTime}
 end exec time = {self.endExecTime}
 exec_time = {self.execTimeStr}
+CPU and mem monitoring = {self.CPUMemDuringExecStr}
 input unpickling and ev load from disk time = {self.inputTimeStr}
 output serialization and ev write to disk time = {self.outputTimeStr}
 input memory size before exec (MemoryPeak 2x) = {self.inputMemStr}
index 730f35cd62e915785c3156d0146b5d8052fb218e..0ec60bba3bd6110b37346b7b4948074bcc10dff2 100644 (file)
@@ -24,6 +24,7 @@
 #include "SALOME_ResourcesManager.hxx"
 #include "SALOME_LoadRateManager.hxx"
 #include "SALOME_NamingService.hxx"
+#include "SALOME_Container_i.hxx"
 #include "SALOME_ResourcesManager_Client.hxx"
 #include "SALOME_Embedded_NamingService.hxx"
 #include "SALOME_ModuleCatalog.hh"
@@ -88,7 +89,7 @@ Utils_Mutex SALOME_ContainerManager::_systemMutex;
 //=============================================================================
 
 SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb, PortableServer::POA_var poa, SALOME_NamingService_Abstract *ns)
-  : _nbprocUsed(1),_delta_time_ns_lookup_in_ms(DFT_DELTA_TIME_NS_LOOKUP_IN_MS)
+  : _nbprocUsed(1),_delta_time_ns_lookup_in_ms(DFT_DELTA_TIME_NS_LOOKUP_IN_MS),_delta_time_measure_in_ms(Abstract_Engines_Container_i::DFT_TIME_INTERVAL_BTW_MEASURE)
 {
   MESSAGE("constructor");
   _NS = ns;
@@ -227,6 +228,16 @@ void SALOME_ContainerManager::SetDeltaTimeBetweenNSLookupAtLaunchTimeInMilliSeco
   this->_delta_time_ns_lookup_in_ms = timeInMS;
 }
 
+CORBA::Long SALOME_ContainerManager::GetDeltaTimeBetweenCPUMemMeasureInMilliSecond()
+{
+  return this->_delta_time_measure_in_ms;
+}
+
+void SALOME_ContainerManager::SetDeltaTimeBetweenCPUMemMeasureInMilliSecond(CORBA::Long timeInMS)
+{
+  this->_delta_time_measure_in_ms = timeInMS;
+}
+
 //=============================================================================
 //! Loop on all the containers listed in naming service, ask shutdown on each
 /*! CORBA Method:
@@ -489,6 +500,8 @@ Engines::Container_ptr SALOME_ContainerManager::GiveContainer(const Engines::Con
       if (!CORBA::is_nil(cont))
       {
         INFOS("[GiveContainer] container " << containerNameInNS << " launched");
+        cont->monitoringtimeresms( this->_delta_time_measure_in_ms );
+        INFOS("[GiveContainer] container " << containerNameInNS << " first CORBA invocation OK");
         std::ostringstream envInfo;
         std::for_each( _override_env.begin(), _override_env.end(), [&envInfo](const std::pair<std::string,std::string>& p) { envInfo << p.first << " = " << p.second << std::endl; } );
         INFOS("[GiveContainer] container " << containerNameInNS << " override " << envInfo.str());
index b579d5c3dd1dccc53f3153930b3a3684b05135f4..1d517c237418c4b71e7d4816450274e9ae81094b 100644 (file)
@@ -71,6 +71,10 @@ public:
 
   void SetDeltaTimeBetweenNSLookupAtLaunchTimeInMilliSecond(CORBA::Long timeInMS) override;
 
+  CORBA::Long GetDeltaTimeBetweenCPUMemMeasureInMilliSecond() override;
+
+  void SetDeltaTimeBetweenCPUMemMeasureInMilliSecond(CORBA::Long timeInMS) override;
+
   static const char *_ContainerManagerNameInNS;
 
 protected:
@@ -214,6 +218,7 @@ private:
   std::vector< std::pair<std::string, std::string> > _override_env;
   int _time_out_in_second;
   int _delta_time_ns_lookup_in_ms;
+  int _delta_time_measure_in_ms;
   std::string _code_to_exe_on_startup;
 };
 #endif
index 882581e69f7bde367a04859fd47f99760bbd41e4..7f974bd5dfbe198bf4e93fb7d2f14da37f4d18cd 100644 (file)
@@ -119,6 +119,8 @@ public:
   void logfilename(const char *name) override;
   char *locallogfilename() override;
   void locallogfilename(const char *name) override;
+  CORBA::Long monitoringtimeresms() override;
+  void monitoringtimeresms(CORBA::Long intervalInMs) override;
   void verbosity(bool& activated, CORBA::String_out level) override;
   void setVerbosity(bool activated, const char *level) override;
   SALOME::vectorOfByte *getAllInfo() override;
@@ -167,7 +169,8 @@ public:
   void unregisterTemporaryFile(const std::string &fileName);
   void clearTemporaryFiles();
   PortableServer::ObjectId *getCORBAId() const { return _id; }
-
+public:
+  static const int DFT_TIME_INTERVAL_BTW_MEASURE;
 protected:
   static std::map<std::string, int> _cntInstances_map;
   static std::map<std::string, void *> _library_map;  // library names, loaded
index d93751eaf4dadbff7d51a5e1674d5dda2e06ae9c..0baa785c066f814eff558bdaba29feeb3c571684 100644 (file)
@@ -31,6 +31,7 @@ import SALOME__POA
 import SALOME
 import logging
 import os
+import sys
 
 MY_CONTAINER_ENTRY_IN_GLBS = "my_container"
 
@@ -452,10 +453,9 @@ def StopMonitoring( ):
     list<float,str> : list of pairs. First param of pair is CPU usage. Second param of pair is rss memory usage
   """
   import KernelBasis
-  from SALOME_ContainerHelper import ScriptExecInfo
   ret = KernelBasis.StopMonitoring()
   cpu = ret[::2]
-  mem_rss = [ScriptExecInfo.MemRepr( int(elt) ) for elt in ret[1::2]]
+  mem_rss = [ int(elt) for elt in ret[1::2]]
   return [(a,b) for a,b in zip(cpu,mem_rss)]
 
 class SeqByteReceiver:
@@ -502,6 +502,7 @@ class PyScriptNode_i (Engines__POA.PyScriptNode,Generic):
     self.context[MY_CONTAINER_ENTRY_IN_GLBS] = self.my_container
     self._pos = None
     self._current_exec = 0
+    sys.stdout.flush() ; sys.stderr.flush() # flush to correctly capture log per execution session
 
   #start of non remote callable methods
     
@@ -584,6 +585,7 @@ class PyScriptNode_i (Engines__POA.PyScriptNode,Generic):
   def executeFirst(self,argsin):
     """ Same than first part of self.execute to reduce memory peak."""
     try:
+      #self.my_container_py.addInfoOnLevel2(self.getIDInContainer(),self._current_exec,"tracePosStart",)
       data = None
       self.my_container_py.addTimeInfoOnLevel2(self.getIDInContainer(),self._current_exec,"startInputTime")
       if True: # to force call of SeqByteReceiver's destructor
@@ -609,9 +611,13 @@ class PyScriptNode_i (Engines__POA.PyScriptNode,Generic):
     import sys
     try:
       self.my_container_py.addTimeInfoOnLevel2(self.getIDInContainer(),self._current_exec,"startExecTime")
-      pyfile = BuildPythonFileForCPUPercent()
-
+      ##
+      monitoringParams = LaunchMonitoring( self.my_container_py.monitoringtimeresms() )
       exec(self.ccode, self.context)
+      cpumeminfo = StopMonitoring( )
+      ##
+      self.my_container_py.addInfoOnLevel2(self.getIDInContainer(),self._current_exec,"CPUMemDuringExec",cpumeminfo)
+      del monitoringParams
       self.my_container_py.addTimeInfoOnLevel2(self.getIDInContainer(),self._current_exec,"endExecTime")
       self.my_container_py.addTimeInfoOnLevel2(self.getIDInContainer(),self._current_exec,"startOutputTime")
       argsout=[]