mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
add: [log] exception handling for log printing
This commit is contained in:
parent
3522061321
commit
56ee0e12df
@ -6,14 +6,14 @@
|
||||
namespace {
|
||||
|
||||
void BM_imp_log_no_output(benchmark::State& state) {
|
||||
imp::log::gripper log {{}, __func__};
|
||||
imp::log::gripper log {__func__, {}};
|
||||
for (auto _ : state) {
|
||||
log.debug("hello log.");
|
||||
}
|
||||
}
|
||||
|
||||
void BM_imp_log_gripper(benchmark::State& state) {
|
||||
imp::log::gripper log {{}, __func__};
|
||||
imp::log::gripper log {__func__, {}};
|
||||
for (auto _ : state) {
|
||||
log.info("hello log.");
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "fmt/chrono.h"
|
||||
@ -53,22 +54,22 @@ template <typename T>
|
||||
constexpr bool has_fn_output_v = has_fn_output<T>::type::value;
|
||||
|
||||
struct vtable_t {
|
||||
void (*output)(void *, log::level, std::string &&);
|
||||
void (*output)(void *, log::level, std::string &&) noexcept;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class traits {
|
||||
template <typename U>
|
||||
static auto make_fn_output() noexcept
|
||||
-> std::enable_if_t<has_fn_output_v<U>, void (*)(void *, log::level, std::string &&)> {
|
||||
return [](void *p, log::level l, std::string &&s) {
|
||||
-> std::enable_if_t<has_fn_output_v<U>, void (*)(void *, log::level, std::string &&) noexcept> {
|
||||
return [](void *p, log::level l, std::string &&s) noexcept {
|
||||
static_cast<U *>(p)->output(l, std::move(s));
|
||||
};
|
||||
}
|
||||
template <typename U>
|
||||
static auto make_fn_output() noexcept
|
||||
-> std::enable_if_t<!has_fn_output_v<U>, void (*)(void *, log::level, std::string &&)> {
|
||||
return [](void *, log::level, std::string &&) {};
|
||||
-> std::enable_if_t<!has_fn_output_v<U>, void (*)(void *, log::level, std::string &&) noexcept> {
|
||||
return [](void *, log::level, std::string &&) noexcept {};
|
||||
}
|
||||
|
||||
public:
|
||||
@ -98,12 +99,12 @@ public:
|
||||
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
void output(log::level, std::string &&);
|
||||
void output(log::level, std::string &&) noexcept;
|
||||
};
|
||||
|
||||
class LIBIMP_EXPORT std_t {
|
||||
public:
|
||||
void output(log::level, std::string &&);
|
||||
void output(log::level, std::string &&) noexcept;
|
||||
};
|
||||
|
||||
LIBIMP_EXPORT extern std_t std_out;
|
||||
@ -114,51 +115,58 @@ class gripper {
|
||||
level level_limit_;
|
||||
|
||||
template <typename Fmt, typename... A>
|
||||
gripper &output(log::level l, Fmt &&ft, A &&... args) {
|
||||
gripper &output(log::level l, Fmt &&ft, A &&... args) noexcept {
|
||||
if (!printer_ || (enum_cast(l) < enum_cast(level_limit_))) {
|
||||
return *this;
|
||||
}
|
||||
constexpr static char types[] = {
|
||||
'T', 'D', 'I', 'W', 'E', 'F'
|
||||
};
|
||||
auto tp = std::chrono::system_clock::now();
|
||||
auto ms = std::chrono::time_point_cast<std::chrono::milliseconds>(tp).time_since_epoch().count() % 1000;
|
||||
auto px = fmt("[{}][{:%Y-%m-%d %H:%M:%S}.{:03}][{}] ", types[enum_cast(l)], tp, ms, func_);
|
||||
printer_.output(l, std::move(px += fmt(std::forward<Fmt>(ft), std::forward<A>(args)...)));
|
||||
try {
|
||||
auto tp = std::chrono::system_clock::now();
|
||||
auto ms = std::chrono::time_point_cast<std::chrono::milliseconds>(tp).time_since_epoch().count() % 1000;
|
||||
auto px = fmt("[{}][{:%Y-%m-%d %H:%M:%S}.{:03}][{}] ", types[enum_cast(l)], tp, ms, func_);
|
||||
printer_.output(l, std::move(px += fmt(std::forward<Fmt>(ft), std::forward<A>(args)...)));
|
||||
} catch (std::exception const &e) {
|
||||
/// @brief [TBD] std::string constructor may throw an exception
|
||||
printer_.output(level::failed, e.what());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
gripper(printer printer, char const *func, level level_limit = level::info) noexcept
|
||||
gripper(char const *func, printer printer = std_out, level level_limit = level::info) noexcept
|
||||
: printer_ (printer)
|
||||
, func_ (func)
|
||||
, level_limit_(level_limit) {}
|
||||
|
||||
template <typename Fmt, typename... A>
|
||||
gripper &trace(Fmt &&ft, A &&... args) {
|
||||
gripper &trace(Fmt &&ft, A &&... args) noexcept {
|
||||
return output(log::level::trace, std::forward<Fmt>(ft), std::forward<A>(args)...);
|
||||
}
|
||||
template <typename Fmt, typename... A>
|
||||
gripper &debug(Fmt &&ft, A &&... args) {
|
||||
gripper &debug(Fmt &&ft, A &&... args) noexcept {
|
||||
return output(log::level::debug, std::forward<Fmt>(ft), std::forward<A>(args)...);
|
||||
}
|
||||
template <typename Fmt, typename... A>
|
||||
gripper &info(Fmt &&ft, A &&... args) {
|
||||
gripper &info(Fmt &&ft, A &&... args) noexcept {
|
||||
return output(log::level::info, std::forward<Fmt>(ft), std::forward<A>(args)...);
|
||||
}
|
||||
template <typename Fmt, typename... A>
|
||||
gripper &warning(Fmt &&ft, A &&... args) {
|
||||
gripper &warning(Fmt &&ft, A &&... args) noexcept {
|
||||
return output(log::level::warning, std::forward<Fmt>(ft), std::forward<A>(args)...);
|
||||
}
|
||||
template <typename Fmt, typename... A>
|
||||
gripper &error(Fmt &&ft, A &&... args) {
|
||||
gripper &error(Fmt &&ft, A &&... args) noexcept {
|
||||
return output(log::level::error, std::forward<Fmt>(ft), std::forward<A>(args)...);
|
||||
}
|
||||
template <typename Fmt, typename... A>
|
||||
gripper &failed(Fmt &&ft, A &&... args) {
|
||||
gripper &failed(Fmt &&ft, A &&... args) noexcept {
|
||||
return output(log::level::failed, std::forward<Fmt>(ft), std::forward<A>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace log
|
||||
LIBIMP_NAMESPACE_END_
|
||||
|
||||
#define LIBIMP_LOG_(...) LIBIMP_NAMESPACE_::log::gripper log {__func__, __VA_ARGS__}
|
||||
@ -11,14 +11,14 @@ printer::operator bool() const noexcept {
|
||||
return (objp_ != nullptr) && (vtable_ != nullptr);
|
||||
}
|
||||
|
||||
void printer::output(log::level l, std::string &&s) {
|
||||
void printer::output(log::level l, std::string &&s) noexcept {
|
||||
if (!*this) return;
|
||||
vtable_->output(objp_, l, std::move(s));
|
||||
}
|
||||
|
||||
std_t std_out;
|
||||
|
||||
void std_t::output(log::level l, std::string &&s) {
|
||||
void std_t::output(log::level l, std::string &&s) noexcept {
|
||||
switch (l) {
|
||||
case level::trace:
|
||||
case level::debug:
|
||||
|
||||
@ -68,6 +68,12 @@ TEST(log, log_printer) {
|
||||
}
|
||||
|
||||
TEST(log, gripper) {
|
||||
imp::log::gripper log {imp::log::std_out, __func__};
|
||||
log.info("hello");
|
||||
{
|
||||
imp::log::gripper log {__func__};
|
||||
log.info("hello");
|
||||
}
|
||||
{
|
||||
LIBIMP_LOG_();
|
||||
log.info("hello 2");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user