1 // Copyright (C) 2024 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "SALOME_LogManager.hxx"
21 #include "SALOME_Fake_NamingService.hxx"
22 #include "SALOME_ContainerManager.hxx"
28 #include <Basics_Utils.hxx>
31 #include "utilities.h"
39 const char SALOME_LogManager::NAME_IN_NS[]="/LogManager";
41 static std::vector<char> FromPyToCpp(PyObject *obj)
43 std::vector<char> ret;
44 char *buffer = nullptr;
45 Py_ssize_t length = 0;
46 PyBytes_AsStringAndSize(obj,&buffer,&length);
48 for(auto i = 0 ; i < length ; ++i)
53 static SALOME::vectorOfByte *FromVectCharToCorba(const std::vector<char>& data)
55 SALOME::vectorOfByte_var ret = new SALOME::vectorOfByte;
56 auto length = data.size();
58 for(auto i = 0 ; i < length ; ++i)
63 SALOME_ContainerScriptPerfLog::~SALOME_ContainerScriptPerfLog()
65 for(auto execSession : _sessions)
67 PortableServer::ServantBase *serv = getPOA()->reference_to_servant(execSession);
68 PortableServer::ObjectId_var oid = getPOA()->reference_to_id(execSession);
69 getPOA()->deactivate_object(oid);
74 PortableServer::POA_var SALOME_ContainerScriptExecPerfLog::getPOA()
76 return father()->getPOA();
79 void SALOME_ContainerScriptExecPerfLog::assign(const SALOME::vectorOfByte& value)
81 auto sz = value.length();
83 for(auto i = 0 ; i < sz ; ++i)
86 AutoPyRef s( this->end( ) );
88 _data = FromPyToCpp(s);
91 SALOME::vectorOfByte *SALOME_ContainerScriptExecPerfLog::getObj()
93 return FromVectCharToCorba(this->_data);
96 void SALOME_ContainerScriptExecPerfLog::accept(SALOME_VisitorContainerLog &visitor)
98 visitor.visitContainerScriptExecPerfLog( *this );
101 void SALOME_ContainerScriptExecPerfLog::start()
104 AutoPyRef result = PyObject_CallMethod(pyObj(),(char*)"start","",nullptr);
105 if (PyErr_Occurred())
107 std::string error("can not start");
109 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
113 AutoPyRef SALOME_ContainerScriptExecPerfLog::end()
116 //https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
117 AutoPyRef dataPy(PyBytes_FromStringAndSize(_data.data(),_data.size()));
118 AutoPyRef result(PyObject_CallMethod(pyObj(),(char*)"end","O",dataPy.get(),nullptr) ) ;
119 if (PyErr_Occurred())
121 std::string error("can not end");
123 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
130 PortableServer::POA_var SALOME_ContainerScriptPerfLog::getPOA()
132 return father()->getPOA();
135 char *SALOME_ContainerScriptPerfLog::getCode()
137 return CORBA::string_dup( _code.c_str() );
140 char *SALOME_ContainerScriptPerfLog::getName()
142 return CORBA::string_dup( _name.c_str() );
145 void SALOME_ContainerScriptPerfLog::accept(SALOME_VisitorContainerLog &visitor)
147 visitor.enterContainerScriptPerfLog( *this );
148 for(auto session : _sessions)
150 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( session );
152 SALOME_ContainerScriptExecPerfLog *servC = dynamic_cast<SALOME_ContainerScriptExecPerfLog *>(serv);
153 visitor.visitContainerScriptExecPerfLog( *servC );
155 visitor.leaveContainerScriptPerfLog( *this );
159 Engines::ContainerScriptExecPerfLog_ptr SALOME_ContainerScriptPerfLog::addExecutionSession()
161 SALOME_ContainerScriptExecPerfLog *execution = new SALOME_ContainerScriptExecPerfLog(this);
162 PortableServer::ObjectId_var id(getPOA()->activate_object(execution));
163 execution->_remove_ref();
164 CORBA::Object_var executionPtr(getPOA()->id_to_reference(id));
165 Engines::ContainerScriptExecPerfLog_var executionPtr2 = Engines::ContainerScriptExecPerfLog::_narrow(executionPtr);
166 _sessions.push_back( executionPtr2 );
169 AutoPyRef result = PyObject_CallMethod(pyObj(),(char*)"addExecution","",nullptr);
170 if (PyErr_Occurred())
172 std::string error("can not addExecution");
174 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
176 execution->setPyObj( result.retn() );//ownership of result is transfered to execution
179 return executionPtr2._retn();
182 Engines::ListOfContainerScriptExecPerfLog *SALOME_ContainerScriptPerfLog::listOfExecs()
184 Engines::ListOfContainerScriptExecPerfLog_var ret = new Engines::ListOfContainerScriptExecPerfLog;
185 auto sz = this->_sessions.size();
187 for(auto i = 0 ; i < sz ; ++i)
188 ret[i] = this->_sessions[i];
194 SALOME_ContainerPerfLog::~SALOME_ContainerPerfLog()
196 this->destroyInternal();
199 PortableServer::POA_var SALOME_ContainerPerfLog::getPOA()
201 return father()->getPOA();
204 Engines::ContainerScriptPerfLog_ptr SALOME_ContainerPerfLog::addScript(const char *name, const char *code)
206 SALOME_ContainerScriptPerfLog *script = new SALOME_ContainerScriptPerfLog(this,name,code);
207 PortableServer::ObjectId_var id(getPOA()->activate_object(script));
208 script->_remove_ref();
209 CORBA::Object_var scriptPtr(getPOA()->id_to_reference(id));
210 Engines::ContainerScriptPerfLog_var scriptPtr2 = Engines::ContainerScriptPerfLog::_narrow(scriptPtr);
211 _scripts.push_back( scriptPtr2 );
214 PyObject *result = PyObject_CallMethod(pyObj(),(char*)"addScript","",nullptr);
215 if (PyErr_Occurred())
217 std::string error("can not addScript");
219 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
221 script->setPyObj( result );
223 return scriptPtr2._retn();
226 Engines::ListOfContainerScriptPerfLog *SALOME_ContainerPerfLog::listOfScripts()
228 Engines::ListOfContainerScriptPerfLog_var ret = new Engines::ListOfContainerScriptPerfLog;
229 std::size_t len( this->_scripts.size() );
231 for(std::size_t i = 0 ; i < len ; ++i)
232 ret[i] = this->_scripts[i];
236 void SALOME_ContainerPerfLog::destroy()
238 this->destroyInternal();
241 void SALOME_ContainerPerfLog::destroyInternal()
243 _father->removeEntryBeforeDying( this );
244 for(auto script : _scripts)
246 PortableServer::ServantBase *serv = getPOA()->reference_to_servant(script);
247 PortableServer::ObjectId_var oid = getPOA()->reference_to_id(script);
248 getPOA()->deactivate_object(oid);
253 void SALOME_ContainerPerfLog::accept(SALOME_VisitorContainerLog &visitor)
255 visitor.enterContainerPerfLog( *this );
256 for(auto script : _scripts)
258 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( script );
260 SALOME_ContainerScriptPerfLog *servC = dynamic_cast<SALOME_ContainerScriptPerfLog *>(serv);
261 servC->accept(visitor);
263 visitor.leaveContainerPerfLog( *this );
266 char *SALOME_ContainerPerfLog::getLogFile()
268 return CORBA::string_dup( this->_log_file.c_str() );
271 char *SALOME_ContainerPerfLog::getContainerEntryInNS()
273 return CORBA::string_dup( this->_name_in_ns.c_str() );
278 std::string SALOME_SafeLoggerFileHolder::getLastVersionOfFileNameLogger()
280 switch( _version_activated )
282 case SafeLoggerActiveVersionType::VersionA_Activated:
283 return _logger_file_a;
284 case SafeLoggerActiveVersionType::VersionB_Activated:
285 return _logger_file_b;
286 case SafeLoggerActiveVersionType::NoVersion_Activated:
287 return std::string();
289 throw std::runtime_error("getLastVersionOfFileNameLogger : Situation not managed");
295 SALOME_LogManager::SALOME_LogManager(CORBA::ORB_ptr orb, PortableServer::POA_var poa,SALOME_NamingService_Abstract *ns):_poa(poa)
298 PortableServer::ObjectId_var id(_poa->activate_object(this));
299 CORBA::Object_var obj(_poa->id_to_reference(id));
300 Engines::LogManager_var refPtr(Engines::LogManager::_narrow(obj));
301 _NS->Register(refPtr,NAME_IN_NS);
304 std::ostringstream myCommand;
305 myCommand << "mylogmanager = SALOME_LogManager.SALOME_LogManagerHelper()";
306 PyRun_SimpleString("import SALOME_LogManager");
307 PyRun_SimpleString((char*)myCommand.str().c_str());
308 PyObject *mainmod = PyImport_AddModule("__main__");
309 PyObject *globals = PyModule_GetDict(mainmod);
310 _pyLogManager = PyDict_GetItemString(globals, "mylogmanager");
314 SALOME_LogManager::~SALOME_LogManager()
319 void SALOME_LogManager::clear()
321 for(auto cont : _containers)
323 PortableServer::ServantBase *serv = getPOA()->reference_to_servant(cont);
324 PortableServer::ObjectId_var oid = getPOA()->reference_to_id(cont);
325 getPOA()->deactivate_object(oid);
330 Engines::ContainerPerfLog_ptr SALOME_LogManager::declareContainer(const char *contInNS, const char *logfile)
332 SALOME_ContainerPerfLog *cont = new SALOME_ContainerPerfLog(this,contInNS,logfile);
333 PortableServer::ObjectId_var id(_poa->activate_object(cont));
334 CORBA::Object_var contPtr(_poa->id_to_reference(id));
336 Engines::ContainerPerfLog_var contPtr2 = Engines::ContainerPerfLog::_narrow(contPtr);
337 _containers.push_back( contPtr2 );
340 PyObject *result = PyObject_CallMethod(_pyLogManager,(char*)"declareContainer","ss",contInNS,logfile,nullptr);
341 if (PyErr_Occurred())
343 std::string error("can not declareContainer");
345 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
347 cont->setPyObj( result );
349 return contPtr2._retn();
352 Engines::ListOfContainerPerfLog *SALOME_LogManager::listOfContainerLogs()
354 Engines::ListOfContainerPerfLog_var ret = new Engines::ListOfContainerPerfLog;
355 std::size_t len( this->_containers.size() );
357 for(std::size_t i = 0 ; i < len ; ++i)
359 ret[i] = this->_containers[i];
364 void SALOME_LogManager::accept(SALOME_VisitorContainerLog &visitor)
366 visitor.enterLogManager( *this );
367 for(auto container : _containers)
369 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( container );
371 SALOME_ContainerPerfLog *servC = dynamic_cast<SALOME_ContainerPerfLog *>(serv);
372 servC->accept(visitor);
374 visitor.leaveLogManager( *this );
378 \param [in] unloadMemory - specify if big part of struct data (SALOME_ContainerScriptExecPerfLog) is cleared after retrieving data
380 SALOME::vectorOfByte *SALOME_LogManager::getAllStruct(bool clearMemory)
382 std::vector<char> data = this->dumpCppInternalFrmt(clearMemory);
383 return FromVectCharToCorba(data);
386 void SALOME_LogManager::putStructInFileAtomic(bool clearMemory, const char *fileName)
388 std::vector<char> data = this->dumpCppInternalFrmt(clearMemory);
391 AutoPyRef dataPy(PyBytes_FromStringAndSize(data.data(),data.size()));
392 AutoPyRef result = PyObject_CallMethod(_pyLogManager,(char*)"putStructInFileAtomic","Os",dataPy.get(),fileName,nullptr);
396 void SALOME_LogManager::setFileNamePairOfLogger(const char *loggerFileNameA, const char *loggerFileNameB)
398 _safe_logger_file_holder.setFileNamePairOfLogger(loggerFileNameA,loggerFileNameB);
401 void SALOME_LogManager::getFileNamePairOfLogger(CORBA::String_out loggerFileNameA, CORBA::String_out loggerFileNameB)
403 std::string loggerFileNameAS,loggerFileNameBS;
404 _safe_logger_file_holder.getFileNamePairOfLogger(loggerFileNameAS,loggerFileNameBS);
405 loggerFileNameA = CORBA::string_dup(loggerFileNameAS.c_str());
406 loggerFileNameB = CORBA::string_dup(loggerFileNameBS.c_str());
409 char *SALOME_LogManager::getLastVersionOfFileNameLogger()
411 return CORBA::string_dup( _safe_logger_file_holder.getLastVersionOfFileNameLogger().c_str() );
414 void SALOME_LogManager::removeEntryBeforeDying(SALOME_ContainerPerfLog *child)
416 for(auto cont = _containers.begin() ; cont != _containers.end() ; ++cont )
418 PortableServer::ServantBase *serv = getPOA()->reference_to_servant(*cont);
419 SALOME_ContainerPerfLog *servCand = dynamic_cast<SALOME_ContainerPerfLog *>(serv);
420 if( servCand==child )
422 _containers.erase( cont );
428 ///////////////////////
432 static void PushIntInVC(std::uint32_t val, std::vector<char>& data)
434 char *valPtr = reinterpret_cast<char *>(&val);
435 data.insert(data.end(),valPtr,valPtr+sizeof(std::uint32_t));
439 static void PushStringInVC(const T& str, std::vector<char>& data)
441 std::uint32_t sz = static_cast<std::uint32_t>( str.size() );
442 PushIntInVC(sz,data);
443 data.insert(data.end(),str.data(),str.data()+sz);
446 class InternalFormatVisitorDump : public SALOME_VisitorContainerLog
449 InternalFormatVisitorDump(bool clearMemory, std::vector<char> *data):_clear_memory(clearMemory),_data(data) { }
450 void enterLogManager(SALOME_LogManager& inst) override;
451 void leaveLogManager(SALOME_LogManager& inst) override { }
452 void enterContainerPerfLog(SALOME_ContainerPerfLog& inst) override;
453 void leaveContainerPerfLog(SALOME_ContainerPerfLog& inst) override { }
454 void enterContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst) override;
455 void leaveContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst) override { }
456 void visitContainerScriptExecPerfLog(SALOME_ContainerScriptExecPerfLog& inst) override;
458 bool _clear_memory = false;
459 std::vector<char> *_data = nullptr;
462 void InternalFormatVisitorDump::visitContainerScriptExecPerfLog(SALOME_ContainerScriptExecPerfLog& inst)
464 PushStringInVC<std::vector<char>>(inst.data(),*_data);
469 void InternalFormatVisitorDump::enterContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst)
471 PushStringInVC<std::string>(inst.name(),*_data);
472 PushStringInVC<std::string>(inst.code(),*_data);
473 PushIntInVC((std::uint32_t)inst.getNumberOfSessions(),*_data);
476 void InternalFormatVisitorDump::enterContainerPerfLog(SALOME_ContainerPerfLog& inst)
478 PushStringInVC<std::string>(inst.nameInNS(),*_data);
479 PushStringInVC<std::string>(inst.logFile(),*_data);
480 PushIntInVC((std::uint32_t)inst.getNumberOfScripts(),*_data);
483 void InternalFormatVisitorDump::enterLogManager(SALOME_LogManager& inst)
485 PushIntInVC((std::uint32_t)inst.getNumberOfContainers(),*_data);
488 std::vector<char> SALOME_LogManager::dumpCppInternalFrmt(bool clearMemory)
490 std::vector<char> ret;
491 InternalFormatVisitorDump visitor(clearMemory,&ret);
492 this->accept( visitor );