Add SPDLOG_LOGGER_NOEXCEPT define as option

Closes #2985.
pull/2986/head
Kerling Philipp (MTN PTT) 2 years ago
parent 444d5153b7
commit b20b28ef1f

@ -70,6 +70,12 @@
#define SPDLOG_CONSTEXPR constexpr
#endif
#ifdef SPDLOG_LOGGER_NOEXCEPT
#define SPDLOG_COND_NOEXCEPT SPDLOG_NOEXCEPT
#else
#define SPDLOG_COND_NOEXCEPT
#endif
// If building with std::format, can just use constexpr, otherwise if building with fmt
// SPDLOG_CONSTEXPR_FUNC needs to be set the same as FMT_CONSTEXPR to avoid situations where
// a constexpr function in spdlog could end up calling a non-constexpr function in fmt

@ -76,17 +76,20 @@ public:
void swap(spdlog::logger &other) SPDLOG_NOEXCEPT;
template <typename... Args>
void log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
void log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
SPDLOG_COND_NOEXCEPT {
log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
}
template <typename... Args>
void log(level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
void log(level::level_enum lvl,
format_string_t<Args...> fmt,
Args &&...args) SPDLOG_COND_NOEXCEPT {
log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
}
template <typename T>
void log(level::level_enum lvl, const T &msg) {
void log(level::level_enum lvl, const T &msg) SPDLOG_COND_NOEXCEPT {
log(source_loc{}, lvl, msg);
}
@ -94,14 +97,14 @@ public:
template <class T,
typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value,
int>::type = 0>
void log(source_loc loc, level::level_enum lvl, const T &msg) {
void log(source_loc loc, level::level_enum lvl, const T &msg) SPDLOG_COND_NOEXCEPT {
log(loc, lvl, "{}", msg);
}
void log(log_clock::time_point log_time,
source_loc loc,
level::level_enum lvl,
string_view_t msg) {
string_view_t msg) SPDLOG_COND_NOEXCEPT {
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled) {
@ -112,7 +115,7 @@ public:
log_it_(log_msg, log_enabled, traceback_enabled);
}
void log(source_loc loc, level::level_enum lvl, string_view_t msg) {
void log(source_loc loc, level::level_enum lvl, string_view_t msg) SPDLOG_COND_NOEXCEPT {
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled) {
@ -123,53 +126,58 @@ public:
log_it_(log_msg, log_enabled, traceback_enabled);
}
void log(level::level_enum lvl, string_view_t msg) { log(source_loc{}, lvl, msg); }
void log(level::level_enum lvl, string_view_t msg) SPDLOG_COND_NOEXCEPT {
log(source_loc{}, lvl, msg);
}
template <typename... Args>
void trace(format_string_t<Args...> fmt, Args &&...args) {
void trace(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::trace, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void debug(format_string_t<Args...> fmt, Args &&...args) {
void debug(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::debug, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void info(format_string_t<Args...> fmt, Args &&...args) {
void info(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::info, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void warn(format_string_t<Args...> fmt, Args &&...args) {
void warn(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::warn, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void error(format_string_t<Args...> fmt, Args &&...args) {
void error(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::err, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void critical(format_string_t<Args...> fmt, Args &&...args) {
void critical(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::critical, fmt, std::forward<Args>(args)...);
}
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
template <typename... Args>
void log(source_loc loc, level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
void log(source_loc loc, level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args)
SPDLOG_COND_NOEXCEPT {
log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
}
template <typename... Args>
void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
void log(level::level_enum lvl,
wformat_string_t<Args...> fmt,
Args &&...args) SPDLOG_COND_NOEXCEPT {
log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
}
void log(log_clock::time_point log_time,
source_loc loc,
level::level_enum lvl,
wstring_view_t msg) {
wstring_view_t msg) SPDLOG_COND_NOEXCEPT {
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled) {
@ -182,7 +190,7 @@ public:
log_it_(log_msg, log_enabled, traceback_enabled);
}
void log(source_loc loc, level::level_enum lvl, wstring_view_t msg) {
void log(source_loc loc, level::level_enum lvl, wstring_view_t msg) SPDLOG_COND_NOEXCEPT {
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled) {
@ -195,66 +203,68 @@ public:
log_it_(log_msg, log_enabled, traceback_enabled);
}
void log(level::level_enum lvl, wstring_view_t msg) { log(source_loc{}, lvl, msg); }
void log(level::level_enum lvl, wstring_view_t msg) SPDLOG_COND_NOEXCEPT {
log(source_loc{}, lvl, msg);
}
template <typename... Args>
void trace(wformat_string_t<Args...> fmt, Args &&...args) {
void trace(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::trace, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void debug(wformat_string_t<Args...> fmt, Args &&...args) {
void debug(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::debug, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void info(wformat_string_t<Args...> fmt, Args &&...args) {
void info(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::info, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void warn(wformat_string_t<Args...> fmt, Args &&...args) {
void warn(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::warn, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void error(wformat_string_t<Args...> fmt, Args &&...args) {
void error(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::err, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void critical(wformat_string_t<Args...> fmt, Args &&...args) {
void critical(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
log(level::critical, fmt, std::forward<Args>(args)...);
}
#endif
template <typename T>
void trace(const T &msg) {
void trace(const T &msg) SPDLOG_COND_NOEXCEPT {
log(level::trace, msg);
}
template <typename T>
void debug(const T &msg) {
void debug(const T &msg) SPDLOG_COND_NOEXCEPT {
log(level::debug, msg);
}
template <typename T>
void info(const T &msg) {
void info(const T &msg) SPDLOG_COND_NOEXCEPT {
log(level::info, msg);
}
template <typename T>
void warn(const T &msg) {
void warn(const T &msg) SPDLOG_COND_NOEXCEPT {
log(level::warn, msg);
}
template <typename T>
void error(const T &msg) {
void error(const T &msg) SPDLOG_COND_NOEXCEPT {
log(level::err, msg);
}
template <typename T>
void critical(const T &msg) {
void critical(const T &msg) SPDLOG_COND_NOEXCEPT {
log(level::critical, msg);
}

@ -144,52 +144,52 @@ template <typename... Args>
inline void log(source_loc source,
level::level_enum lvl,
format_string_t<Args...> fmt,
Args &&...args) {
Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void log(level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
inline void log(level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void trace(format_string_t<Args...> fmt, Args &&...args) {
inline void trace(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->trace(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void debug(format_string_t<Args...> fmt, Args &&...args) {
inline void debug(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->debug(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void info(format_string_t<Args...> fmt, Args &&...args) {
inline void info(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->info(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void warn(format_string_t<Args...> fmt, Args &&...args) {
inline void warn(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->warn(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void error(format_string_t<Args...> fmt, Args &&...args) {
inline void error(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->error(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void critical(format_string_t<Args...> fmt, Args &&...args) {
inline void critical(format_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->critical(fmt, std::forward<Args>(args)...);
}
template <typename T>
inline void log(source_loc source, level::level_enum lvl, const T &msg) {
inline void log(source_loc source, level::level_enum lvl, const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->log(source, lvl, msg);
}
template <typename T>
inline void log(level::level_enum lvl, const T &msg) {
inline void log(level::level_enum lvl, const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->log(lvl, msg);
}
@ -198,73 +198,73 @@ template <typename... Args>
inline void log(source_loc source,
level::level_enum lvl,
wformat_string_t<Args...> fmt,
Args &&...args) {
Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
inline void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void trace(wformat_string_t<Args...> fmt, Args &&...args) {
inline void trace(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->trace(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void debug(wformat_string_t<Args...> fmt, Args &&...args) {
inline void debug(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->debug(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void info(wformat_string_t<Args...> fmt, Args &&...args) {
inline void info(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->info(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void warn(wformat_string_t<Args...> fmt, Args &&...args) {
inline void warn(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->warn(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void error(wformat_string_t<Args...> fmt, Args &&...args) {
inline void error(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->error(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
inline void critical(wformat_string_t<Args...> fmt, Args &&...args) {
inline void critical(wformat_string_t<Args...> fmt, Args &&...args) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->critical(fmt, std::forward<Args>(args)...);
}
#endif
template <typename T>
inline void trace(const T &msg) {
inline void trace(const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->trace(msg);
}
template <typename T>
inline void debug(const T &msg) {
inline void debug(const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->debug(msg);
}
template <typename T>
inline void info(const T &msg) {
inline void info(const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->info(msg);
}
template <typename T>
inline void warn(const T &msg) {
inline void warn(const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->warn(msg);
}
template <typename T>
inline void error(const T &msg) {
inline void error(const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->error(msg);
}
template <typename T>
inline void critical(const T &msg) {
inline void critical(const T &msg) SPDLOG_COND_NOEXCEPT {
default_logger_raw()->critical(msg);
}

@ -139,3 +139,16 @@
// # define SPDLOG_FUNCTION __FUNCTION__
// #endif
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Uncomment to declare all output functionality in spdlog namespace and on spdlog::logger as
// noexcept. This may allow the compiler to perform further optimizations when logging is performed.
// Additionally, static analysis can assume that logging never throws, which may be useful
// when logging is used in inherently exception-unsafe places such as destructors.
//
// Note that this will result in program termination if the registered error handler
// throws. It might also interact badly with mechanisms that inject exceptions into running
// code (such as the pthread_cancel implementation of NPTL).
//
// #define SPDLOG_LOGGER_NOEXCEPT
///////////////////////////////////////////////////////////////////////////////

@ -39,11 +39,16 @@ TEST_CASE("custom_error_handler", "[errors]") {
spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
logger->flush_on(spdlog::level::info);
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
bool error_seen = false;
logger->set_error_handler([&](const std::string &) { error_seen = true; });
logger->info("Good message #1");
REQUIRE_FALSE(error_seen);
REQUIRE_THROWS_AS(logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx"), custom_ex);
logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx");
REQUIRE(error_seen);
error_seen = false;
logger->info("Good message #2");
REQUIRE_FALSE(error_seen);
require_message_count(SIMPLE_LOG, 2);
}
#endif
@ -51,8 +56,10 @@ TEST_CASE("custom_error_handler", "[errors]") {
TEST_CASE("default_error_handler2", "[errors]") {
spdlog::drop_all();
auto logger = spdlog::create<failing_sink>("failed_logger");
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
bool error_seen = false;
logger->set_error_handler([&](const std::string &) { error_seen = true; });
logger->info("Some message");
REQUIRE(error_seen);
}
TEST_CASE("flush_error_handler", "[errors]") {
@ -62,6 +69,15 @@ TEST_CASE("flush_error_handler", "[errors]") {
REQUIRE_THROWS_AS(logger->flush(), custom_ex);
}
#if !defined(SPDLOG_LOGGER_NOEXCEPT)
TEST_CASE("custom_throw_error_handler", "[errors]") {
spdlog::drop_all();
auto logger = spdlog::create<failing_sink>("failed_logger");
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
}
#endif
#if !defined(SPDLOG_USE_STD_FORMAT)
TEST_CASE("async_error_handler", "[errors]") {
prepare_logdir();

Loading…
Cancel
Save