HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
log.cpp
Go to the documentation of this file.
2 
4 
5 #include <iostream>
6 
7 namespace hal
8 {
9  namespace
10  {
19  std::string python_caller_location()
20  {
21  try
22  {
23  py::object frame = py::module_::import("sys").attr("_getframe")();
24  const auto file = py::cast<std::string>(frame.attr("f_code").attr("co_filename"));
25  const auto line = py::cast<int>(frame.attr("f_lineno"));
26  return "[" + file + ":" + std::to_string(line) + "] ";
27  }
28  catch (const py::error_already_set&)
29  {
30  return std::string();
31  }
32  }
33 
34  void log_message(spdlog::level::level_enum level, const std::string& channel, const std::string& message, bool with_location)
35  {
36  const std::string text = with_location ? python_caller_location() + message : message;
37  LogManager::get_instance()->get_channel(channel)->log(level, text);
38  }
39  } // namespace
40 
42  {
43  // The python counterparts of the C++ log_* macros. They keep the C++ argument order
44  // (channel first) and, like the macros, prefix every severity but 'info' with the source
45  // location of the caller.
46  m.def(
47  "log_trace",
48  [](const std::string& channel, const std::string& message) { log_message(spdlog::level::trace, channel, message, true); },
49  py::arg("channel"),
50  py::arg("message"),
51  R"(
52  Log a message into a specific channel with severity ``trace``.
53  The message is prefixed with the file name and line number of the calling python code.
54 
55  :param str channel: The log channel's name.
56  :param str message: The message to log.
57  )");
58 
59  m.def(
60  "log_debug",
61  [](const std::string& channel, const std::string& message) { log_message(spdlog::level::debug, channel, message, true); },
62  py::arg("channel"),
63  py::arg("message"),
64  R"(
65  Log a message into a specific channel with severity ``debug``.
66  The message is prefixed with the file name and line number of the calling python code.
67 
68  :param str channel: The log channel's name.
69  :param str message: The message to log.
70  )");
71 
72  m.def(
73  "log_info",
74  [](const std::string& channel, const std::string& message) { log_message(spdlog::level::info, channel, message, false); },
75  py::arg("channel"),
76  py::arg("message"),
77  R"(
78  Log a message into a specific channel with severity ``info``.
79 
80  :param str channel: The log channel's name.
81  :param str message: The message to log.
82  )");
83 
84  m.def(
85  "log_warning",
86  [](const std::string& channel, const std::string& message) { log_message(spdlog::level::warn, channel, message, true); },
87  py::arg("channel"),
88  py::arg("message"),
89  R"(
90  Log a message into a specific channel with severity ``warning``.
91  The message is prefixed with the file name and line number of the calling python code.
92 
93  :param str channel: The log channel's name.
94  :param str message: The message to log.
95  )");
96 
97  m.def(
98  "log_error",
99  [](const std::string& channel, const std::string& message) { log_message(spdlog::level::err, channel, message, true); },
100  py::arg("channel"),
101  py::arg("message"),
102  R"(
103  Log a message into a specific channel with severity ``error``.
104  The message is prefixed with the file name and line number of the calling python code.
105 
106  :param str channel: The log channel's name.
107  :param str message: The message to log.
108  )");
109 
110  m.def(
111  "log_critical",
112  [](const std::string& channel, const std::string& message) { log_message(spdlog::level::critical, channel, message, true); },
113  py::arg("channel"),
114  py::arg("message"),
115  R"(
116  Log a message into a specific channel with severity ``critical``.
117  The message is prefixed with the file name and line number of the calling python code.
118 
119  :param str channel: The log channel's name.
120  :param str message: The message to log.
121  )");
122 
123  auto log_manager = py::class_<LogManager, RawPtrWrapper<LogManager>>(m, "LogManager", R"(
124  The log manager takes care of the log channels of HAL and the sinks (e.g., stdout, log file, GUI) that they write to.
125  )");
126 
127  log_manager.def(py::init([]() {
129  return RawPtrWrapper<LogManager>(lm);
130  }));
131 
132  log_manager.def("set_file_name", &LogManager::set_file_name, py::arg("file_name") = "", R"(
133  Set the log file name.
134  If file_name is empty, the default log file will be used.
135 
136  :param str file_name: The desired log file.
137  )");
138 
139  log_manager.def("set_level_of_channel", &LogManager::set_level_of_channel, py::arg("channel_name"), py::arg("level"), R"(
140  Set a channel's severity level.
141 
142  :param str channel_name: Name of the channel.
143  :param str level: The severity level.
144  )");
145 
146  log_manager.def_static(
147  "get_channel", [](std::string channel_name) { LogManager::get_instance()->get_channel(channel_name); }, py::arg("channel_name"), R"(
148  Ensure that a channel with the given name exists, creating it if it does not exist yet.
149  Note that, unlike its C++ counterpart, this does not return the channel itself.
150 
151  :param str channel_name: Name of the channel.
152  )");
153 
154  log_manager.def("get_channels", &LogManager::get_channels, R"(
155  Returns all channels' names.
156 
157  :returns: A set of channel names.
158  :rtype: set[str]
159  )");
160 
161  log_manager.def("get_available_log_levels", &LogManager::get_available_log_levels, R"(
162  Get all available severity levels.
163 
164  :returns: A set of severity levels.
165  :rtype: set[str]
166  )");
167 
168  log_manager.def("activate_channel", &LogManager::activate_channel, py::arg("channel_name"), R"(
169  Activate a channel.
170  By default all channels are active.
171 
172  :param str channel_name: The name of the channel.
173  )");
174 
175  log_manager.def("activate_all_channels", &LogManager::activate_all_channels, R"(
176  Activate all logging channels.
177  )");
178 
179  log_manager.def("deactivate_channel", &LogManager::deactivate_channel, py::arg("channel_name"), R"(
180  Deactivate a channel suppressing all output.
181 
182  :param str channel_name: The name of the channel.
183  )");
184 
185  log_manager.def("deactivate_all_channels", &LogManager::deactivate_all_channels, R"(
186  Deactivate all logging channels.
187  )");
188 
189  log_manager.def("get_default_sinks", &LogManager::get_default_sinks, R"(
190  Get the list of default sinks that are added to each newly created logger by default.
191 
192  :returns: The default sinks.
193  :rtype: list[hal_py.log_sink]
194  )");
195 
196  log_manager.def("remove_sink_from_default", &LogManager::remove_sink_from_default, py::arg("sink_type"), R"(
197  Remove the specified sink type from the list of default sinks if present.
198 
199  :param str sink_type: The type of sink to remove from default sinks.
200  )");
201 
202  auto log_sink = py::class_<LogManager::log_sink, RawPtrWrapper<LogManager::log_sink>>(log_manager, "log_sink");
203 
204  log_sink.def_readonly("sink_type", &LogManager::log_sink::sink_type, R"(
205  The type of the sink.
206 
207  :type: str
208  )");
209 
210  log_sink.def_readonly("is_file_sink", &LogManager::log_sink::is_file_sink, R"(
211  Boolean indication whether sink is a file sink.
212 
213  :type: bool
214  )");
215 
216  log_sink.def_readonly("truncate", &LogManager::log_sink::truncate, R"(
217  Truncate option passed to sink.
218 
219  :type: bool
220  )");
221 
222  log_sink.def_readonly("path", &LogManager::log_sink::path, R"(
223  The file path incase the sink is a file sink.
224 
225  :type: pathlib.Path
226  )");
227  }
228 } // namespace hal
void set_level_of_channel(const std::string &channel_name, const std::string &level)
Definition: log.cpp:164
void activate_channel(const std::string &channel_name)
Definition: log.cpp:178
void deactivate_all_channels()
Definition: log.cpp:196
void deactivate_channel(const std::string &channel_name)
Definition: log.cpp:191
void activate_all_channels()
Definition: log.cpp:183
std::vector< std::shared_ptr< hal::LogManager::log_sink > > get_default_sinks()
Definition: log.cpp:204
std::set< std::string > get_channels() const
Definition: log.cpp:90
std::shared_ptr< spdlog::logger > get_channel(const std::string &channel_name="stdout")
Definition: log.cpp:75
void remove_sink_from_default(const std::string &sink_type)
Definition: log.cpp:209
static LogManager * get_instance(const std::filesystem::path &file_name="")
Definition: log.cpp:61
std::set< std::string > get_available_log_levels() const
Definition: log.cpp:283
void set_file_name(const std::filesystem::path &file_name)
Definition: log.cpp:291
std::unique_ptr< T, py::nodelete > RawPtrWrapper
void log_init(py::module &m)
Definition: log.cpp:41
const Module * module(const Gate *g, const NodeBoxes &boxes)
Definition: defines.h:45
std::string sink_type
Definition: log.h:115
std::filesystem::path path
Definition: log.h:118