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