Loading...
Searching...
No Matches
logger.h
Go to the documentation of this file.
/* -*- c++ -*- */
/*
* Copyright 2012-2013 Free Software Foundation, Inc.
* Copyright 2021,2022 Marcus Müller
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef INCLUDED_GR_LOGGER_H
#define INCLUDED_GR_LOGGER_H
/*!
* \ingroup logging
* \brief GNU Radio logging wrapper
*
*/
#ifdef DISABLE_LOGGER_H
// pygccxml as of v2.2.1 has a difficult time parsing headers that
// include spdlog or format
// Since it only needs the top level header info, this is a hack to not
// transitively include anything logger related when parsing the
// headers
#include <memory>
namespace gr {
using logger_ptr = std::shared_ptr<void>;
}
#else
// Since this file is included in *all* gr::blocks, please make sure this list of includes
// keeps as short as possible; if anything is needed only by the implementation in
// buffer.cc, then only include it there
#include <gnuradio/api.h>
#include <spdlog/common.h> /* important to include before spdlog/fmt/anything.h,
* see https://github.com/gabime/spdlog/issues/2922 */
#include <spdlog/fmt/fmt.h>
#include <spdlog/fmt/ostr.h>
#include <spdlog/version.h>
#include <memory>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/dist_sink.h>
#include <boost/format.hpp>
namespace gr {
using log_level = spdlog::level::level_enum;
class GR_RUNTIME_API logging
{
public:
/* \brief deleted copy constructor
* get your own logging system, or, more likely, use the singleton.
*/
logging(logging const&) = delete;
// \brief deleted assignment operator
void operator=(logging const&) = delete;
// \brief singleton to access the one logging system
static logging& singleton();
//! \brief get the default logging level
inline log_level default_level() const { return _default_backend->level(); }
//! \brief get the debug logging level
inline log_level debug_level() const { return _debug_backend->level(); }
//! \brief set the default logging level
void set_default_level(log_level level);
//! \brief set the debug logging level
void set_debug_level(log_level level);
spdlog::sink_ptr default_backend() const;
//! \brief adds a logging sink
void add_default_sink(const spdlog::sink_ptr& sink);
//! \brief adds a debugging sink
void add_debug_sink(const spdlog::sink_ptr& sink);
//! \brief add a default-constructed console sink to the default logger
void add_default_console_sink();
//! \brief add a default-constructed console sink to the debugging logger
void add_debug_console_sink();
static constexpr const char* default_pattern = "%n :%l: %v";
private:
logging();
std::shared_ptr<spdlog::sinks::dist_sink_mt> _default_backend, _debug_backend;
};
/*!
* \brief GR_LOG macros
* \ingroup logging
*
* These macros wrap the standard LOG4CPP_LEVEL macros. The available macros
* are:
* LOG_DEBUG
* LOG_INFO
* LOG_WARN
* LOG_TRACE
* LOG_ERROR
* LOG_ALERT
* LOG_CRIT
* LOG_FATAL
* LOG_EMERG
*/
/********************* Start Classes and Methods for Python ******************/
/*!
* \brief Logger class for referencing loggers in python. Not
* needed in C++ (use macros) Wraps and manipulates loggers for
* python as python has no macros
* \ingroup logging
*
*/
class GR_RUNTIME_API logger
{
private:
/*! \brief pointer to logger associated with this wrapper class */
std::string _name;
using underlying_logger_ptr = std::shared_ptr<spdlog::logger>;
#if SPDLOG_VERSION >= 11000
// spdlog 1.10 onwards can depend either on fmt or std format, so it defined
// its own alias for format strings
template <typename... Args>
using format_string_t = spdlog::format_string_t<Args...>;
#elif SPDLOG_VERSION >= 10910
// spdlog 1.9.1 supported/enforced fmt compile time format string validation
// in c++20 by using fmt::format_string in its logging functions
template <typename... Args>
using format_string_t = fmt::format_string<Args...>;
#else
// lower versions of spdlog did not support compile time validation
template <typename... Args>
using format_string_t = const spdlog::string_view_t&;
#endif
public:
/*!
* \brief constructor Provide name of logger to associate with this class
* \param logger_name Name of logger associated with class
*
* Creates a new logger. Loggers inherit the logging level (through `gr.prefs` or
* through `gr::logging::singleton().set_default_level()`) that is set at the time of
* their creation.
*/
logger(const std::string& logger_name);
/*! \brief Destructor */
// FIXME implement or = default
~logger() = default;
underlying_logger_ptr d_logger;
// Wrappers for logging macros
/*! \brief inline function, wrapper to set the logger level */
void set_level(const std::string& level);
void set_level(const log_level level);
/*! \brief inline function, wrapper to get the logger level */
void get_level(std::string& level) const;
const std::string get_string_level() const;
log_level get_level() const;
const std::string& name() const;
void set_name(const std::string& name);
/*! \brief inline function, wrapper for TRACE message */
template <typename... Args>
inline void trace(format_string_t<Args...> msg, Args&&... args)
{
d_logger->trace(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for DEBUG message */
template <typename... Args>
inline void debug(format_string_t<Args...> msg, Args&&... args)
{
d_logger->debug(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for INFO message */
template <typename... Args>
inline void info(format_string_t<Args...> msg, Args&&... args)
{
d_logger->info(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for INFO message, DEPRECATED */
template <typename... Args>
inline void notice(format_string_t<Args...> msg, Args&&... args)
{
d_logger->info(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for WARN message */
template <typename... Args>
inline void warn(format_string_t<Args...> msg, Args&&... args)
{
d_logger->warn(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for ERROR message */
template <typename... Args>
inline void error(format_string_t<Args...> msg, Args&&... args)
{
d_logger->error(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for CRITICAL message */
template <typename... Args>
inline void crit(format_string_t<Args...> msg, Args&&... args)
{
d_logger->critical(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
template <typename... Args>
inline void alert(format_string_t<Args...> msg, Args&&... args)
{
d_logger->critical(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
template <typename... Args>
inline void fatal(format_string_t<Args...> msg, Args&&... args)
{
d_logger->critical(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for CRITICAL message, DEPRECATED */
template <typename... Args>
inline void emerg(format_string_t<Args...> msg, Args&&... args)
{
d_logger->critical(msg, std::forward<Args>(args)...);
}
/*! \brief inline function, wrapper for logging with ad-hoc adjustable level*/
template <typename... Args>
inline void
log(spdlog::level::level_enum level, format_string_t<Args...> msg, Args&&... args)
{
d_logger->log(level, msg, std::forward<Args>(args)...);
}
};
using logger_ptr = std::shared_ptr<logger>;
/*!
* Function to use the GR prefs files to get and setup the two
* default loggers defined there. The loggers are unique to the
* class in which they are called, and we pass it the \p name to
* identify where the log message originates from. For a GNU Radio
* block, we use 'alias()' for this value, and this is set up for us
* automatically in gr::block.
*/
GR_RUNTIME_API bool
configure_default_loggers(gr::logger_ptr& l, gr::logger_ptr& d, const std::string& name);
} /* namespace gr */
// global logging shorthands
#define GR_LOG_TRACE(log, msg) \
{ \
log->d_logger->trace(msg); \
}
#define GR_LOG_DEBUG(log, msg) \
{ \
log->d_logger->debug(msg); \
}
#define GR_LOG_INFO(log, msg) \
{ \
log->d_logger->info(msg); \
}
#define GR_LOG_NOTICE(log, msg) \
{ \
log->d_logger->info(msg); \
}
#define GR_LOG_WARN(log, msg) \
{ \
log->d_logger->warn(msg); \
}
#define GR_LOG_ERROR(log, msg) \
{ \
log->d_logger->error(msg); \
}
#define GR_LOG_CRIT(log, msg) \
{ \
log->d_logger->critical(msg); \
}
#define GR_LOG_ALERT(log, msg) \
{ \
log->d_logger->critical(msg); \
}
#define GR_LOG_FATAL(log, msg) \
{ \
log->d_logger->critical(msg); \
}
#define GR_LOG_EMERG(log, msg) \
{ \
log->d_logger->critical(msg); \
}
// Helper class to allow passing of boost::format to fmt
template <>
struct fmt::formatter<boost::format> : formatter<string_view> {
// parse is inherited from formatter<string_view>.
template <typename FormatContext>
auto format(const boost::format& bfmt, FormatContext& ctx)
-> decltype(formatter<string_view>::format(bfmt.str(), ctx))
{
return formatter<string_view>::format(bfmt.str(), ctx);
}
};
#endif
#endif /* INCLUDED_GR_LOGGER_H */
gr::logger::alert
void alert(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition logger.h:224
gr::logger::set_name
void set_name(const std::string &name)
gr::logger::get_level
void get_level(std::string &level) const
inline function, wrapper to get the logger level
gr::logger::error
void error(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for ERROR message
Definition logger.h:210
gr::logger::trace
void trace(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for TRACE message
Definition logger.h:175
gr::logger::log
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:245
gr::logger::~logger
~logger()=default
Destructor.
gr::logger::d_logger
underlying_logger_ptr d_logger
Definition logger.h:158
gr::logger::crit
void crit(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message
Definition logger.h:217
gr::logger::info
void info(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for INFO message
Definition logger.h:189
gr::logger::debug
void debug(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for DEBUG message
Definition logger.h:182
gr::logger::logger
logger(const std::string &logger_name)
constructor Provide name of logger to associate with this class
gr::logger::name
const std::string & name() const
gr::logger::set_level
void set_level(const log_level level)
gr::logger::notice
void notice(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for INFO message, DEPRECATED
Definition logger.h:196
gr::logger::set_level
void set_level(const std::string &level)
inline function, wrapper to set the logger level
gr::logger::fatal
void fatal(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition logger.h:231
gr::logger::emerg
void emerg(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for CRITICAL message, DEPRECATED
Definition logger.h:238
gr::logger::get_level
log_level get_level() const
gr::logger::get_string_level
const std::string get_string_level() const
gr::logger::warn
void warn(format_string_t< Args... > msg, Args &&... args)
inline function, wrapper for WARN message
Definition logger.h:203
gr::logging::set_default_level
void set_default_level(log_level level)
set the default logging level
gr::logging::add_default_sink
void add_default_sink(const spdlog::sink_ptr &sink)
adds a logging sink
gr::logging::default_pattern
static constexpr const char * default_pattern
Definition logger.h:88
gr::logging::default_backend
spdlog::sink_ptr default_backend() const
gr::logging::operator=
void operator=(logging const &)=delete
gr::logging::add_default_console_sink
void add_default_console_sink()
add a default-constructed console sink to the default logger
gr::logging::logging
logging(logging const &)=delete
gr::logging::add_debug_console_sink
void add_debug_console_sink()
add a default-constructed console sink to the debugging logger
gr::logging::singleton
static logging & singleton()
gr::logging::set_debug_level
void set_debug_level(log_level level)
set the debug logging level
gr::logging::debug_level
log_level debug_level() const
get the debug logging level
Definition logger.h:70
gr::logging::add_debug_sink
void add_debug_sink(const spdlog::sink_ptr &sink)
adds a debugging sink
gr::logging::default_level
log_level default_level() const
get the default logging level
Definition logger.h:67
api.h
GR_RUNTIME_API
#define GR_RUNTIME_API
Definition gnuradio-runtime/include/gnuradio/api.h:18
gr
GNU Radio logging wrapper.
Definition basic_block.h:29
gr::logger_ptr
std::shared_ptr< logger > logger_ptr
Definition logger.h:250
gr::configure_default_loggers
GR_RUNTIME_API bool configure_default_loggers(gr::logger_ptr &l, gr::logger_ptr &d, const std::string &name)
gr::log_level
spdlog::level::level_enum log_level
Definition logger.h:50
fmt::formatter< boost::format >::format
auto format(const boost::format &bfmt, FormatContext &ctx) -> decltype(formatter< string_view >::format(bfmt.str(), ctx))
Definition logger.h:323