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