13#include <fmt/format.h>
15#include <fmt/ostream.h>
19#include <source_location>
21#include <unordered_map>
38 message {
std::forward<T>(msg) }, location { loc }
48 Logger(std::string name,
unsigned debug_level);
50 [[nodiscard]]
inline unsigned debugLevel()
const {
return m_debug; }
52 [[nodiscard]]
inline bool shouldInfo()
const {
return m_debug >= 1; }
53 [[nodiscard]]
inline bool shouldDebug()
const {
return m_debug >= 2; }
54 [[nodiscard]]
inline bool shouldTrace()
const {
return m_debug >= 3; }
62 template <
typename... Args>
63 void info(
const char* fmt, Args&&... args)
68 fmt::styled(
"INFO ", fmt::fg(fmt::color::cornflower_blue)),
69 fmt::styled(m_name, fmt::fg(m_pass_color)),
70 fmt::vformat(fmt, fmt::make_format_args(args...)));
79 template <
typename... Args>
80 void warn(
const char* fmt, Args&&... args)
83 m_stream ==
nullptr ? std::cerr : *m_stream,
85 fmt::styled(
"Warning", colorize() ? fmt::fg(fmt::color::dark_orange) : fmt::text_style()),
86 fmt::vformat(fmt, fmt::make_format_args(args...)));
95 template <
typename... Args>
100 "{} [{}] {}({}:{}) {}",
101 fmt::styled(
"DEBUG", fmt::fg(fmt::color::pale_violet_red)),
102 fmt::styled(m_name, fmt::fg(m_pass_color)),
103 fmt::styled(data.
location.file_name(), fmt::fg(fmt::color::pale_turquoise)),
104 fmt::styled(data.
location.line(), fmt::fg(fmt::color::pale_turquoise)),
105 fmt::styled(data.
location.column(), fmt::fg(fmt::color::pale_turquoise)),
106 fmt::vformat(data.
message, fmt::make_format_args(args...)));
111 m_trace_starts[trace_name] = std::chrono::high_resolution_clock::now();
112 m_active_traces.push_back(trace_name);
117 std::string trace_name = m_active_traces.back();
118 m_active_traces.pop_back();
120 const auto time = std::chrono::high_resolution_clock::now();
121 const std::chrono::duration<double, std::milli> ms_double = time - m_trace_starts[trace_name];
122 trace(
"{} took {:.3f}ms", trace_name, ms_double.count());
131 template <
typename... Args>
132 void trace(
const char* fmt, Args&&... args)
137 fmt::styled(
"TRACE", fmt::fg(fmt::color::golden_rod)),
138 fmt::styled(m_name, fmt::fg(m_pass_color)),
139 fmt::vformat(fmt, fmt::make_format_args(args...)));
159 return m_stream ==
nullptr;
166 std::unordered_map<std::string, std::chrono::time_point<std::chrono::high_resolution_clock>>
m_trace_starts;
void debug(const Logger::MessageAndLocation &data, Args &&... args)
Write a debug level log using fmtlib.
bool colorize() const noexcept
Check if logs can be colorized.
std::unordered_map< std::string, std::chrono::time_point< std::chrono::high_resolution_clock > > m_trace_starts
void info(const char *fmt, Args &&... args)
Write an info level log using fmtlib.
void trace(const char *fmt, Args &&... args)
Write a trace level log using fmtlib.
void configureOutputStream(std::ostream *os)
Set a custom output stream to use for warnings. This will disable colors.
void warn(const char *fmt, Args &&... args)
Write a warn level log using fmtlib.
std::vector< std::string > m_active_traces
void traceStart(std::string &&trace_name)
unsigned debugLevel() const
std::source_location location
MessageAndLocation(T &&msg, const std::source_location loc=std::source_location::current())