custom formatter api

This commit is contained in:
janis 2022-06-21 01:18:52 +01:00
parent e348c235fa
commit 0d9ec17ec3
2 changed files with 68 additions and 22 deletions

View file

@ -2,6 +2,8 @@
#include <format> #include <format>
#include <ios> #include <ios>
#include <memory>
#include <string>
#include <string_view> #include <string_view>
namespace journal { namespace journal {
@ -48,8 +50,30 @@ enum LogVerbosity {
Error, Error,
}; };
struct Verbosity {
journal::detail::LogVerbosity inner;
Verbosity(journal::detail::LogVerbosity &&value) : inner(value) {}
Verbosity(const journal::detail::LogVerbosity &value) : inner(value) {}
auto operator<=>(const Verbosity &rhs) const -> std::strong_ordering {
return static_cast<std::underlying_type_t<decltype(inner)>>(inner) <=>
static_cast<std::underlying_type_t<decltype(rhs.inner)>>(rhs.inner);
}
};
constexpr auto to_string(const LogVerbosity& verbosity) -> std::string; constexpr auto to_string(const LogVerbosity& verbosity) -> std::string;
namespace formatter {
struct Formatter {
virtual auto operator()(const Verbosity &verbosity,
const source_location &source) -> std::string = 0;
virtual ~Formatter() {}
};
} // namespace formatter
template <typename... Args> template <typename... Args>
inline constexpr auto log(const LogVerbosity &verbosity, std::string_view fmt, inline constexpr auto log(const LogVerbosity &verbosity, std::string_view fmt,
Args... args, const detail::source_location source) Args... args, const detail::source_location source)
@ -61,6 +85,7 @@ inline constexpr auto log(const LogVerbosity &verbosity, std::string_view fmt,
auto log_internal(const LogVerbosity &verbosity, auto log_internal(const LogVerbosity &verbosity,
const detail::source_location source, const std::string &msg) const detail::source_location source, const std::string &msg)
-> void; -> void;
} // namespace detail } // namespace detail
using detail::LogVerbosity; using detail::LogVerbosity;
@ -69,6 +94,8 @@ auto init_std_out(const LogVerbosity &min = LogVerbosity::Info) -> void;
auto init_std_out_err(const LogVerbosity &min = LogVerbosity::Info) -> void; auto init_std_out_err(const LogVerbosity &min = LogVerbosity::Info) -> void;
auto init() -> void; auto init() -> void;
auto init_no_threads() -> void; auto init_no_threads() -> void;
auto set_formatter(std::unique_ptr<detail::formatter::Formatter> &&formatter)
-> void;
auto add_std_out() -> void; auto add_std_out() -> void;
auto add_std_err() -> void; auto add_std_err() -> void;
auto add_file(std::string_view file_path, auto add_file(std::string_view file_path,

View file

@ -11,6 +11,7 @@
#include <optional> #include <optional>
#include <ostream> #include <ostream>
#include <stop_token> #include <stop_token>
#include <string>
#include <string_view> #include <string_view>
#include <thread> #include <thread>
@ -166,17 +167,30 @@ constexpr auto to_string(const LogVerbosity& verbosity) -> std::string {
} }
} }
struct Verbosity { namespace formatter {
journal::detail::LogVerbosity inner;
Verbosity(journal::detail::LogVerbosity &&value) : inner(value) {} struct DefaultFormatter : public Formatter {
Verbosity(const journal::detail::LogVerbosity &value) : inner(value) {} virtual auto operator()(const Verbosity &verbosity,
const source_location &source) -> std::string {
return std::format("[{}] [{: <5}] [{}]", get_current_time_string(),
to_string(verbosity.inner),
get_source_location_string(source));
}
auto operator<=>(const Verbosity &rhs) const -> std::strong_ordering { auto get_source_location_string(const source_location &source)
return static_cast<std::underlying_type_t<decltype(inner)>>(inner) <=> -> std::string {
static_cast<std::underlying_type_t<decltype(rhs.inner)>>(rhs.inner); const auto file =
std::filesystem::path(source.file_name()).filename().string();
return std::format("{}::{}", file, source.line());
}
auto get_current_time_string() -> std::string {
const auto now = std::chrono::utc_clock::now();
return std::format("{:%Y-%m-%d %H:%M:%OS} UTC", now);
} }
}; };
} // namespace formatter
using namespace std::chrono_literals; using namespace std::chrono_literals;
@ -251,11 +265,14 @@ static auto try_flush_all_loop(std::stop_token) -> void;
class Journal { class Journal {
std::vector<std::unique_ptr<sinks::BaseSink>> sinks; std::vector<std::unique_ptr<sinks::BaseSink>> sinks;
std::unique_ptr<formatter::Formatter> formatter;
std::optional<std::jthread> flush_thread; std::optional<std::jthread> flush_thread;
std::chrono::system_clock::duration flush_interval; std::chrono::system_clock::duration flush_interval;
public: public:
Journal() : flush_interval(250ms) {} Journal()
: flush_interval(250ms),
formatter(std::make_unique<formatter::DefaultFormatter>()) {}
~Journal() { ~Journal() {
if (flush_thread) { if (flush_thread) {
log(LogVerbosity::Trace, source_location::current(), log(LogVerbosity::Trace, source_location::current(),
@ -270,6 +287,15 @@ public:
flush_all(); flush_all();
} }
auto reset_formatter() -> void {
formatter = std::make_unique<formatter::DefaultFormatter>();
}
auto set_formatter(std::unique_ptr<formatter::Formatter> &&formatter)
-> void {
formatter = std::move(formatter);
}
auto auto
set_flush_interval(const std::chrono::system_clock::duration &new_interval) set_flush_interval(const std::chrono::system_clock::duration &new_interval)
-> void { -> void {
@ -311,20 +337,7 @@ public:
auto format(std::string_view str, const Verbosity &verbosity, auto format(std::string_view str, const Verbosity &verbosity,
const source_location &source) -> std::string { const source_location &source) -> std::string {
return std::format("[{}] [{: <5}] [{}] {}\n", get_current_time_string(), return std::format("{} {}\n", (*formatter)(verbosity, source), str);
to_string(verbosity.inner),
get_source_location_string(source), str);
}
auto get_source_location_string(const source_location& source) -> std::string {
const auto file = std::filesystem::path(source.file_name()).filename().string();
return std::format("{}::{}", file, source.line());
}
auto get_current_time_string() -> std::string {
const auto now = std::chrono::utc_clock::now();
return std::format("{:%Y-%m-%d %H:%M:%OS} UTC", now);
} }
auto add_file(const std::string &file_name, auto add_file(const std::string &file_name,
@ -392,6 +405,12 @@ auto init_std_out_err(const LogVerbosity &min) -> void {
ref->add_std_err(); ref->add_std_err();
} }
auto set_formatter(std::unique_ptr<detail::formatter::Formatter> &&formatter)
-> void {
auto &&[lock, ref] = detail::global_journal.mut();
ref->set_formatter(std::move(formatter));
}
auto add_std_out() -> void { auto add_std_out() -> void {
auto &&[lock, ref] = detail::global_journal.mut(); auto &&[lock, ref] = detail::global_journal.mut();
ref->add_std_out(); ref->add_std_out();