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>
37 const char SALOME_LogManager::NAME_IN_NS[]="/LogManager";
39 static std::vector<char> FromPyToCpp(PyObject *obj)
41 std::vector<char> ret;
42 char *buffer = nullptr;
43 Py_ssize_t length = 0;
44 PyBytes_AsStringAndSize(obj,&buffer,&length);
46 for(auto i = 0 ; i < length ; ++i)
51 static SALOME::vectorOfByte *FromVectCharToCorba(const std::vector<char>& data)
53 SALOME::vectorOfByte_var ret = new SALOME::vectorOfByte;
54 auto length = data.size();
56 for(auto i = 0 ; i < length ; ++i)
61 PortableServer::POA_var SALOME_ContainerScriptExecPerfLog::getPOA()
63 return father()->getPOA();
66 void SALOME_ContainerScriptExecPerfLog::assign(const SALOME::vectorOfByte& value)
68 auto sz = value.length();
70 for(auto i = 0 ; i < sz ; ++i)
73 AutoPyRef s( this->end( ) );
75 _data = FromPyToCpp(s);
78 SALOME::vectorOfByte *SALOME_ContainerScriptExecPerfLog::getObj()
80 return FromVectCharToCorba(this->_data);
83 void SALOME_ContainerScriptExecPerfLog::accept(SALOME_VisitorContainerLog &visitor)
85 visitor.visitContainerScriptExecPerfLog( *this );
88 void SALOME_ContainerScriptExecPerfLog::start()
91 AutoPyRef result = PyObject_CallMethod(pyObj(),(char*)"start","",nullptr);
94 std::string error("can not start");
96 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
100 AutoPyRef SALOME_ContainerScriptExecPerfLog::end()
103 //https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
104 AutoPyRef dataPy(PyBytes_FromStringAndSize(_data.data(),_data.size()));
105 AutoPyRef result(PyObject_CallMethod(pyObj(),(char*)"end","O",dataPy.get(),nullptr) ) ;
106 if (PyErr_Occurred())
108 std::string error("can not end");
110 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
117 PortableServer::POA_var SALOME_ContainerScriptPerfLog::getPOA()
119 return father()->getPOA();
122 char *SALOME_ContainerScriptPerfLog::getCode()
124 return CORBA::string_dup( _code.c_str() );
127 char *SALOME_ContainerScriptPerfLog::getName()
129 return CORBA::string_dup( _name.c_str() );
132 void SALOME_ContainerScriptPerfLog::accept(SALOME_VisitorContainerLog &visitor)
134 visitor.enterContainerScriptPerfLog( *this );
135 for(auto session : _sessions)
137 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( session );
139 SALOME_ContainerScriptExecPerfLog *servC = dynamic_cast<SALOME_ContainerScriptExecPerfLog *>(serv);
140 visitor.visitContainerScriptExecPerfLog( *servC );
142 visitor.leaveContainerScriptPerfLog( *this );
145 Engines::ContainerScriptExecPerfLog_ptr SALOME_ContainerScriptPerfLog::addExecutionSession()
147 SALOME_ContainerScriptExecPerfLog *execution = new SALOME_ContainerScriptExecPerfLog(this);
148 PortableServer::ObjectId_var id(getPOA()->activate_object(execution));
149 execution->_remove_ref();
150 CORBA::Object_var executionPtr(getPOA()->id_to_reference(id));
151 Engines::ContainerScriptExecPerfLog_var executionPtr2 = Engines::ContainerScriptExecPerfLog::_narrow(executionPtr);
152 _sessions.push_back( executionPtr2 );
155 AutoPyRef result = PyObject_CallMethod(pyObj(),(char*)"addExecution","",nullptr);
156 if (PyErr_Occurred())
158 std::string error("can not addExecution");
160 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
162 execution->setPyObj( result.retn() );//ownership of result is transfered to execution
165 return executionPtr2._retn();
168 Engines::ListOfContainerScriptExecPerfLog *SALOME_ContainerScriptPerfLog::listOfExecs()
170 Engines::ListOfContainerScriptExecPerfLog_var ret = new Engines::ListOfContainerScriptExecPerfLog;
171 auto sz = this->_sessions.size();
173 for(auto i = 0 ; i < sz ; ++i)
174 ret[i] = this->_sessions[i];
180 PortableServer::POA_var SALOME_ContainerPerfLog::getPOA()
182 return father()->getPOA();
185 Engines::ContainerScriptPerfLog_ptr SALOME_ContainerPerfLog::addScript(const char *name, const char *code)
187 SALOME_ContainerScriptPerfLog *script = new SALOME_ContainerScriptPerfLog(this,name,code);
188 PortableServer::ObjectId_var id(getPOA()->activate_object(script));
189 script->_remove_ref();
190 CORBA::Object_var scriptPtr(getPOA()->id_to_reference(id));
191 Engines::ContainerScriptPerfLog_var scriptPtr2 = Engines::ContainerScriptPerfLog::_narrow(scriptPtr);
192 _scripts.push_back( scriptPtr2 );
195 PyObject *result = PyObject_CallMethod(pyObj(),(char*)"addScript","",nullptr);
196 if (PyErr_Occurred())
198 std::string error("can not addScript");
200 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
202 script->setPyObj( result );
204 return scriptPtr2._retn();
207 Engines::ListOfContainerScriptPerfLog *SALOME_ContainerPerfLog::listOfScripts()
209 Engines::ListOfContainerScriptPerfLog_var ret = new Engines::ListOfContainerScriptPerfLog;
210 std::size_t len( this->_scripts.size() );
212 for(std::size_t i = 0 ; i < len ; ++i)
213 ret[i] = this->_scripts[i];
217 void SALOME_ContainerPerfLog::accept(SALOME_VisitorContainerLog &visitor)
219 visitor.enterContainerPerfLog( *this );
220 for(auto script : _scripts)
222 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( script );
224 SALOME_ContainerScriptPerfLog *servC = dynamic_cast<SALOME_ContainerScriptPerfLog *>(serv);
225 servC->accept(visitor);
227 visitor.leaveContainerPerfLog( *this );
230 char *SALOME_ContainerPerfLog::getLogFile()
232 return CORBA::string_dup( this->_log_file.c_str() );
235 char *SALOME_ContainerPerfLog::getContainerEntryInNS()
237 return CORBA::string_dup( this->_name_in_ns.c_str() );
242 std::string SALOME_SafeLoggerFileHolder::getLastVersionOfFileNameLogger()
244 switch( _version_activated )
246 case SafeLoggerActiveVersionType::VersionA_Activated:
247 return _logger_file_a;
248 case SafeLoggerActiveVersionType::VersionB_Activated:
249 return _logger_file_b;
250 case SafeLoggerActiveVersionType::NoVersion_Activated:
251 return std::string();
253 throw std::runtime_error("getLastVersionOfFileNameLogger : Situation not managed");
259 SALOME_LogManager::SALOME_LogManager(CORBA::ORB_ptr orb, PortableServer::POA_var poa,SALOME_NamingService_Abstract *ns):_poa(poa)
262 PortableServer::ObjectId_var id(_poa->activate_object(this));
263 CORBA::Object_var obj(_poa->id_to_reference(id));
264 Engines::LogManager_var refPtr(Engines::LogManager::_narrow(obj));
265 _NS->Register(refPtr,NAME_IN_NS);
268 std::ostringstream myCommand;
269 myCommand << "mylogmanager = SALOME_LogManager.SALOME_LogManagerHelper()";
270 PyRun_SimpleString("import SALOME_LogManager");
271 PyRun_SimpleString((char*)myCommand.str().c_str());
272 PyObject *mainmod = PyImport_AddModule("__main__");
273 PyObject *globals = PyModule_GetDict(mainmod);
274 _pyLogManager = PyDict_GetItemString(globals, "mylogmanager");
278 Engines::ContainerPerfLog_ptr SALOME_LogManager::declareContainer(const char *contInNS, const char *logfile)
280 SALOME_ContainerPerfLog *cont = new SALOME_ContainerPerfLog(this,contInNS,logfile);
281 PortableServer::ObjectId_var id(_poa->activate_object(cont));
282 CORBA::Object_var contPtr(_poa->id_to_reference(id));
284 Engines::ContainerPerfLog_var contPtr2 = Engines::ContainerPerfLog::_narrow(contPtr);
285 _containers.push_back( contPtr2 );
288 PyObject *result = PyObject_CallMethod(_pyLogManager,(char*)"declareContainer","ss",contInNS,logfile,nullptr);
289 if (PyErr_Occurred())
291 std::string error("can not declareContainer");
293 THROW_SALOME_CORBA_EXCEPTION(error.c_str(),SALOME::INTERNAL_ERROR);
295 cont->setPyObj( result );
297 return contPtr2._retn();
300 Engines::ListOfContainerPerfLog *SALOME_LogManager::listOfContainerLogs()
302 Engines::ListOfContainerPerfLog_var ret = new Engines::ListOfContainerPerfLog;
303 std::size_t len( this->_containers.size() );
305 for(std::size_t i = 0 ; i < len ; ++i)
307 ret[i] = this->_containers[i];
312 void SALOME_LogManager::accept(SALOME_VisitorContainerLog &visitor)
314 visitor.enterLogManager( *this );
315 for(auto container : _containers)
317 PortableServer::ServantBase *serv = getPOA()->reference_to_servant( container );
319 SALOME_ContainerPerfLog *servC = dynamic_cast<SALOME_ContainerPerfLog *>(serv);
320 servC->accept(visitor);
322 visitor.leaveLogManager( *this );
326 \param [in] unloadMemory - specify if big part of struct data (SALOME_ContainerScriptExecPerfLog) is cleared after retrieving data
328 SALOME::vectorOfByte *SALOME_LogManager::getAllStruct(bool clearMemory)
330 std::vector<char> data = this->dumpCppInternalFrmt(clearMemory);
331 return FromVectCharToCorba(data);
334 void SALOME_LogManager::putStructInFileAtomic(bool clearMemory, const char *fileName)
336 std::vector<char> data = this->dumpCppInternalFrmt(clearMemory);
339 AutoPyRef dataPy(PyBytes_FromStringAndSize(data.data(),data.size()));
340 AutoPyRef result = PyObject_CallMethod(_pyLogManager,(char*)"putStructInFileAtomic","Os",dataPy.get(),fileName,nullptr);
344 void SALOME_LogManager::setFileNamePairOfLogger(const char *loggerFileNameA, const char *loggerFileNameB)
346 _safe_logger_file_holder.setFileNamePairOfLogger(loggerFileNameA,loggerFileNameB);
349 void SALOME_LogManager::getFileNamePairOfLogger(CORBA::String_out loggerFileNameA, CORBA::String_out loggerFileNameB)
351 std::string loggerFileNameAS,loggerFileNameBS;
352 _safe_logger_file_holder.getFileNamePairOfLogger(loggerFileNameAS,loggerFileNameBS);
353 loggerFileNameA = CORBA::string_dup(loggerFileNameAS.c_str());
354 loggerFileNameB = CORBA::string_dup(loggerFileNameBS.c_str());
357 char *SALOME_LogManager::getLastVersionOfFileNameLogger()
359 return CORBA::string_dup( _safe_logger_file_holder.getLastVersionOfFileNameLogger().c_str() );
362 ///////////////////////
366 static void PushIntInVC(std::uint32_t val, std::vector<char>& data)
368 char *valPtr = reinterpret_cast<char *>(&val);
369 data.insert(data.end(),valPtr,valPtr+sizeof(std::uint32_t));
373 static void PushStringInVC(const T& str, std::vector<char>& data)
375 std::uint32_t sz = static_cast<std::uint32_t>( str.size() );
376 PushIntInVC(sz,data);
377 data.insert(data.end(),str.data(),str.data()+sz);
380 class InternalFormatVisitorDump : public SALOME_VisitorContainerLog
383 InternalFormatVisitorDump(bool clearMemory, std::vector<char> *data):_clear_memory(clearMemory),_data(data) { }
384 void enterLogManager(SALOME_LogManager& inst) override;
385 void leaveLogManager(SALOME_LogManager& inst) override { }
386 void enterContainerPerfLog(SALOME_ContainerPerfLog& inst) override;
387 void leaveContainerPerfLog(SALOME_ContainerPerfLog& inst) override { }
388 void enterContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst) override;
389 void leaveContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst) override { }
390 void visitContainerScriptExecPerfLog(SALOME_ContainerScriptExecPerfLog& inst) override;
392 bool _clear_memory = false;
393 std::vector<char> *_data = nullptr;
396 void InternalFormatVisitorDump::visitContainerScriptExecPerfLog(SALOME_ContainerScriptExecPerfLog& inst)
398 PushStringInVC<std::vector<char>>(inst.data(),*_data);
403 void InternalFormatVisitorDump::enterContainerScriptPerfLog(SALOME_ContainerScriptPerfLog& inst)
405 PushStringInVC<std::string>(inst.name(),*_data);
406 PushStringInVC<std::string>(inst.code(),*_data);
407 PushIntInVC((std::uint32_t)inst.getNumberOfSessions(),*_data);
410 void InternalFormatVisitorDump::enterContainerPerfLog(SALOME_ContainerPerfLog& inst)
412 PushStringInVC<std::string>(inst.nameInNS(),*_data);
413 PushStringInVC<std::string>(inst.logFile(),*_data);
414 PushIntInVC((std::uint32_t)inst.getNumberOfScripts(),*_data);
417 void InternalFormatVisitorDump::enterLogManager(SALOME_LogManager& inst)
419 PushIntInVC((std::uint32_t)inst.getNumberOfContainers(),*_data);
422 std::vector<char> SALOME_LogManager::dumpCppInternalFrmt(bool clearMemory)
424 std::vector<char> ret;
425 InternalFormatVisitorDump visitor(clearMemory,&ret);
426 this->accept( visitor );