]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
[EDF29150] : head monitoring file management
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 9 Jan 2024 13:09:44 +0000 (14:09 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 9 Jan 2024 14:33:07 +0000 (15:33 +0100)
idl/SALOME_LogManager.idl
src/Basics/KernelBasis.i
src/Basics/Monitoring.cxx
src/Basics/Monitoring.hxx
src/Container/SALOME_PyNode.py
src/KERNEL_PY/__init__.py
src/Launcher/SALOME_LogManager.cxx
src/Launcher/SALOME_LogManager.hxx
src/Launcher/SALOME_LogManager.py
src/Launcher/Test/testPerfLogManager1.py

index 3e56d300f727dc7e2219828eb3313a5d5ff21e21..3a7a67e3916b2d84d93f96e940ca365a43697688 100644 (file)
@@ -58,6 +58,13 @@ module Engines
     ContainerPerfLog declareContainer(in string contInNS, in string logfile);
     ListOfContainerPerfLog listOfContainerLogs();
     SALOME::vectorOfByte getAllStruct( in boolean clearMemory );
+    void putStructInFileAtomic(in boolean clearMemory, in string fileName);
+    /* Part of methods dedicated of management of performance log file in the most safety manner */
+    void setFileNamePairOfLogger(in string loggerFileNameA, in string loggerFileNameB);
+    void getFileNamePairOfLogger(out string loggerFileNameA, out string loggerFileNameB);
+    void versionA_IsTheLatestValidVersion();
+    void versionB_IsTheLatestValidVersion();
+    string getLastVersionOfFileNameLogger();
   };
 };
 
index 3d070b68c757d653990561a1705a45fbdf44e30f..06c4fdd0868a35db45eb63b715ad3c043c19f98e 100644 (file)
@@ -62,9 +62,9 @@ void setIOROfEmbeddedNS(const std::string& ior);
 
 double GetTimeAdjustmentCst();
 
-void LaunchMonitoring(const std::string& pyScriptToEvaluate, const std::string& outFileName);
+long LaunchMonitoring(const std::string& pyScriptToEvaluate);
 
-std::vector<double> StopMonitoring();
+void StopMonitoring(long pid);
 
 bool VerbosityActivated();
 
@@ -97,6 +97,17 @@ PyObject *HeatMarcelSwig(double timeAjustment, unsigned int nbThreads = 0)
   return ret;
 }
 
+std::vector<double> ReadFloatsInFileSwig(const std::string& fileName)
+{
+  std::vector<double> ret;
+  try
+  {
+    ret = SALOME::ReadFloatsInFile( fileName );
+  }
+  catch(std::exception& e) { }
+  return ret;
+}
+
 void SetVerbosityLevelSwig(const std::string& level)
 {
   SetVerbosityLevelStr(level);
@@ -107,3 +118,9 @@ std::string VerbosityLevelSwig()
   return VerbosityLevelStr();
 }
 }
+
+%pythoncode %{
+def ReadFloatsInFile( fileName ):
+  ret = ReadFloatsInFileSwig( fileName )
+  return ret
+%}
\ No newline at end of file
index 690490c04046d23a7ea9b3897c48201b408b36d0..85247479c6745946c2c62a3299d6974517f85c18 100644 (file)
 #include <signal.h>
 #endif
 
-static std::string _out_filename;
 #ifndef WIN32
