8#include "cpu_counter_clock.hpp"
9#include "hires_utc_clock.hpp"
10#include "polymorphic_optional.hpp"
11#include "wfree_message_queue.hpp"
15#include "source_location.hpp"
16#include "os_detect.hpp"
17#include "delayed_format.hpp"
18#include "fixed_string.hpp"
20#include <fmt/format.h>
21#include <fmt/ostream.h>
31[[noreturn]]
void terminateOnFatalError(
std::string &&message)
noexcept;
34void trace_record() noexcept;
36enum class log_level : uint8_t {
57constexpr char const *to_const_string(log_level level)
noexcept
60 case log_level::Debug:
return "DEBUG";
61 case log_level::Info:
return "INFO";
62 case log_level::Trace:
return "TRACE";
63 case log_level::Counter:
return "COUNT";
64 case log_level::Audit:
return "AUDIT";
65 case log_level::Warning:
return "WARN";
66 case log_level::Error:
return "ERROR";
67 case log_level::Critical:
return "CRIT";
68 case log_level::Fatal:
return "FATAL";
69 default:
return "<unknown>";
73inline int command_line_argument_to_log_level(std::string_view str)
noexcept
76 return static_cast<int>(log_level::Debug);
77 }
else if (str ==
"info") {
78 return static_cast<int>(log_level::Info);
79 }
else if (str ==
"audit") {
80 return static_cast<int>(log_level::Audit);
81 }
else if (str ==
"warning") {
82 return static_cast<int>(log_level::Warning);
83 }
else if (str ==
"error") {
84 return static_cast<int>(log_level::Error);
85 }
else if (str ==
"critical") {
86 return static_cast<int>(log_level::Critical);
87 }
else if (str ==
"fatal") {
88 return static_cast<int>(log_level::Fatal);
94constexpr bool operator<(log_level lhs, log_level rhs)
noexcept
96 return static_cast<int>(lhs) <
static_cast<int>(rhs);
98constexpr bool operator>(log_level lhs, log_level rhs)
noexcept
102constexpr bool operator==(log_level lhs, log_level rhs)
noexcept
104 return static_cast<int>(lhs) ==
static_cast<int>(rhs);
106constexpr bool operator!=(log_level lhs, log_level rhs)
noexcept
108 return !(lhs == rhs);
110constexpr bool operator<=(log_level lhs, log_level rhs)
noexcept
114constexpr bool operator>=(log_level lhs, log_level rhs)
noexcept
137 static_assert(std::is_same_v<
decltype(SourceFile)::value_type,
char>,
"SourceFile must be a basic_fixed_string<char>");
138 static_assert(std::is_same_v<
decltype(Fmt)::value_type,
char>,
"Fmt must be a basic_fixed_string<char>");
140 template<
typename... Args>
142 _timestamp(timestamp), _what(std::forward<Args>(args)...)
148 ttlet local_timestring = log_message_base::cpu_utc_clock_as_iso8601(_timestamp);
150 if constexpr (Level == log_level::Trace || Level == log_level::Counter) {
151 return fmt::format(
"{} {:5} {}", local_timestring, to_const_string(Level), _what());
154 "{} {:5} {} ({}:{})", local_timestring, to_const_string(Level), _what(), SourceFile, SourceLine);
170 static constexpr size_t MAX_MESSAGE_SIZE = 224;
171 static constexpr size_t MESSAGE_ALIGNMENT = 256;
172 static constexpr size_t MAX_NR_MESSAGES = 4096;
185 log_level minimum_log_level = log_level::Debug;
187 void logger_tick()
noexcept;
188 void gather_tick(
bool last)
noexcept;
194 if (Level >= minimum_log_level) {
200 auto message = message_queue.
write<
"logger_blocked">();
204 timestamp, std::forward<Args>(args)...);
206 if constexpr (Level >= log_level::Fatal) {
208 terminateOnFatalError((*message)->format());
210 }
else if constexpr (Level >= log_level::Error) {
222 void display_time_calibration()
noexcept;
223 void display_counters()
noexcept;
224 void display_trace_statistics()
noexcept;
233#define tt_log(level, fmt, ...) \
235 ttlet _tt_log_timestamp = ::tt::cpu_counter_clock::now(); \
236 ::tt::logger.log<level, __FILE__, __LINE__, fmt>(_tt_log_timestamp __VA_OPT__(,) __VA_ARGS__); \
239#define tt_log_debug(fmt, ...) tt_log(::tt::log_level::Debug, fmt __VA_OPT__(,) __VA_ARGS__)
240#define tt_log_trace(fmt, ...) tt_log(::tt::log_level::Trace, fmt __VA_OPT__(,) __VA_ARGS__)
241#define tt_log_counter(fmt, ...) tt_log(::tt::log_level::Counter, fmt __VA_OPT__(,) __VA_ARGS__)
242#define tt_log_info(fmt, ...) tt_log(::tt::log_level::Info, fmt __VA_OPT__(,) __VA_ARGS__)
243#define tt_log_audit(fmt, ...) tt_log(::tt::log_level::Audit, fmt __VA_OPT__(,) __VA_ARGS__)
244#define tt_log_warning(fmt, ...) tt_log(::tt::log_level::Warning, fmt __VA_OPT__(,) __VA_ARGS__)
245#define tt_log_error(fmt, ...) tt_log(::tt::log_level::Error, fmt __VA_OPT__(,) __VA_ARGS__)
246#define tt_log_critical(fmt, ...) tt_log(::tt::log_level::Critical, fmt __VA_OPT__(,) __VA_ARGS__)
247#define tt_log_fatal(fmt, ...) \
248 tt_log(::tt::log_level::Fatal, fmt __VA_OPT__(,) __VA_ARGS__); \
Delayed formatting.
Definition delayed_format.hpp:19
example: ``` template<tt::basic_fixed_string Foo> class A { auto bar() { return std::string{Foo}; } }...
Definition fixed_string.hpp:29
Definition logger.hpp:119
Definition logger.hpp:135
Definition logger.hpp:169
Polymorphic optional.
Definition polymorphic_optional.hpp:26
scoped_write_operation write() noexcept
Definition wfree_message_queue.hpp:130