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