GNU Radio Manual and C++ API Reference 3.10.3.0
The Free & Open Software Radio Ecosystem
logger.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * Copyright 2012-2013 Free Software Foundation, Inc.
4 * Copyright 2021 Marcus Müller
5 *
6 * This file is part of GNU Radio
7 *
8 * SPDX-License-Identifier: GPL-3.0-or-later
9 *
10 */
11
12#ifndef INCLUDED_GR_LOGGER_H
13#define INCLUDED_GR_LOGGER_H
14
15/*!
16 * \ingroup logging
17 * \brief GNU Radio logging wrapper
18 *
19 */
20#ifdef DISABLE_LOGGER_H
21// pygccxml as of v2.2.1 has a difficult time parsing headers that
22// include spdlog or format
23// Since it only needs the top level header info, this is a hack to not
24// transitively include anything logger related when parsing the
25// headers
26#include <memory>
27namespace gr {
28using logger_ptr = std::shared_ptr<void>;
29}
30#else
31
32// Since this file is included in *all* gr::blocks, please make sure this list of includes
33// keeps as short as possible; if anything is needed only by the implementation in
34// buffer.cc, then only include it there
35#include <gnuradio/api.h>
36#include <spdlog/common.h>
37#include <spdlog/fmt/fmt.h>
38#include <spdlog/fmt/ostr.h>
39#include <memory>
40#include <string>
41#include <type_traits>
42#include <utility>
43
44#include <spdlog/spdlog.h>
45
46#include <spdlog/sinks/dist_sink.h>
47
48#include <boost/format.hpp>
49
50namespace gr {
51using log_level = spdlog::level::level_enum;
52
54{
55public:
56 logging(logging const&) = delete; // delete copy ctor, this is a singleton class
57 void operator=(logging const&) = delete; // can't assign to singleton class
58 static logging& singleton(); //! \brief get the singleton
59
60 //! \brief get the default logging level
61 inline log_level default_level() const { return _default_level; }
62
63 //! \brief get the debug logging level
64 inline log_level debug_level() const { return _debug_level; }
65 spdlog::sink_ptr default_backend() const;
66 //! \brief adds a logging sink
67 void add_default_sink(const spdlog::sink_ptr& sink);
68 //! \brief adds a debugging sink
69 void add_debug_sink(const spdlog::sink_ptr& sink);
70 //! \brief add a default-constructed console sink to the default logger
72 //! \brief add a default-constructed console sink to the debugging logger
74
75 static constexpr const char* default_pattern = "%n :%l: %v";
76
77private:
78 logging();
79 const log_level _default_level, _debug_level;
80 std::shared_ptr<spdlog::sinks::dist_sink_mt> _default_backend, _debug_backend;
81};
82
83/*!
84 * \brief GR_LOG macros
85 * \ingroup logging
86 *
87 * These macros wrap the standard LOG4CPP_LEVEL macros. The available macros
88 * are:
89 * LOG_DEBUG
90 * LOG_INFO
91 * LOG_WARN
92 * LOG_TRACE
93 * LOG_ERROR
94 * LOG_ALERT
95 * LOG_CRIT
96 * LOG_FATAL
97 * LOG_EMERG
98 */
99
100/********************* Start Classes and Methods for Python ******************/
101/*!
102 * \brief Logger class for referencing loggers in python. Not
103 * needed in C++ (use macros) Wraps and manipulates loggers for
104 * python as python has no macros
105 * \ingroup logging
106 *
107 */
109{
110private:
111 /*! \brief pointer to logger associated with this wrapper class */
112 std::string _name;
113 using underlying_logger_ptr = std::shared_ptr<spdlog::logger>;
114
115public:
116 /*!
117 * \brief constructor Provide name of logger to associate with this class
118 * \param logger_name Name of logger associated with class
119 */
120 logger(const std::string& logger_name);
121
122 /*! \brief Destructor */
123 // FIXME implement or = default
124 ~logger() = default;
125
126 underlying_logger_ptr d_logger;
127
128 // Wrappers for logging macros
129 /*! \brief inline function, wrapper to set the logger level */
130 void set_level(const std::string& level);
131 void set_level(const log_level level);
132
133 /*! \brief inline function, wrapper to get the logger level */
134 void get_level(std::string& level) const;
135 const std::string get_string_level() const;
137
138 const std::string& name() const;
139 void set_name(const std::string& name);
140
141 /*! \brief inline function, wrapper for TRACE message */
142 template <typename... Args>
143 inline void trace(const spdlog::string_view_t& msg, const Args&... args)
144 {
145 d_logger->trace(msg, args...);
146 }
147
148 /*! \brief inline function, wrapper for DEBUG message */
149 template <typename... Args>
150 inline void debug(const spdlog::string_view_t& msg, const Args&... args)
151 {
152 d_logger->debug(msg, args...);
153 }
154
155 /*! \brief inline function, wrapper for INFO message */
156 template <typename... Args>
157 inline void info(const spdlog::string_view_t& msg, const Args&... args)
158 {
159 d_logger->info(msg, args...);
160 }
161
162 /*! \brief inline function, wrapper for INFO message, DEPRECATED */
163 template <typename... Args>
164 inline void notice(const spdlog::string_view_t& msg, const Args&... args)
165 {
166 d_logger->info(msg, args...);
167 }
168
169 /*! \brief inline function, wrapper for WARN message */
170 template <typename... Args>
171 inline void warn(const spdlog::string_view_t& msg, const Args&... args)
172 {
173 d_logger->warn(msg, args...);
174 }
175
176 /*! \brief inline function, wrapper for ERROR message */
177 template <typename... Args>
178 inline void error(const spdlog::string_view_t& msg, const Args&... args)
179 {
180 d_logger->error(msg, args...);
181 }
182
183 /*! \brief inline function, wrapper for CRITICAL message */
184 template <typename... Args>
185 inline void crit(const spdlog::string_view_t& msg, const Args&... args)
186 {
187 d_logger->critical(msg, args...);
188 }
189
190 /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
191 template <typename... Args>
192 inline void alert(const spdlog::string_view_t& msg, const Args&... args)
193 {
194 d_logger->critical(msg, args...);
195 }
196
197 /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
198 template <typename... Args>
199 inline void fatal(const spdlog::string_view_t& msg, const Args&... args)
200 {
201 d_logger->critical(msg, args...);
202 }
203
204 /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
205 template <typename... Args>
206 inline void emerg(const spdlog::string_view_t& msg, const Args&... args)
207 {
208 d_logger->critical(msg, args...);
209 }
210};
211using logger_ptr = std::shared_ptr<logger>;
212
213/*!
214 * Function to use the GR prefs files to get and setup the two
215 * default loggers defined there. The loggers are unique to the
216 * class in which they are called, and we pass it the \p name to
217 * identify where the log message originates from. For a GNU Radio
218 * block, we use 'alias()' for this value, and this is set up for us
219 * automatically in gr::block.
220 */
223
224} /* namespace gr */
225
226// global logging shorthands
227
228#define GR_LOG_TRACE(log, msg) \
229 { \
230 log->d_logger->trace(msg); \
231 }
232
233#define GR_LOG_DEBUG(log, msg) \
234 { \
235 log->d_logger->debug(msg); \
236 }
237
238#define GR_LOG_INFO(log, msg) \
239 { \
240 log->d_logger->info(msg); \
241 }
242
243#define GR_LOG_NOTICE(log, msg) \
244 { \
245 log->d_logger->info(msg); \
246 }
247
248
249#define GR_LOG_WARN(log, msg) \
250 { \
251 log->d_logger->warn(msg); \
252 }
253
254#define GR_LOG_ERROR(log, msg) \
255 { \
256 log->d_logger->error(msg); \
257 }
258
259#define GR_LOG_CRIT(log, msg) \
260 { \
261 log->d_logger->critical(msg); \
262 }
263
264#define GR_LOG_ALERT(log, msg) \
265 { \
266 log->d_logger->critical(msg); \
267 }
268
269#define GR_LOG_FATAL(log, msg) \
270 { \
271 log->d_logger->critical(msg); \
272 }
273
274#define GR_LOG_EMERG(log, msg) \
275 { \
276 log->d_logger->critical(msg); \
277 }
278
279// Helper class to allow passing of boost::format to fmt
280template <>
281struct fmt::formatter<boost::format> : formatter<string_view> {
282 // parse is inherited from formatter<string_view>.
283 template <typename FormatContext>
284 auto format(const boost::format& bfmt, FormatContext& ctx)
285 -> decltype(formatter<string_view>::format(bfmt.str(), ctx))
286 {
287 return formatter<string_view>::format(bfmt.str(), ctx);
288 }
289};
290
291namespace fmt {
292template <typename T>
293struct formatter<
294 T,
295 typename std::enable_if<
296 std::is_convertible<
297 decltype(std::declval<T>().identifier()),
298 std::string
299 >::value,
300 char
301 >::type > : fmt::formatter<std::string> {
302 template <typename FormatCtx>
303 auto format(const T& value, FormatCtx& ctx)
304 -> decltype(fmt::formatter<std::string>::format(value.identifier(), ctx))
305 {
306 return fmt::formatter<std::string>::format(value.identifier(), ctx);
307 }
308};
309template <typename T, typename Ch>
310struct formatter<std::shared_ptr<T>, Ch> : fmt::formatter<const void *, Ch> {
311 template <typename FormatCtx>
312 auto format(const std::shared_ptr<T>& ptr, FormatCtx& ctx)
313 -> decltype(fmt::formatter<const void *, Ch>::format(fmt::ptr(ptr), ctx))
314 {
315 return fmt::formatter<const void *, Ch>::format(fmt::ptr(ptr), ctx);
316 }
317};
318template <typename T>
319struct formatter<
320 std::shared_ptr<T>,
321 typename std::enable_if<
322 std::is_convertible<
323 decltype(std::declval<T>().identifier()),
324 std::string
325 >::value,
326 char
327 >::type > : fmt::formatter<std::string> {
328 template <typename FormatCtx>
329 auto format(const std::shared_ptr<T>& ptr, FormatCtx& ctx)
330 -> decltype(fmt::formatter<std::string>::format(ptr->identifier(), ctx))
331 {
332 return fmt::formatter<std::string>::format(ptr->identifier(), ctx);
333 }
334};
335}
336
337#endif
338
339#endif /* INCLUDED_GR_LOGGER_H */
GR_LOG macros.
Definition: logger.h:109
void crit(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message
Definition: logger.h:185
void set_name(const std::string &name)
void get_level(std::string &level) const
inline function, wrapper to get the logger level
void emerg(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:206
void alert(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:192
~logger()=default
Destructor.
underlying_logger_ptr d_logger
Definition: logger.h:126
void debug(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for DEBUG message
Definition: logger.h:150
void fatal(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:199
logger(const std::string &logger_name)
constructor Provide name of logger to associate with this class
void trace(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for TRACE message
Definition: logger.h:143
const std::string & name() const
void error(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for ERROR message
Definition: logger.h:178
void set_level(const log_level level)
void set_level(const std::string &level)
inline function, wrapper to set the logger level
void notice(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for INFO message, DEPRECATED
Definition: logger.h:164
log_level get_level() const
void warn(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for WARN message
Definition: logger.h:171
const std::string get_string_level() const
void info(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for INFO message
Definition: logger.h:157
Definition: logger.h:54
void add_default_sink(const spdlog::sink_ptr &sink)
adds a logging sink
spdlog::sink_ptr default_backend() const
void operator=(logging const &)=delete
void add_default_console_sink()
add a default-constructed console sink to the default logger
logging(logging const &)=delete
void add_debug_console_sink()
add a default-constructed console sink to the debugging logger
static logging & singleton()
log_level debug_level() const
get the debug logging level
Definition: logger.h:64
void add_debug_sink(const spdlog::sink_ptr &sink)
adds a debugging sink
log_level default_level() const
get the singleton
Definition: logger.h:61
#define GR_RUNTIME_API
Definition: gnuradio-runtime/include/gnuradio/api.h:18
Definition: logger.h:291
GR_RUNTIME_API const pmt::pmt_t msg()
GNU Radio logging wrapper.
Definition: basic_block.h:29
std::shared_ptr< logger > logger_ptr
Definition: logger.h:211
GR_RUNTIME_API bool configure_default_loggers(gr::logger_ptr &l, gr::logger_ptr &d, const std::string &name)
spdlog::level::level_enum log_level
Definition: logger.h:51
STL namespace.
auto format(const T &value, FormatCtx &ctx) -> decltype(fmt::formatter< std::string >::format(value.identifier(), ctx))
Definition: logger.h:303
auto format(const boost::format &bfmt, FormatContext &ctx) -> decltype(formatter< string_view >::format(bfmt.str(), ctx))
Definition: logger.h:284
auto format(const std::shared_ptr< T > &ptr, FormatCtx &ctx) -> decltype(fmt::formatter< const void *, Ch >::format(fmt::ptr(ptr), ctx))
Definition: logger.h:312
auto format(const std::shared_ptr< T > &ptr, FormatCtx &ctx) -> decltype(fmt::formatter< std::string >::format(ptr->identifier(), ctx))
Definition: logger.h:329