GNU Radio C++ API Reference  g90d26cb
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,2022 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>
27 namespace gr {
28 using 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> /* important to include before spdlog/fmt/anything.h,
37  * see https://github.com/gabime/spdlog/issues/2922 */
38 #include <spdlog/fmt/fmt.h>
39 #include <spdlog/fmt/ostr.h>
40 #include <spdlog/version.h>
41 #include <memory>
42 
43 #include <spdlog/spdlog.h>
44 
45 #include <spdlog/sinks/dist_sink.h>
46 
47 namespace gr {
48 using log_level = spdlog::level::level_enum;
49 
51 {
52 public:
53  /* \brief deleted copy constructor
54  * get your own logging system, or, more likely, use the singleton.
55  */
56  logging(logging const&) = delete;
57 
58  // \brief deleted assignment operator
59  void operator=(logging const&) = delete;
60 
61  // \brief singleton to access the one logging system
62  static logging& singleton();
63 
64  //! \brief get the default logging level
65  inline log_level default_level() const { return _default_backend->level(); }
66 
67  //! \brief get the debug logging level
68  inline log_level debug_level() const { return _debug_backend->level(); }
69 
70  //! \brief set the default logging level
72 
73  //! \brief set the debug logging level
75 
76  spdlog::sink_ptr default_backend() const;
77  //! \brief adds a logging sink
78  void add_default_sink(const spdlog::sink_ptr& sink);
79  //! \brief adds a debugging sink
80  void add_debug_sink(const spdlog::sink_ptr& sink);
81  //! \brief add a default-constructed console sink to the default logger
83  //! \brief add a default-constructed console sink to the debugging logger
85 
86  static constexpr const char* default_pattern = "%n :%l: %v";
87 
88 private:
89  logging();
90  std::shared_ptr<spdlog::sinks::dist_sink_mt> _default_backend, _debug_backend;
91 };
92 
93 /*!
94  * \brief GR_LOG macros
95  * \ingroup logging
96  *
97  * These macros wrap the standard LOG4CPP_LEVEL macros. The available macros
98  * are:
99  * LOG_DEBUG
100  * LOG_INFO
101  * LOG_WARN
102  * LOG_TRACE
103  * LOG_ERROR
104  * LOG_ALERT
105  * LOG_CRIT
106  * LOG_FATAL
107  * LOG_EMERG
108  */
109 
110 /********************* Start Classes and Methods for Python ******************/
111 /*!
112  * \brief Logger class for referencing loggers in python. Not
113  * needed in C++ (use macros) Wraps and manipulates loggers for
114  * python as python has no macros
115  * \ingroup logging
116  *
117  */
119 {
120 private:
121  /*! \brief pointer to logger associated with this wrapper class */
122  std::string _name;
123  using underlying_logger_ptr = std::shared_ptr<spdlog::logger>;
124 
125 #if SPDLOG_VERSION >= 11000
126  // spdlog 1.10 onwards can depend either on fmt or std format, so it defined
127  // its own alias for format strings
128  template <typename... Args>
129  using format_string_t = spdlog::format_string_t<Args...>;
130 #elif SPDLOG_VERSION >= 10910
131  // spdlog 1.9.1 supported/enforced fmt compile time format string validation
132  // in c++20 by using fmt::format_string in its logging functions
133  template <typename... Args>
134  using format_string_t = fmt::format_string<Args...>;
135 #else
136  // lower versions of spdlog did not support compile time validation
137  template <typename... Args>
138  using format_string_t = const spdlog::string_view_t&;
139 #endif
140 
141 public:
142  /*!
143  * \brief constructor Provide name of logger to associate with this class
144  * \param logger_name Name of logger associated with class
145  *
146  * Creates a new logger. Loggers inherit the logging level (through `gr.prefs` or
147  * through `gr::logging::singleton().set_default_level()`) that is set at the time of
148  * their creation.
149  */
150  logger(const std::string& logger_name);
151 
152  /*! \brief Destructor */
153  // FIXME implement or = default
154  ~logger() = default;
155 
156  underlying_logger_ptr d_logger;
157 
158  // Wrappers for logging macros
159  /*! \brief inline function, wrapper to set the logger level */
160  void set_level(const std::string& level);
161  void set_level(const log_level level);
162 
163  /*! \brief inline function, wrapper to get the logger level */
164  void get_level(std::string& level) const;
165  const std::string get_string_level() const;
167 
168  const std::string& name() const;
169  void set_name(const std::string& name);
170 
171  /*! \brief inline function, wrapper for TRACE message */
172  template <typename... Args>
173  inline void trace(format_string_t<Args...> msg, Args&&... args)
174  {
175  d_logger->trace(msg, std::forward<Args>(args)...);
176  }
177 
178  /*! \brief inline function, wrapper for DEBUG message */
179  template <typename... Args>
180  inline void debug(format_string_t<Args...> msg, Args&&... args)
181  {
182  d_logger->debug(msg, std::forward<Args>(args)...);
183  }
184 
185  /*! \brief inline function, wrapper for INFO message */
186  template <typename... Args>
187  inline void info(format_string_t<Args...> msg, Args&&... args)
188  {
189  d_logger->info(msg, std::forward<Args>(args)...);
190  }
191 
192  /*! \brief inline function, wrapper for INFO message, DEPRECATED */
193  template <typename... Args>
194  inline void notice(format_string_t<Args...> msg, Args&&... args)
195  {
196  d_logger->info(msg, std::forward<Args>(args)...);
197  }
198 
199  /*! \brief inline function, wrapper for WARN message */
200  template <typename... Args>
201  inline void warn(format_string_t<Args...> msg, Args&&... args)
202  {
203  d_logger->warn(msg, std::forward<Args>(args)...);
204  }
205 
206  /*! \brief inline function, wrapper for ERROR message */
207  template <typename... Args>
208  inline void error(format_string_t<Args...> msg, Args&&... args)
209  {
210  d_logger->error(msg, std::forward<Args>(args)...);
211  }
212 
213  /*! \brief inline function, wrapper for CRITICAL message */
214  template <typename... Args>
215  inline void crit(format_string_t<Args...> msg, Args&&... args)
216  {
217  d_logger->critical(msg, std::forward<Args>(args)...);
218  }
219 
220  /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
221  template <typename... Args>
222  inline void alert(format_string_t<Args...> msg, Args&&... args)
223  {
224  d_logger->critical(msg, std::forward<Args>(args)...);
225  }
226 
227  /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
228  template <typename... Args>
229  inline void fatal(format_string_t<Args...> msg, Args&&... args)
230  {
231  d_logger->critical(msg, std::forward<Args>(args)...);
232  }
233 
234  /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
235  template <typename... Args>
236  inline void emerg(format_string_t<Args...> msg, Args&&... args)
237  {
238  d_logger->critical(msg, std::forward<Args>(args)...);
239  }
240  /*! \brief inline function, wrapper for logging with ad-hoc adjustable level*/
241  template <typename... Args>
242  inline void
243  log(spdlog::level::level_enum level, format_string_t<Args...> msg, Args&&... args)
244  {
245  d_logger->log(level, msg, std::forward<Args>(args)...);
246  }
247 };
248 using logger_ptr = std::shared_ptr<logger>;
249 
250 /*!
251  * Function to use the GR prefs files to get and setup the two
252  * default loggers defined there. The loggers are unique to the
253  * class in which they are called, and we pass it the \p name to
254  * identify where the log message originates from. For a GNU Radio
255  * block, we use 'alias()' for this value, and this is set up for us
256  * automatically in gr::block.
257  */
258 GR_RUNTIME_API bool
259 configure_default_loggers(gr::logger_ptr& l, gr::logger_ptr& d, const std::string& name);
260 
261 } /* namespace gr */
262 
263 // global logging shorthands
264 
265 #define GR_LOG_TRACE(log, msg) \
266  { \
267  log->d_logger->trace(msg); \
268  }
269 
270 #define GR_LOG_DEBUG(log, msg) \
271  { \
272  log->d_logger->debug(msg); \
273  }
274 
275 #define GR_LOG_INFO(log, msg) \
276  { \
277  log->d_logger->info(msg); \
278  }
279 
280 #define GR_LOG_NOTICE(log, msg) \
281  { \
282  log->d_logger->info(msg); \
283  }
284 
285 
286 #define GR_LOG_WARN(log, msg) \
287  { \
288  log->d_logger->warn(msg); \
289  }
290 
291 #define GR_LOG_ERROR(log, msg) \
292  { \
293  log->d_logger->error(msg); \
294  }
295 
296 #define GR_LOG_CRIT(log, msg) \
297  { \
298  log->d_logger->critical(msg); \
299  }
300 
301 #define GR_LOG_ALERT(log, msg) \
302  { \
303  log->d_logger->critical(msg); \
304  }
305 
306 #define GR_LOG_FATAL(log, msg) \
307  { \
308  log->d_logger->critical(msg); \
309  }
310 
311 #define GR_LOG_EMERG(log, msg) \
312  { \
313  log->d_logger->critical(msg); \
314  }
315 
316 #endif
317 
318 #endif /* INCLUDED_GR_LOGGER_H */
GR_LOG macros.
Definition: logger.h:119
void alert(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:222
void set_name(const std::string &name)
const std::string & name() const
void get_level(std::string &level) const
inline function, wrapper to get the logger level
void error(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for ERROR message
Definition: logger.h:208
void trace(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for TRACE message
Definition: logger.h:173
void log(spdlog::level::level_enum level, format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for logging with ad-hoc adjustable level
Definition: logger.h:243
~logger()=default
Destructor.
underlying_logger_ptr d_logger
Definition: logger.h:156
void crit(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message
Definition: logger.h:215
void info(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for INFO message
Definition: logger.h:187
void debug(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for DEBUG message
Definition: logger.h:180
logger(const std::string &logger_name)
constructor Provide name of logger to associate with this class
void set_level(const log_level level)
void notice(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for INFO message, DEPRECATED
Definition: logger.h:194
void set_level(const std::string &level)
inline function, wrapper to set the logger level
void fatal(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:229
void emerg(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:236
log_level get_level() const
const std::string get_string_level() const
void warn(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for WARN message
Definition: logger.h:201
Definition: logger.h:51
void set_default_level(log_level level)
set the default logging level
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
void set_debug_level(log_level level)
set the debug logging level
log_level debug_level() const
get the debug logging level
Definition: logger.h:68
static logging & singleton()
void add_debug_sink(const spdlog::sink_ptr &sink)
adds a debugging sink
log_level default_level() const
get the default logging level
Definition: logger.h:65
#define GR_RUNTIME_API
Definition: gnuradio-runtime/include/gnuradio/api.h:18
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:248
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:48