custom formatter api
This commit is contained in:
parent
e348c235fa
commit
0d9ec17ec3
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue