err_helper class

pull/3309/head
gabime 8 months ago
parent eb450b0240
commit 35322adf8f

@ -156,7 +156,7 @@ set(SPDLOG_HEADERS
"include/spdlog/details/mpmc_blocking_q.h"
"include/spdlog/details/null_mutex.h"
"include/spdlog/details/os.h"
"include/spdlog/details/default_err_handler.h"
"include/spdlog/details/err_helper.h"
"include/spdlog/bin_to_hex.h"
"include/spdlog/sinks/android_sink.h"
"include/spdlog/sinks/base_sink.h"
@ -192,7 +192,7 @@ set(SPDLOG_SRCS
"src/details/os_filesystem.cpp"
"src/details/log_msg.cpp"
"src/details/async_log_msg.cpp"
"src/details/default_err_handler.cpp"
"src/details/err_helper.cpp"
"src/sinks/base_sink.cpp"
"src/sinks/basic_file_sink.cpp"
"src/sinks/rotating_file_sink.cpp"

@ -11,10 +11,12 @@
// by default, prints the error to stderr, thread safe
namespace spdlog {
namespace details {
class default_err_handler {
mutable std::mutex mutex_;
class err_helper {
err_handler custom_err_handler_;
public:
void handle_ex(const std::string& origin, const source_loc& loc, const std::exception& ex) const;
void handle_unknown_ex(const std::string& origin, const source_loc& loc) const;
void set_err_handler(err_handler handler);
};

@ -16,7 +16,7 @@
#include <vector>
#include "common.h"
#include "details/default_err_handler.h"
#include "details/err_helper.h"
#include "details/log_msg.h"
#include "sinks/sink.h"
@ -160,8 +160,7 @@ private:
std::vector<sink_ptr> sinks_;
atomic_level_t level_{level::info};
atomic_level_t flush_level_{level::off};
err_handler custom_err_handler_;
details::default_err_handler default_err_handler_;
details::err_helper err_helper_;
// common implementation for after templated public api has been resolved to format string and
// args
@ -173,9 +172,9 @@ private:
fmt::vformat_to(std::back_inserter(buf), format_string, fmt::make_format_args(args...));
sink_it_(details::log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())));
} catch (const std::exception &ex) {
handle_ex_(loc, ex);
err_helper_.handle_ex(name_, loc, ex);
} catch (...) {
handle_unknown_ex_(loc);
err_helper_.handle_unknown_ex(name_, loc);
}
}
@ -187,9 +186,9 @@ private:
try {
sink->log(msg);
} catch (const std::exception &ex) {
handle_ex_(msg.source, ex);
err_helper_.handle_ex(name_, msg.source, ex);
} catch (...) {
handle_unknown_ex_(msg.source);
err_helper_.handle_unknown_ex(name_, msg.source);
}
}
}
@ -200,9 +199,6 @@ private:
}
void flush_();
[[nodiscard]] bool should_flush_(const details::log_msg &msg) const;
void handle_ex_(const source_loc &loc, const std::exception &ex) const;
void handle_unknown_ex_(const source_loc &loc) const;
};
} // namespace spdlog

@ -8,7 +8,7 @@
#include <vector>
#include "../details/async_log_msg.h"
#include "../details/default_err_handler.h"
#include "../details/err_helper.h"
#include "sink.h"
// async_sink is a sink that sends log messages to a dist_sink in a separate thread using a queue.
@ -39,6 +39,7 @@ public:
std::vector<std::shared_ptr<sink>> sinks;
std::function<void()> on_thread_start = nullptr;
std::function<void()> on_thread_stop = nullptr;
err_handler err_handler = nullptr;
};
explicit async_sink(config async_config);
@ -78,7 +79,7 @@ private:
config config_;
std::unique_ptr<queue_t> q_;
std::thread worker_thread_;
details::default_err_handler err_handler_;
details::err_helper err_helper_;
};
} // namespace sinks

@ -1,29 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include "iostream"
#include "spdlog/details/default_err_handler.h"
#include "spdlog/details/os.h"
namespace spdlog {
namespace details {
// Prints error to stderr with source location (if available). A stderr sink is not used because reaching
// this point might indicate a problem with the logging system itself so we use fputs() directly.
void default_err_handler::handle_ex(const std::string &origin, const source_loc &loc, const std::exception &ex) const {
std::lock_guard lk{mutex_};
const auto tm_time = os::localtime();
char date_buf[64];
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
std::string msg;
if (loc.empty()) {
msg = fmt_lib::format("[*** LOGGING ERROR ***] [{}] [{}] {}\n", date_buf, origin, ex.what());
} else {
msg = fmt_lib::format("[*** LOGGING ERROR ***] [{}({})] [{}] [{}] {}\n", loc.filename, loc.line, date_buf, origin,
ex.what());
}
std::fputs(msg.c_str(), stderr);
}
} // namespace details
} // namespace spdlog

@ -0,0 +1,40 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include "iostream"
#include "spdlog/details/err_helper.h"
#include "spdlog/details/os.h"
namespace spdlog {
namespace details {
// Prints error to stderr with source location (if available). A stderr sink is not used because reaching
// this point might indicate a problem with the logging system itself so we use fputs() directly.
void err_helper::handle_ex(const std::string &origin, const source_loc &loc, const std::exception &ex) const {
if (custom_err_handler_) {
custom_err_handler_(ex.what());
return;
}
const auto tm_time = os::localtime();
char date_buf[32];
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
std::string msg;
if (loc.empty()) {
msg = fmt_lib::format("[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, origin, ex.what());
} else {
msg = fmt_lib::format("[*** LOG ERROR ***] [{}({})] [{}] [{}] {}\n", loc.filename, loc.line, date_buf, origin,
ex.what());
}
std::fputs(msg.c_str(), stderr);
}
void err_helper::handle_unknown_ex(const std::string &origin, const source_loc &loc) const {
handle_ex(origin, loc, std::runtime_error("unknown exception"));
}
void err_helper::set_err_handler(err_handler handler) {
custom_err_handler_ = std::move(handler);
}
} // namespace details
} // namespace spdlog

@ -14,14 +14,14 @@ logger::logger(const logger &other) noexcept
sinks_(other.sinks_),
level_(other.level_.load(std::memory_order_relaxed)),
flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
custom_err_handler_(other.custom_err_handler_) {}
err_helper_(other.err_helper_) {}
logger::logger(logger &&other) noexcept
: name_(std::move(other.name_)),
sinks_(std::move(other.sinks_)),
level_(other.level_.load(std::memory_order_relaxed)),
flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
custom_err_handler_(std::move(other.custom_err_handler_)) {}
err_helper_(std::move(other.err_helper_)) {}
void logger::set_level(level level) { level_.store(level); }
@ -60,7 +60,7 @@ const std::vector<sink_ptr> &logger::sinks() const { return sinks_; }
std::vector<sink_ptr> &logger::sinks() { return sinks_; }
// custom error handler
void logger::set_error_handler(err_handler handler) { custom_err_handler_ = std::move(handler); }
void logger::set_error_handler(err_handler handler) { err_helper_.set_err_handler(std::move(handler)); }
// create new logger with same sinks and configuration.
std::shared_ptr<logger> logger::clone(std::string logger_name) {
@ -75,32 +75,16 @@ void logger::flush_() {
try {
sink->flush();
} catch (const std::exception &ex) {
handle_ex_(source_loc{}, ex);
err_helper_.handle_ex(name_, source_loc{}, ex);
} catch (...) {
handle_unknown_ex_(source_loc{});
err_helper_.handle_unknown_ex(name_, source_loc{});
}
}
}
bool logger::should_flush_(const details::log_msg &msg) const {
auto flush_level = flush_level_.load(std::memory_order_relaxed);
const auto flush_level = flush_level_.load(std::memory_order_relaxed);
return (msg.log_level >= flush_level) && (msg.log_level != level::off);
}
void logger::handle_ex_(const source_loc &loc, const std::exception &ex) const {
if (custom_err_handler_) {
custom_err_handler_(ex.what());
return;
}
default_err_handler_.handle_ex(name_, loc, ex);
}
void logger::handle_unknown_ex_(const source_loc &loc) const {
if (custom_err_handler_) {
custom_err_handler_("unknown exception");
return;
}
default_err_handler_.handle_ex(name_, loc, std::runtime_error("Unknown exception"));
}
} // namespace spdlog

@ -107,7 +107,9 @@ void async_sink::backend_log_(const details::log_msg &msg) {
try {
sink->log(msg);
} catch (const std::exception &ex) {
err_handler_.handle_ex("async log", msg.source, ex);
err_helper_.handle_ex("async log", msg.source, ex);
} catch (...) {
err_helper_.handle_unknown_ex("async log", source_loc{});
}
}
}
@ -118,9 +120,9 @@ void async_sink::backend_flush_() {
try {
sink->flush();
} catch (const std::exception &ex) {
err_handler_.handle_ex("async flush", source_loc{}, ex);
err_helper_.handle_ex("async flush", source_loc{}, ex);
} catch (...) {
err_handler_.handle_ex("async flush", source_loc{}, std::runtime_error("Unknown exception during flush"));
err_helper_.handle_unknown_ex("async flush", source_loc{});
}
}
}

Loading…
Cancel
Save