-static pid_t pid_of_subprocess = 0;
-#endif
-
-#ifndef WIN32
-static void LaunchMonitoringLinux(const std::string& pyScriptToEvaluate, const std::string& outFileName)
+static long LaunchMonitoringLinux(const std::string& pyScriptToEvaluate)
 {
+  pid_t pid_of_subprocess = 0;
   constexpr char PYTHON_EXEC[] = "python3";
   pid_t pid = fork();
   if (pid == -1)
@@ -69,14 +65,14 @@ static void LaunchMonitoringLinux(const std::string& pyScriptToEvaluate, const s
   {
     pid_of_subprocess = pid;
   }
+  return pid_of_subprocess;
 }
 #endif
 
-void SALOME::LaunchMonitoring(const std::string& pyScriptToEvaluate, const std::string& outFileName)
+long SALOME::LaunchMonitoring(const std::string& pyScriptToEvaluate)
 {
-  _out_filename = outFileName;
 #ifndef WIN32
-  LaunchMonitoringLinux(pyScriptToEvaluate,outFileName);
+  return LaunchMonitoringLinux(pyScriptToEvaluate);
 #else
   throw std::runtime_error("LaunchMonitoring not implemented for Windows !");
 #endif
@@ -88,7 +84,7 @@ std::vector<double> SALOME::ReadFloatsInFile(const std::string& fileName)
 
   if(!inputFile.is_open())
   {
-    std::ostringstream oss; oss << "Impossible to open file \"" << _out_filename<< "\" !";
+    std::ostringstream oss; oss << "Impossible to open file \"" << fileName << "\" !";
     throw std::runtime_error( oss.str() );
   }
   std::vector<double> ret;
@@ -114,25 +110,17 @@ std::vector<double> SALOME::ReadFloatsInFile(const std::string& fileName)
 }
 
 #ifndef WIN32
-static std::vector<double> StopMonitoringLinux()
+static void StopMonitoringLinux(long pid)
 {
+  pid_t pid_of_subprocess = (pid_t) pid;
   kill( pid_of_subprocess, SIGTERM );
-  std::vector<double> ret;
-  try
-  {
-    ret = SALOME::ReadFloatsInFile( _out_filename );
-  }
-  catch(std::exception& e) { }
-  pid_of_subprocess = 0;
-  _out_filename.clear();
-  return ret;
 }
 #endif
 
-std::vector<double> SALOME::StopMonitoring()
+void SALOME::StopMonitoring(long pid)
 {
 #ifndef WIN32
-  return StopMonitoringLinux();
+  return StopMonitoringLinux( pid );
 #else
   throw std::runtime_error("StopMonitoring not implemented for Windows !");
 #endif
index 379218844e0be8134eece594f98db10374e47618..d8372d185a1cba02f88d88356e8f3c2e62ebffda 100644 (file)
@@ -26,9 +26,9 @@
 
 namespace SALOME
 {
-  void BASICS_EXPORT LaunchMonitoring(const std::string& pyScriptToEvaluate, const std::string& outFileName);
+  long BASICS_EXPORT LaunchMonitoring(const std::string& pyScriptToEvaluate);
 
   std::vector<double> BASICS_EXPORT ReadFloatsInFile(const std::string& fileName);
 
-  std::vector<double> BASICS_EXPORT StopMonitoring();
+  void BASICS_EXPORT StopMonitoring(long pid);
 }
index d6d46668f9172c97c9f2aae9f37951aa50a768b1..ab91c1bfa98ec685b2beea80c3531632651dfe36 100644 (file)
@@ -413,7 +413,25 @@ class FileDeleter:
     if os.path.exists( self._filename ):
       os.unlink( self._filename )
 
-def LaunchMonitoring( intervalInMs ):
+class MonitoringInfo:
+  def __init__(self, pyFileName, outFileName, pid):
+    self._py_file_name = pyFileName
+    self._out_file_name = outFileName
+    self._pid = pid
+
+  @property
+  def pyFileName(self):
+    return self._py_file_name
+
+  @property
+  def pid(self):
+    return self._pid
+  
+  @property
+  def outFileName(self):
+    return self._out_file_name
+
+def LaunchTimeCPUMonitoring( intervalInMs ):
   """
   Launch a subprocess monitoring self process.
   This monitoring subprocess is a python process lauching every intervalInMs ms evaluation of
@@ -442,19 +460,34 @@ with open("{}","a") as f:
 """.format(pid, tempOutFile, intervalInMs))
     return FileDeleter(tempPyFile), FileDeleter(tempOutFile)
   pyFileName, outFileName = BuildPythonFileForCPUPercent( intervalInMs )
-  KernelBasis.LaunchMonitoring(pyFileName.filename,outFileName.filename)
-  return pyFileName, outFileName
+  pid = KernelBasis.LaunchMonitoring(pyFileName.filename)
+  return MonitoringInfo(pyFileName, outFileName, pid)
 
-def StopMonitoring( ):
+def StopMonitoring( monitoringInfo ):
   """
-  Retrieve data of monitoring and kill monitoring subprocess.
+  Kill monitoring subprocess.
+
+  Args:
+  ----
+      monitoringInfo (MonitoringInfo): info returned by LaunchMonitoring
+  """
+  import KernelBasis
+  KernelBasis.StopMonitoring(monitoringInfo.pid)
+
+def ReadCPUMemInfo( monitoringInfo ):
+  """
+  Retrieve data of monitoring.
+
+  Args:
+  ----
+      monitoringInfo (MonitoringInfo): info returned by LaunchMonitoring
   
   Returns
   -------
     list<float,str> : list of pairs. First param of pair is CPU usage. Second param of pair is rss memory usage
   """
   import KernelBasis
-  ret = KernelBasis.StopMonitoring()
+  ret = KernelBasis.ReadFloatsInFile( monitoringInfo.outFileName.filename )
   cpu = ret[::2]
   mem_rss = [ int(elt) for elt in ret[1::2]]
   return [(a,b) for a,b in zip(cpu,mem_rss)]
@@ -612,9 +645,10 @@ class PyScriptNode_i (Engines__POA.PyScriptNode,Generic):
       self.addTimeInfoOnLevel2("startExecTime")
       ##
       self.addInfoOnLevel2("measureTimeResolution",self.my_container_py.monitoringtimeresms())
-      monitoringParams = LaunchMonitoring( self.my_container_py.monitoringtimeresms() )
+      monitoringParams = LaunchTimeCPUMonitoring( self.my_container_py.monitoringtimeresms() )
       exec(self.ccode, self.context)
-      cpumeminfo = StopMonitoring( )
+      StopMonitoring( monitoringParams )
+      cpumeminfo = ReadCPUMemInfo( monitoringParams )
       ##
       self.addInfoOnLevel2("CPUMemDuringExec",cpumeminfo)
       del monitoringParams
index cdc0ead26224741c20d53716b41bb2e2db7b7ad9..f163a808596d75de6179f4db4866385e43e6380f 100644 (file)
@@ -272,6 +272,8 @@ def salome_init_without_session(path=None, embedded=False, iorfakensfile=None):
     type(logm).Fetch = LogManagerFetch
     type(logm).DumpInFile = LogManagerDumpInFile
     type(logm).LoadFromFile = LogManagerLoadFromFile
+    type(logm).LaunchMonitoringDumpFile = LogManagerLaunchMonitoringDumpFile
+    type(logm).GetLatestMonitoringDumpFile = LogManagerGetLatestMonitoringDumpFile
     #
     import KernelLogger
     naming_service.Register(KernelLogger.myLogger(),"/Logger")
@@ -478,5 +480,90 @@ def LogManagerLoadFromFile(self,fileName):
         data = f.read()
     return unserializeLogManager( data )
 
+class LogManagerLaunchMonitoringFileCtxMgr:
+    def __init__(self, intervalInMs, outFileName):
+        self._interval_in_ms = intervalInMs
+        self._out_filename = outFileName
+        self._monitoring_params = None
+    def __enter__(self):
+        import salome
+        self._monitoring_params = salome.logm.LaunchMonitoringDumpFile(self._interval_in_ms, self._out_filename)
+        return self._monitoring_params
+    def __exit__(self,exctype, exc, tb):
+        import SALOME_PyNode
+        import salome
+        SALOME_PyNode.StopMonitoring( self._monitoring_params )
+        salome.logm.GetLatestMonitoringDumpFile()
+        pass
+
+def LogManagerLaunchMonitoringDumpFile(self, intervalInMs, outFileName):
+    """
+    This method loops indefinitely every intervalInMs milliseconds to dump the singleton 
+    content of perf log stored in salome.logm.
+    This method runs in a dedicated subprocess that can be killed at any time.
+    So subprocess code must deal with.
+
+    See also LogManagerGetLatestMonitoringDumpFile
+    """
+    global orb,logm
+    ior = orb.object_to_string( logm )
+    import os
+    outFileName2 = os.path.abspath( os.path.expanduser(outFileName) )
+    import tempfile
+    import logging
+    import SALOME_PyNode
+    import KernelBasis
+    # outFileNameSave stores the content of outFileName during phase of dumping
+    with tempfile.NamedTemporaryFile(prefix=os.path.basename(outFileName2),dir=os.path.dirname(outFileName2)) as f:
+      outFileNameSave = f.name
+    with tempfile.NamedTemporaryFile(prefix="htopmain_",suffix=".py") as f:
+      tempPyFile = f.name
+    with open(tempPyFile,"w") as f:
+        f.write("""import Engines
+import os
+import shutil
+import CORBA
+import time
+orb=CORBA.ORB_init([''], CORBA.ORB_ID)
+logm = orb.string_to_object("{ior}")
+outFileName = "{outFileName}"
+outFileNameSave = "{outFileNameSave}"
+logm.setFileNamePairOfLogger(outFileName, outFileNameSave )
+import salome
+while(True):
+  if os.path.exists( outFileName ):
+    shutil.copy(outFileName,outFileNameSave)
+    logm.versionB_IsTheLatestValidVersion()
+  salome.LogManagerDumpInFile(logm,outFileName)
+  logm.versionA_IsTheLatestValidVersion()
+  time.sleep( {intervalInMs} / 1000.0 )
+""".format( **locals()))
+    logging.debug( "File for monitoring dump file : {}".format(tempPyFile) )
+    pyFileName = SALOME_PyNode.FileDeleter( tempPyFile )
+    pid = KernelBasis.LaunchMonitoring( tempPyFile )
+    return SALOME_PyNode.MonitoringInfo(pyFileName,None,pid)
+
+def LogManagerGetLatestMonitoringDumpFile(self):
+    import shutil
+    import logging
+    a,b = self.getFileNamePairOfLogger()
+    if a=="" or b=="":
+        return ""
+    if a == b:
+        return a
+    lastVersion = self.getLastVersionOfFileNameLogger()
+    if lastVersion == a:
+        logging.debug("LogManagerGetLatestMonitoringDumpFile SITUATION A")
+        if os.path.exists( b ):
+            os.remove( b )
+        return a
+    if lastVersion == b:
+        logging.debug("LogManagerGetLatestMonitoringDumpFile SITUATION B")
+        if os.path.exists( b ):
+            shutil.move( b, a)
+        return a
+    logging.warning("in LogManagerGetLatestMonitoringDumpFile an unexpected situation araises.")
+    return ""
+
 #to expose all objects to pydoc
 __all__=dir()
index b477724768b217c6ba041fb49de2ec05f008a031..54a8b90d56a3d9c2e21b820bccb9a804c534f31b 100644 (file)
@@ -101,7 +101,8 @@ AutoPyRef SALOME_ContainerScriptExecPerfLog::end()
 {
   AutoGIL gstate;
   //https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
-  AutoPyRef result(PyObject_CallMethod(pyObj(),(char*)"end","y#",_data.data(),_data.size(),nullptr) ) ;
+  AutoPyRef dataPy(PyBytes_FromStringAndSize(_data.data(),_data.size()));
+  AutoPyRef result(PyObject_CallMethod(pyObj(),(char*)"end","O",dataPy.get(),nullptr) ) ;
   if (PyErr_Occurred())
   {
     std::string error("can not end");
@@ -238,6 +239,23 @@ char *SALOME_ContainerPerfLog::getContainerEntryInNS()
 
 /////
 
+std::string SALOME_SafeLoggerFileHolder::getLastVersionOfFileNameLogger()
+{
+  switch( _version_activated )
+  {
+  case SafeLoggerActiveVersionType::VersionA_Activated:
+    return _logger_file_a;
+  case SafeLoggerActiveVersionType::VersionB_Activated:
+    return _logger_file_b;
+  case SafeLoggerActiveVersionType::NoVersion_Activated:
+    return std::string();
+  default:
+    throw std::runtime_error("getLastVersionOfFileNameLogger : Situation not managed");
+  }
+}
+
+/////
+
 SALOME_LogManager::SALOME_LogManager(CORBA::ORB_ptr orb, PortableServer::POA_var poa,SALOME_NamingService_Abstract *ns):_poa(poa)
 {
   _NS.reset(ns);
@@ -313,6 +331,34 @@ SALOME::vectorOfByte *SALOME_LogManager::getAllStruct(bool clearMemory)
   return FromVectCharToCorba(data);
 }
 
+void SALOME_LogManager::putStructInFileAtomic(bool clearMemory, const char *fileName)
+{
+  std::vector<char> data = this->dumpCppInternalFrmt(clearMemory);
+  {
+    AutoGIL gstate;
+    AutoPyRef dataPy(PyBytes_FromStringAndSize(data.data(),data.size()));
+    AutoPyRef result = PyObject_CallMethod(_pyLogManager,(char*)"putStructInFileAtomic","Os",dataPy.get(),fileName,nullptr);
+  }
+}
+
+void SALOME_LogManager::setFileNamePairOfLogger(const char *loggerFileNameA, const char *loggerFileNameB)
+{
+  _safe_logger_file_holder.setFileNamePairOfLogger(loggerFileNameA,loggerFileNameB);
+}
+
+void SALOME_LogManager::getFileNamePairOfLogger(CORBA::String_out loggerFileNameA, CORBA::String_out loggerFileNameB)
+{
+  std::string loggerFileNameAS,loggerFileNameBS;
+  _safe_logger_file_holder.getFileNamePairOfLogger(loggerFileNameAS,loggerFileNameBS);
+  loggerFileNameA = CORBA::string_dup(loggerFileNameAS.c_str());
+  loggerFileNameB = CORBA::string_dup(loggerFileNameBS.c_str());
+}
+
+char *SALOME_LogManager::getLastVersionOfFileNameLogger()
+{
+  return CORBA::string_dup( _safe_logger_file_holder.getLastVersionOfFileNameLogger().c_str() );
+}
+
 ///////////////////////
  
  #include <cstdint>
index 755e25268a85c6c10c3222fe21692efc82cbf921..7fa108fc8213c35f9f0560ca7ef1b6e51e487598 100644 (file)
@@ -129,6 +129,23 @@ private:
   std::vector< Engines::ContainerScriptPerfLog_var > _scripts;
 };
 
+enum class SafeLoggerActiveVersionType
+{ VersionA_Activated, VersionB_Activated, NoVersion_Activated };
+
+class SALOME_SafeLoggerFileHolder
+{
+public:
+  void setFileNamePairOfLogger(const std::string& loggerFileNameA, const std::string& loggerFileNameB) { _logger_file_a = loggerFileNameA; _logger_file_b = loggerFileNameB; }
+  void getFileNamePairOfLogger(std::string& loggerFileNameA, std::string& loggerFileNameB) { loggerFileNameA = _logger_file_a; loggerFileNameB = _logger_file_b; }
+  void versionA_IsTheLatestValidVersion() { _version_activated = SafeLoggerActiveVersionType::VersionA_Activated; }
+  void versionB_IsTheLatestValidVersion() { _version_activated = SafeLoggerActiveVersionType::VersionB_Activated; }
+  std::string getLastVersionOfFileNameLogger();
+private:
+  std::string _logger_file_a;
+  std::string _logger_file_b;
+  SafeLoggerActiveVersionType _version_activated = SafeLoggerActiveVersionType::NoVersion_Activated;
+};
+
 class SALOMELAUNCHER_EXPORT SALOME_LogManager : public POA_Engines::LogManager
 {
  public:
@@ -139,6 +156,14 @@ class SALOMELAUNCHER_EXPORT SALOME_LogManager : public POA_Engines::LogManager
   Engines::ContainerPerfLog_ptr declareContainer(const char *contInNS, const char *logfile) override;
   Engines::ListOfContainerPerfLog *listOfContainerLogs() override;
   SALOME::vectorOfByte *getAllStruct(bool clearMemory) override;
+  void putStructInFileAtomic(bool clearMemory, const char *fileName) override;
+ public:
+  void setFileNamePairOfLogger(const char *loggerFileNameA, const char *loggerFileNameB) override;
+  void getFileNamePairOfLogger(CORBA::String_out loggerFileNameA, CORBA::String_out loggerFileNameB) override;
+  void versionA_IsTheLatestValidVersion() override { _safe_logger_file_holder.versionA_IsTheLatestValidVersion(); }
+  void versionB_IsTheLatestValidVersion() override { _safe_logger_file_holder.versionB_IsTheLatestValidVersion(); }
+  char *getLastVersionOfFileNameLogger() override;
+ public:
   std::size_t getNumberOfContainers() const { return _containers.size(); }
  public:
   void accept(SALOME_VisitorContainerLog &visitor);
@@ -149,6 +174,7 @@ class SALOMELAUNCHER_EXPORT SALOME_LogManager : public POA_Engines::LogManager
   std::unique_ptr<SALOME_NamingService_Abstract> _NS;
   PortableServer::POA_var _poa;
   std::vector<Engines::ContainerPerfLog_var> _containers;
+  SALOME_SafeLoggerFileHolder _safe_logger_file_holder;
  public:
   static const char NAME_IN_NS[];
 };
index 6e30a380da9749757ab27a8dcff56d9ca9adf95d..2af278a4be2ea446251ed9bd4ca656236342349b 100644 (file)
@@ -77,3 +77,7 @@ class SALOME_LogManagerHelper:
   def declareContainer(self, contInNS,logfile):
     inst = SALOME_ContainerPerfLog(contInNS,logfile)
     return inst
+  
+  def putStructInFileAtomic(self,s,fileName):
+    with open(fileName,"wb") as f:
+      f.write( s )
index 2268284fe675297b06198d73513f1264ab8737fa..739376a8eef52624812a0dc3b9c56fefc16e2941 100644 (file)
@@ -25,6 +25,7 @@ import Engines
 import pylauncher
 import SALOME_PyNode
 
+import glob
 import pickle
 import tempfile
 import logging
@@ -65,15 +66,22 @@ class testPerfLogManager1(unittest.TestCase):
         cp = pylauncher.GetRequestForGiveContainer(hostname,"container_test")
         #PROXY_THRES = "-1"
         PROXY_THRES = "1"
-        with tempfile.TemporaryDirectory() as tmpdirname:
-            val_for_big_obj = str( tmpdirname )
-            os.environ["SALOME_FILE_BIG_OBJ_DIR"] = val_for_big_obj
-            # Override environement for all containers launched
-            salome.cm.SetOverrideEnvForContainersSimple(env = [("SALOME_FILE_BIG_OBJ_DIR",val_for_big_obj),("SALOME_BIG_OBJ_ON_DISK_THRES",PROXY_THRES)])
-            salome.cm.SetDeltaTimeBetweenCPUMemMeasureInMilliSecond( 250 )
-            cont = salome.cm.GiveContainer(cp)
-            logging.debug("{} {}".format(40*"*",cont.getPID()))
-            script_st = """
+        with tempfile.TemporaryDirectory() as tmpdirnameMonitoring:
+            monitoringFile = os.path.join( str( tmpdirnameMonitoring ), "zeHtop.pckl" )
+            monitoringFileTwo = os.path.join( str( tmpdirnameMonitoring ), "zeHtopTwo.pckl" )
+            logging.debug("Monitoring file : {}".format(monitoringFile))
+            with tempfile.TemporaryDirectory() as tmpdirname:
+                with salome.LogManagerLaunchMonitoringFileCtxMgr(250,monitoringFile) as monitoringParams:
+                    pyFileContainingCodeOfMonitoring = monitoringParams.pyFileName.filename
+                    logging.debug("Python file containing code of monitoring : {}".format(pyFileContainingCodeOfMonitoring))
+                    val_for_big_obj = str( tmpdirname )
+                    os.environ["SALOME_FILE_BIG_OBJ_DIR"] = val_for_big_obj
+                    # Override environement for all containers launched
+                    salome.cm.SetOverrideEnvForContainersSimple(env = [("SALOME_FILE_BIG_OBJ_DIR",val_for_big_obj),("SALOME_BIG_OBJ_ON_DISK_THRES",PROXY_THRES)])
+                    salome.cm.SetDeltaTimeBetweenCPUMemMeasureInMilliSecond( 250 )
+                    cont = salome.cm.GiveContainer(cp)
+                    logging.debug("{} {}".format(40*"*",cont.getPID()))
+                    script_st = """
 import logging
 import sys
 import KernelBasis
@@ -90,74 +98,85 @@ pihm, ts = KernelBasis.HeatMarcel(1 * nbcore * cst,nbcore)
 print("Time ellapse spent : {} s".format(ts))
 sys.stderr.write("fake error message\\n")
 """
-            poa = salome.orb.resolve_initial_references("RootPOA")
-            zeinput0 = [ bytes(100000000) ]
-            if SALOME_PyNode.GetBigObjectOnDiskThreshold() != -1:
-                zeinput0 = SALOME_PyNode.ProxyfyPickeled( zeinput0 )
-                zeinput0.unlinkOnDestructor()
-            obj = SALOME_PyNode.SenderByte_i(poa,pickle.dumps( (["zeinput0"],{"zeinput0": [zeinput0], "zeinput1": [ [zeinput0], [zeinput0] ] }) ))
-            id_o = poa.activate_object(obj)
-            refPtr = poa.id_to_reference(id_o)
-            pyscript2 = cont.createPyScriptNode("testScript2",script_st)
-            pyscript2.executeFirst(refPtr)
-            ret2 = pyscript2.executeSecond(["ob","ob2"])# generate a DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats on debian11 ?
-            ret3, fileNamesProxyOut = unProxyfy( ret2 )
-            logging.getLogger().debug("test logging 1")
-            logging.debug("test logging 2")
-            logging.debug( salome.orb.object_to_string( salome.logm ) )
-            a = salome.logm.NaiveFetch()
-            logging.debug(a)
-            logging.debug(a[0][1][0])
-            logging.debug( a[0][1][0].get()._input_hdd_mem._data[0]._data[0]._hdd_mem ) # important
-            logging.debug( a[0][1][0].get()._input_hdd_mem._data[1]._data[0]._data[0]._hdd_mem ) # important
-            fileNameProxyIn = a[0][1][0].get()._input_hdd_mem._data[0]._data[0]._file_name
-            logging.debug( fileNameProxyIn )
-            del zeinput0
-            del ret3
-            import gc ; gc.collect()
-            if fileNameProxyIn is not None:
-                if os.path.exists(fileNameProxyIn):
-                    raise RuntimeError("Oooops 2")
-            for fileNameProxyOut in fileNamesProxyOut:
-                if fileNameProxyOut is not None:
-                    if os.path.exists(fileNameProxyOut):
-                        raise RuntimeError("Oooops 3")
-
-            # execution #2 inside last
-            script_st2 = """
+                    poa = salome.orb.resolve_initial_references("RootPOA")
+                    zeinput0 = [ bytes(100000000) ]
+                    if SALOME_PyNode.GetBigObjectOnDiskThreshold() != -1:
+                        zeinput0 = SALOME_PyNode.ProxyfyPickeled( zeinput0 )
+                        zeinput0.unlinkOnDestructor()
+                    obj = SALOME_PyNode.SenderByte_i(poa,pickle.dumps( (["zeinput0"],{"zeinput0": [zeinput0], "zeinput1": [ [zeinput0], [zeinput0] ] }) ))
+                    id_o = poa.activate_object(obj)
+                    refPtr = poa.id_to_reference(id_o)
+                    pyscript2 = cont.createPyScriptNode("testScript2",script_st)
+                    pyscript2.executeFirst(refPtr)
+                    ret2 = pyscript2.executeSecond(["ob","ob2"])# generate a DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats on debian11 ?
+                    ret3, fileNamesProxyOut = unProxyfy( ret2 )
+                    logging.getLogger().debug("test logging 1")
+                    logging.debug("test logging 2")
+                    logging.debug( salome.orb.object_to_string( salome.logm ) )
+                    a = salome.logm.NaiveFetch()
+                    logging.debug(a)
+                    logging.debug(a[0][1][0])
+                    logging.debug( a[0][1][0].get()._input_hdd_mem._data[0]._data[0]._hdd_mem ) # important
+                    logging.debug( a[0][1][0].get()._input_hdd_mem._data[1]._data[0]._data[0]._hdd_mem ) # important
+                    fileNameProxyIn = a[0][1][0].get()._input_hdd_mem._data[0]._data[0]._file_name
+                    logging.debug( fileNameProxyIn )
+                    del zeinput0
+                    del ret3
+                    import gc ; gc.collect()
+                    if fileNameProxyIn is not None:
+                        if os.path.exists(fileNameProxyIn):
+                            raise RuntimeError("Oooops 2")
+                    for fileNameProxyOut in fileNamesProxyOut:
+                        if fileNameProxyOut is not None:
+                            if os.path.exists(fileNameProxyOut):
+                                raise RuntimeError("Oooops 3")
+                    # execution #2 inside last
+                    script_st2 = """
 import logging
 b = 7+a
 logging.debug("Execution 2")
 import time
 time.sleep(1)
 """
-            obj2 = SALOME_PyNode.SenderByte_i(poa,pickle.dumps((["a"],{"a":3})))
-            id2_o = poa.activate_object(obj2)
-            refPtr2 = poa.id_to_reference(id2_o)
-            pyscript2.assignNewCompiledCode(script_st2)
-            pyscript2.executeFirst(refPtr2)
-            ret2_0 = pyscript2.executeSecond(["b"])
-            ret2_1, fileNamesProxyOut2 = unProxyfy( ret2_0 )
-            logging.debug( fileNamesProxyOut2 )
-            a = salome.logm.NaiveFetch()
-            del ret2_1
-            import gc ; gc.collect()
-            for fileNameProxyOut in fileNamesProxyOut2:
-                if fileNameProxyOut is not None:
-                    if os.path.exists(fileNameProxyOut):
-                        raise RuntimeError("Oooops 3")
-            #
-            fname = os.path.join(str( tmpdirname ),"perf.log")
-            salome.logm.DumpInFile( fname )
-            logManagerInst0 = salome.logm.LoadFromFile( fname )
-            logging.debug( logManagerInst0[0][1][0].get()._input_hdd_mem._data[1]._data[0]._data[0]._hdd_mem ) # important
-            logManagerInst = salome.logm.Fetch(True)
-            logManagerInst2 = salome.logm.Fetch(True)
-            logging.debug( logManagerInst[0][1][0].get()._input_hdd_mem._data[1]._data[0]._data[0]._hdd_mem ) # important
-            self.assertTrue( logManagerInst2[0][1][0].get() is None )
-            self.assertTrue( logManagerInst[0][1][1].get()._output_hdd_mem._data[0]._file_name == fileNamesProxyOut2[0] )
-            logging.debug( logManagerInst[0][1][1].log() )
-            cont.Shutdown()
+                    obj2 = SALOME_PyNode.SenderByte_i(poa,pickle.dumps((["a"],{"a":3})))
+                    id2_o = poa.activate_object(obj2)
+                    refPtr2 = poa.id_to_reference(id2_o)
+                    pyscript2.assignNewCompiledCode(script_st2)
+                    pyscript2.executeFirst(refPtr2)
+                    ret2_0 = pyscript2.executeSecond(["b"])
+                    ret2_1, fileNamesProxyOut2 = unProxyfy( ret2_0 )
+                    logging.debug( fileNamesProxyOut2 )
+                    a = salome.logm.NaiveFetch()
+                    del ret2_1
+                    import gc ; gc.collect()
+                    for fileNameProxyOut in fileNamesProxyOut2:
+                        if fileNameProxyOut is not None:
+                            if os.path.exists(fileNameProxyOut):
+                                raise RuntimeError("Oooops 3")
+                    #
+                    fname = os.path.join(str( tmpdirname ),"perf.log")
+                    salome.logm.DumpInFile( fname )
+                    logManagerInst0 = salome.logm.LoadFromFile( fname )
+                    logging.debug( logManagerInst0[0][1][0].get()._input_hdd_mem._data[1]._data[0]._data[0]._hdd_mem ) # important
+                    logManagerInst = salome.logm.Fetch(True)
+                    logManagerInst2 = salome.logm.Fetch(True)
+                    salome.logm.putStructInFileAtomic(False,monitoringFileTwo)
+                    logging.debug( salome.logm.LoadFromFile(monitoringFileTwo)[0][1][0].get() )
+                    logging.debug( logManagerInst[0][1][0].get()._input_hdd_mem._data[1]._data[0]._data[0]._hdd_mem ) # important
+                    self.assertTrue( logManagerInst2[0][1][0].get() is None )
+                    self.assertTrue( logManagerInst[0][1][1].get()._output_hdd_mem._data[0]._file_name == fileNamesProxyOut2[0] )
+                    logging.debug( logManagerInst[0][1][1].log() )
+                    # 2 files because a backup file is stored in case of unexpected kill during 
+                    self.assertEqual( len( glob.glob("{}*".format(monitoringFile) ) ) , 2 )
+                    # leaving MonitoringFile Manager -> backup file is killed
+                    pass
+                #self.assertEqual(monitoringFileSafe, monitoringFile)
+                self.assertEqual( len( glob.glob("{}*".format(monitoringFile) ) ) , 1 )
+                logging.debug( salome.logm.LoadFromFile(monitoringFile)[0][1][0].get() )
+                del monitoringParams
+                import gc ; gc.collect()
+                self.assertFalse( os.path.exists(pyFileContainingCodeOfMonitoring) )
+                cont.Shutdown()
 
 if __name__ == '__main__':
     from salome_utils import positionVerbosityOfLoggerRegardingState,setVerboseLevel,setVerbose