Skip to content

Commit 959b4cd

Browse files
authored
Redirect SOFA logs to Python's sys.stdout using a custom PythonMessageHandler (#576)
* Redirect SOFA logs to Python's sys.stdout using a custom PythonMessageHandler. * cleaning * Redirect SOFA logs to Python's sys.stdout using a custom PythonMessageHandler.
1 parent c0dc30e commit 959b4cd

4 files changed

Lines changed: 140 additions & 3 deletions

File tree

bindings/SofaRuntime/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ project(Bindings.SofaRuntime)
22

33
set(SOURCE_FILES
44
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/SofaRuntime/Module_SofaRuntime.cpp
5+
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/SofaRuntime/PythonMessageHandler.cpp
56
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/SofaRuntime/Timer/Submodule_Timer.cpp
67
)
78

89
set(HEADER_FILES
10+
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/SofaRuntime/PythonMessageHandler.h
911
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/SofaRuntime/Timer/Submodule_Timer.h
1012
${CMAKE_CURRENT_SOURCE_DIR}/src/SofaPython3/SofaRuntime/Timer/Submodule_Timer_doc.h
1113
)

bindings/SofaRuntime/src/SofaPython3/SofaRuntime/Module_SofaRuntime.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ using sofapython3::SceneLoaderPY3;
6262
#include <sofa/core/logging/PerComponentLoggingMessageHandler.h>
6363
using sofa::helper::logging::MessageDispatcher;
6464
using sofa::helper::logging::MainPerComponentLoggingMessageHandler;
65-
using sofa::helper::logging::MainConsoleMessageHandler;
65+
#include <SofaPython3/SofaRuntime/PythonMessageHandler.h>
6666

6767
#include <sofa/core/init.h>
6868
#include <sofa/helper/init.h>
@@ -155,9 +155,9 @@ PYBIND11_MODULE(SofaRuntime, m) {
155155

156156
m.def("init", []() {
157157
MessageDispatcher::clearHandlers();
158-
MessageDispatcher::addHandler(&MainConsoleMessageHandler::getInstance());
158+
MessageDispatcher::addHandler(&MainPythonMessageHandler::getInstance());
159159
MessageDispatcher::addHandler(&MainPerComponentLoggingMessageHandler::getInstance());
160-
});
160+
}, "redirect SOFA messages to Python's sys.stdout");
161161

162162
m.add_object("DataRepository", py::cast(&sofa::helper::system::DataRepository));
163163
m.add_object("PluginRepository", py::cast(&sofa::helper::system::PluginRepository));
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/******************************************************************************
2+
* SOFA, Simulation Open-Framework Architecture *
3+
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Authors: The SOFA Team and external contributors (see Authors.txt) *
19+
* *
20+
* Contact information: contact@sofa-framework.org *
21+
******************************************************************************/
22+
#include <SofaPython3/SofaRuntime/PythonMessageHandler.h>
23+
#include <pybind11/pybind11.h>
24+
#include <sofa/helper/logging/Message.h>
25+
26+
namespace sofapython3
27+
{
28+
29+
namespace
30+
{
31+
32+
using namespace std::string_literals;
33+
const std::string red { "\033[31m"s };
34+
const std::string green { "\033[32m"s };
35+
const std::string orange { "\033[38;5;214m"s };
36+
const std::string magenta { "\033[35m"s };
37+
const std::string blue { "\033[34m"s };
38+
const std::string reset { "\033[0m"s };
39+
40+
std::string format(const std::string& type, const std::string& color)
41+
{
42+
return color + "[" + type + "] " + reset;
43+
};
44+
45+
const std::string& getPrefixText(sofa::helper::logging::Message::Type type)
46+
{
47+
static const std::string advice = format("SUGGESTION", green);
48+
static const std::string deprecated = format("DEPRECATED", orange);
49+
static const std::string warning = format("WARNING", orange);
50+
static const std::string info = format("INFO", green);
51+
static const std::string error = format("ERROR", red);
52+
static const std::string fatal = format("FATAL", magenta);
53+
static const std::string empty = format("EMPTY", reset);
54+
static const std::string nothing{};
55+
56+
switch (type)
57+
{
58+
case sofa::helper::logging::Message::Advice : return advice;
59+
case sofa::helper::logging::Message::Deprecated : return deprecated;
60+
case sofa::helper::logging::Message::Warning : return warning;
61+
case sofa::helper::logging::Message::Info : return info;
62+
case sofa::helper::logging::Message::Error : return error;
63+
case sofa::helper::logging::Message::Fatal : return fatal;
64+
case sofa::helper::logging::Message::TEmpty : return empty;
65+
66+
case sofa::helper::logging::Message::TypeCount:
67+
return nothing;
68+
}
69+
}
70+
71+
}
72+
73+
namespace py { using namespace pybind11; }
74+
75+
void PythonMessageHandler::process(sofa::helper::logging::Message &m)
76+
{
77+
if (!m.sender().empty())
78+
{
79+
py::print(getPrefixText(m.type()), format(m.sender(), blue), m.messageAsString());
80+
}
81+
else
82+
{
83+
py::print(getPrefixText(m.type()), m.messageAsString());
84+
}
85+
}
86+
87+
PythonMessageHandler& MainPythonMessageHandler::getInstance()
88+
{
89+
static PythonMessageHandler s_instance;
90+
return s_instance;
91+
}
92+
93+
} // namespace sofapython3
94+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/******************************************************************************
2+
* SOFA, Simulation Open-Framework Architecture *
3+
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Authors: The SOFA Team and external contributors (see Authors.txt) *
19+
* *
20+
* Contact information: contact@sofa-framework.org *
21+
******************************************************************************/
22+
#pragma once
23+
24+
#include <sofa/helper/logging/MessageHandler.h>
25+
26+
namespace sofapython3
27+
{
28+
29+
class PythonMessageHandler : public sofa::helper::logging::MessageHandler
30+
{
31+
public:
32+
PythonMessageHandler() = default;
33+
void process(sofa::helper::logging::Message& m) override ;
34+
};
35+
36+
class MainPythonMessageHandler
37+
{
38+
public:
39+
static PythonMessageHandler& getInstance() ;
40+
};
41+
} // namespace sofapython3

0 commit comments

Comments
 (0)