GNU Radio Manual and C++ API Reference  3.10.2.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>
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 <memory>
40 
41 #include <spdlog/spdlog.h>
42 
43 #include <spdlog/sinks/dist_sink.h>
44 
45 #include <boost/format.hpp>
46 
47 namespace gr {
48 using log_level = spdlog::level::level_enum;
49 
51 {
52 public:
53  logging(logging const&) = delete; // delete copy ctor, this is a singleton class
54  void operator=(logging const&) = delete; // can't assign to singleton class
55  static logging& singleton(); //! \brief get the singleton
56 
57  //! \brief get the default logging level
58  inline log_level default_level() const { return _default_level; }
59 
60  //! \brief get the debug logging level
61  inline log_level debug_level() const { return _debug_level; }
62  spdlog::sink_ptr default_backend() const;
63  //! \brief adds a logging sink
64  void add_default_sink(const spdlog::sink_ptr& sink);
65  //! \brief adds a debugging sink
66  void add_debug_sink(const spdlog::sink_ptr& sink);
67  //! \brief add a default-constructed console sink to the default logger
69  //! \brief add a default-constructed console sink to the debugging logger
71 
72  static constexpr const char* default_pattern = "%n :%l: %v";
73 
74 private:
75  logging();
76  const log_level _default_level, _debug_level;
77  std::shared_ptr<spdlog::sinks::dist_sink_mt> _default_backend, _debug_backend;
78 };
79 
80 /*!
81  * \brief GR_LOG macros
82  * \ingroup logging
83  *
84  * These macros wrap the standard LOG4CPP_LEVEL macros. The available macros
85  * are:
86  * LOG_DEBUG
87  * LOG_INFO
88  * LOG_WARN
89  * LOG_TRACE
90  * LOG_ERROR
91  * LOG_ALERT
92  * LOG_CRIT
93  * LOG_FATAL
94  * LOG_EMERG
95  */
96 
97 /********************* Start Classes and Methods for Python ******************/
98 /*!
99  * \brief Logger class for referencing loggers in python. Not
100  * needed in C++ (use macros) Wraps and manipulates loggers for
101  * python as python has no macros
102  * \ingroup logging
103  *
104  */
106 {
107 private:
108  /*! \brief pointer to logger associated with this wrapper class */
109  std::string _name;
110  using underlying_logger_ptr = std::shared_ptr<spdlog::logger>;
111 
112 public:
113  /*!
114  * \brief constructor Provide name of logger to associate with this class
115  * \param logger_name Name of logger associated with class
116  */
117  logger(const std::string& logger_name);
118 
119  /*! \brief Destructor */
120  // FIXME implement or = default
121  ~logger() = default;
122 
123  underlying_logger_ptr d_logger;
124 
125  // Wrappers for logging macros
126  /*! \brief inline function, wrapper to set the logger level */
127  void set_level(const std::string& level);
128  void set_level(const log_level level);
129 
130  /*! \brief inline function, wrapper to get the logger level */
131  void get_level(std::string& level) const;
132  const std::string get_string_level() const;
134 
135  const std::string& name() const;
136  void set_name(const std::string& name);
137 
138  /*! \brief inline function, wrapper for TRACE message */
139  template <typename... Args>
140  inline void trace(const spdlog::string_view_t& msg, const Args&... args)
141  {
142  d_logger->trace(msg, args...);
143  }
144 
145  /*! \brief inline function, wrapper for DEBUG message */
146  template <typename... Args>
147  inline void debug(const spdlog::string_view_t& msg, const Args&... args)
148  {
149  d_logger->debug(msg, args...);
150  }
151 
152  /*! \brief inline function, wrapper for INFO message */
153  template <typename... Args>
154  inline void info(const spdlog::string_view_t& msg, const Args&... args)
155  {
156  d_logger->info(msg, args...);
157  }
158 
159  /*! \brief inline function, wrapper for INFO message, DEPRECATED */
160  template <typename... Args>
161  inline void notice(const spdlog::string_view_t& msg, const Args&... args)
162  {
163  d_logger->info(msg, args...);
164  }
165 
166  /*! \brief inline function, wrapper for WARN message */
167  template <typename... Args>
168  inline void warn(const spdlog::string_view_t& msg, const Args&... args)
169  {
170  d_logger->warn(msg, args...);
171  }
172 
173  /*! \brief inline function, wrapper for ERROR message */
174  template <typename... Args>
175  inline void error(const spdlog::string_view_t& msg, const Args&... args)
176  {
177  d_logger->error(msg, args...);
178  }
179 
180  /*! \brief inline function, wrapper for CRITICAL message */
181  template <typename... Args>
182  inline void crit(const spdlog::string_view_t& msg, const Args&... args)
183  {
184  d_logger->critical(msg, args...);
185  }
186 
187  /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
188  template <typename... Args>
189  inline void alert(const spdlog::string_view_t& msg, const Args&... args)
190  {
191  d_logger->critical(msg, args...);
192  }
193 
194  /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
195  template <typename... Args>
196  inline void fatal(const spdlog::string_view_t& msg, const Args&... args)
197  {
198  d_logger->critical(msg, args...);
199  }
200 
201  /*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
202  template <typename... Args>
203  inline void emerg(const spdlog::string_view_t& msg, const Args&... args)
204  {
205  d_logger->critical(msg, args...);
206  }
207 };
208 using logger_ptr = std::shared_ptr<logger>;
209 
210 /*!
211  * Function to use the GR prefs files to get and setup the two
212  * default loggers defined there. The loggers are unique to the
213  * class in which they are called, and we pass it the \p name to
214  * identify where the log message originates from. For a GNU Radio
215  * block, we use 'alias()' for this value, and this is set up for us
216  * automatically in gr::block.
217  */
218 GR_RUNTIME_API bool
219 configure_default_loggers(gr::logger_ptr& l, gr::logger_ptr& d, const std::string& name);
220 
221 } /* namespace gr */
222 
223 // global logging shorthands
224 
225 #define GR_LOG_TRACE(log, msg) \
226  { \
227  log->d_logger->trace(msg); \
228  }
229 
230 #define GR_LOG_DEBUG(log, msg) \
231  { \
232  log->d_logger->debug(msg); \
233  }
234 
235 #define GR_LOG_INFO(log, msg) \
236  { \
237  log->d_logger->info(msg); \
238  }
239 
240 #define GR_LOG_NOTICE(log, msg) \
241  { \
242  log->d_logger->info(msg); \
243  }
244 
245 
246 #define GR_LOG_WARN(log, msg) \
247  { \
248  log->d_logger->warn(msg); \
249  }
250 
251 #define GR_LOG_ERROR(log, msg) \
252  { \
253  log->d_logger->error(msg); \
254  }
255 
256 #define GR_LOG_CRIT(log, msg) \
257  { \
258  log->d_logger->critical(msg); \
259  }
260 
261 #define GR_LOG_ALERT(log, msg) \
262  { \
263  log->d_logger->critical(msg); \
264  }
265 
266 #define GR_LOG_FATAL(log, msg) \
267  { \
268  log->d_logger->critical(msg); \
269  }
270 
271 #define GR_LOG_EMERG(log, msg) \
272  { \
273  log->d_logger->critical(msg); \
274  }
275 
276 // Helper class to allow passing of boost::format to fmt
277 template <>
278 struct fmt::formatter<boost::format> : formatter<string_view> {
279  // parse is inherited from formatter<string_view>.
280  template <typename FormatContext>
281  auto format(const boost::format& bfmt, FormatContext& ctx)
282  -> decltype(formatter<string_view>::format(bfmt.str(), ctx))
283  {
284  return formatter<string_view>::format(bfmt.str(), ctx);
285  }
286 };
287 
288 #endif
289 
290 #endif /* INCLUDED_GR_LOGGER_H */
GR_LOG macros.
Definition: logger.h:106
void crit(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message
Definition: logger.h:182
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 emerg(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:203
void alert(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:189
~logger()=default
Destructor.
underlying_logger_ptr d_logger
Definition: logger.h:123
void debug(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for DEBUG message
Definition: logger.h:147
void fatal(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition: logger.h:196
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:140
void error(const spdlog::string_view_t &msg, const Args &... args)
inline function, wrapper for ERROR message
Definition: logger.h:175
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:161
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:168
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:154
Definition: logger.h:51
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
log_level debug_level() const
get the debug logging level
Definition: logger.h:61
static logging & singleton()
void add_debug_sink(const spdlog::sink_ptr &sink)
adds a debugging sink
log_level default_level() const
get the singleton
Definition: logger.h:58
#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:208
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
auto format(const boost::format &bfmt, FormatContext &ctx) -> decltype(formatter< string_view >::format(bfmt.str(), ctx))
Definition: logger.h:281