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 for(auto script : _scripts)
198 PortableServer::ServantBase *serv = getPOA()->reference_to_servant(script);
199 PortableServer::ObjectId_var oid = getPOA()->reference_to_id(script);
200 getPOA()->deactivate_object(oid);
205 PortableServer::POA_var SALOME_ContainerPerfLog::getPOA()
207 return father()->getPOA();
210 Engines::ContainerScriptPerfLog_ptr SALOME_ContainerPerfLog::addScript(const char *name, const char *code)
212 SALOME_ContainerScriptPerfLog *script = new SALOME_ContainerScriptPerfLog(this,name,code);
213 PortableServer::ObjectId_var id(getPOA()->activate_object(script));
214 script->_remove_ref();
215 CORBA::Object_var scriptPtr(getPOA()->id_to_reference(id));
216 Engines::ContainerScriptPerfLog_var scriptPtr2 = Engines::ContainerScriptPerfLog::_narrow(scriptPtr);
217 _scripts.push_back( scriptPtr2 );
220 PyObject *result = PyObject_CallMethod(pyObj(),(char*)"addScript","",nullptr);
221 if (PyErr_Occurred())
223 std::string error("can not addScript");
225 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
227 script->setPyObj( result );
229 return scriptPtr2._retn();
232 Engines::ListOfContainerScriptPerfLog *SALOME_ContainerPerfLog::listOfScripts()
234 Engines::ListOfContainerScriptPerfLog_var ret = new Engines::ListOfContainerScriptPerfLog;
235 std::size_t len( this->_scripts.size() );
237 for(std::size_t i = 0 ; i < len ; ++i)
238 ret[i] = this->_scripts[i];
242 void SALOME_ContainerPerfLog::accept(SALOME_VisitorContainerLog &visitor)
244 visitor.enterContainerPerfLog( *this );
245 for(auto script : _scripts)
247 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( script );
249 SALOME_ContainerScriptPerfLog *servC = dynamic_cast<SALOME_ContainerScriptPerfLog *>(serv);
250 servC->accept(visitor);
252 visitor.leaveContainerPerfLog( *this );
255 char *SALOME_ContainerPerfLog::getLogFile()
257 return CORBA::string_dup( this->_log_file.c_str() );
260 char *SALOME_ContainerPerfLog::getContainerEntryInNS()
262 return CORBA::string_dup( this->_name_in_ns.c_str() );
267 std::string SALOME_SafeLoggerFileHolder::getLastVersionOfFileNameLogger()
269 switch( _version_activated )
271 case SafeLoggerActiveVersionType::VersionA_Activated:
272 return _logger_file_a;
273 case SafeLoggerActiveVersionType::VersionB_Activated:
274 return _logger_file_b;
275 case SafeLoggerActiveVersionType::NoVersion_Activated:
276 return std::string();
278 throw std::runtime_error("getLastVersionOfFileNameLogger : Situation not managed");
284 SALOME_LogManager::SALOME_LogManager(CORBA::ORB_ptr orb, PortableServer::POA_var poa,SALOME_NamingService_Abstract *ns):_poa(poa)
287 PortableServer::ObjectId_var id(_poa->activate_object(this));
288 CORBA::Object_var obj(_poa->id_to_reference(id));
289 Engines::LogManager_var refPtr(Engines::LogManager::_narrow(obj));
290 _NS->Register(refPtr,NAME_IN_NS);
293 std::ostringstream myCommand;
294 myCommand << "mylogmanager = SALOME_LogManager.SALOME_LogManagerHelper()";
295 PyRun_SimpleString("import SALOME_LogManager");
296 PyRun_SimpleString((char*)myCommand.str().c_str());
297 PyObject *mainmod = PyImport_AddModule("__main__");
298 PyObject *globals = PyModule_GetDict(mainmod);
299 _pyLogManager = PyDict_GetItemString(globals, "mylogmanager");
303 SALOME_LogManager::~SALOME_LogManager()
308 void SALOME_LogManager::clear()
310 for(auto cont : _containers)
312 PortableServer::ServantBase *serv = getPOA()->reference_to_servant(cont);
313 PortableServer::ObjectId_var oid = getPOA()->reference_to_id(cont);
314 getPOA()->deactivate_object(oid);
319 Engines::ContainerPerfLog_ptr SALOME_LogManager::declareContainer(const char *contInNS, const char *logfile)
321 SALOME_ContainerPerfLog *cont = new SALOME_ContainerPerfLog(this,contInNS,logfile);
322 PortableServer::ObjectId_var id(_poa->activate_object(cont));
323 CORBA::Object_var contPtr(_poa->id_to_reference(id));
325 Engines::ContainerPerfLog_var contPtr2 = Engines::ContainerPerfLog::_narrow(contPtr);
326 _containers.push_back( contPtr2 );
329 PyObject *result = PyObject_CallMethod(_pyLogManager,(char*)"declareContainer","ss",contInNS,logfile,nullptr);
330 if (PyErr_Occurred())
332 std::string error("can not declareContainer");
334 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
336 cont->setPyObj( result );
338 return contPtr2._retn();
341 Engines::ListOfContainerPerfLog *SALOME_LogManager::listOfContainerLogs()
343 Engines::ListOfContainerPerfLog_var ret = new Engines::ListOfContainerPerfLog;
344 std::size_t len( this->_containers.size() );
346 for(std::size_t i = 0 ; i < len ; ++i)
348 ret[i] = this->_containers[i];
353 void SALOME_LogManager::accept(SALOME_VisitorContainerLog &visitor)
355 visitor.enterLogManager( *this );
356 for(auto container : _containers)
358 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( container );
360 SALOME_ContainerPerfLog *servC = dynamic_cast<SALOME_ContainerPerfLog *>(serv);
361 servC->accept(visitor);
363 visitor.leaveLogManager( *this );
367 \param [in] unloadMemory - specify if big part of struct data (SALOME_ContainerScriptExecPerfLog) is cleared after retrieving data
369 SALOME::vectorOfByte *SALOME_LogManager::getAllStruct(bool clearMemory)
371 std::vector<char> data = this->dumpCppInternalFrmt(clearMemory);
372 return FromVectCharToCorba(data);
375 void SALOME_LogManager::putStructInFileAtomic(bool clearMemory, const char *fileName)
377 std::vector<char> data = this->dumpCppInternalFrmt(clearMemory);
380 AutoPyRef dataPy(PyBytes_FromStringAndSize(data.data(),data.size()));
381 AutoPyRef result = PyObject_CallMethod(_pyLogManager,(char*)"putStructInFileAtomic","Os",dataPy.get(),fileName,nullptr);
385 void SALOME_LogManager::setFileNamePairOfLogger(const char *loggerFileNameA, const char *loggerFileNameB)
387 _safe_logger_file_holder.setFileNamePairOfLogger(loggerFileNameA,loggerFileNameB);
390 void SALOME_LogManager::getFileNamePairOfLogger(CORBA::String_out loggerFileNameA, CORBA::String_out loggerFileNameB)
392 std::string loggerFileNameAS,loggerFileNameBS;
393 _safe_logger_file_holder.getFileNamePairOfLogger(loggerFileNameAS,loggerFileNameBS);
394 loggerFileNameA = CORBA::string_dup(loggerFileNameAS.c_str());
395 loggerFileNameB = CORBA::string_dup(loggerFileNameBS.c_str());
398 char *SALOME_LogManager::getLastVersionOfFileNameLogger()
400 return CORBA::string_dup( _safe_logger_file_holder.getLastVersionOfFileNameLogger().c_str() );
403 ///////////////////////
407 static void PushIntInVC(std::uint32_t val, std::vector<char>& data)
409 char *valPtr = reinterpret_cast<char *>(&val);
410 data.insert(data.end(),valPtr,valPtr+sizeof(std::uint32_t));
414 static void PushStringInVC(const T& str, std::vector<char>& data)
416 std::uint32_t sz = static_cast<std::uint32_t>( str.size() );
417 PushIntInVC(sz,data);
418 data.insert(data.end(),str.data(),str.data()+sz);
421 class InternalFormatVisitorDump : public SALOME_VisitorContainerLog
424 InternalFormatVisitorDump(bool clearMemory, std::vector<char> *data):_clear_memory(clearMemory),_data(data) { }
425 void enterLogManager(SALOME_LogManager& inst) override;
426 void leaveLogManager(SALOME_LogManager& inst) override { }
427 void enterContainerPerfLog(SALOME_ContainerPerfLog& inst) override;
428 void leaveContainerPerfLog(SALOME_ContainerPerfLog& inst) override { }
429 void enterContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst) override;
430 void leaveContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst) override { }
431 void visitContainerScriptExecPerfLog(SALOME_ContainerScriptExecPerfLog& inst) override;
433 bool _clear_memory = false;
434 std::vector<char> *_data = nullptr;
437 void InternalFormatVisitorDump::visitContainerScriptExecPerfLog(SALOME_ContainerScriptExecPerfLog& inst)
439 PushStringInVC<std::vector<char>>(inst.data(),*_data);
444 void InternalFormatVisitorDump::enterContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst)
446 PushStringInVC<std::string>(inst.name(),*_data);
447 PushStringInVC<std::string>(inst.code(),*_data);
448 PushIntInVC((std::uint32_t)inst.getNumberOfSessions(),*_data);
451 void InternalFormatVisitorDump::enterContainerPerfLog(SALOME_ContainerPerfLog& inst)
453 PushStringInVC<std::string>(inst.nameInNS(),*_data);
454 PushStringInVC<std::string>(inst.logFile(),*_data);
455 PushIntInVC((std::uint32_t)inst.getNumberOfScripts(),*_data);
458 void InternalFormatVisitorDump::enterLogManager(SALOME_LogManager& inst)
460 PushIntInVC((std::uint32_t)inst.getNumberOfContainers(),*_data);
463 std::vector<char> SALOME_LogManager::dumpCppInternalFrmt(bool clearMemory)
465 std::vector<char> ret;
466 InternalFormatVisitorDump visitor(clearMemory,&ret);
467 this->accept( visitor );