8#include "time_stamp_count.hpp"
9#include "hires_utc_clock.hpp"
10#include "polymorphic_optional.hpp"
11#include "wfree_fifo.hpp"
15#include "source_location.hpp"
16#include "architecture.hpp"
17#include "delayed_format.hpp"
18#include "fixed_string.hpp"
19#include "subsystem.hpp"
20#include "log_level.hpp"
31void trace_record() noexcept;
42 [[nodiscard]]
virtual std::string format()
const noexcept = 0;
49 static_assert(std::is_same_v<
decltype(SourceFile)::value_type,
char>,
"SourceFile must be a basic_fixed_string<char>");
50 static_assert(std::is_same_v<
decltype(Fmt)::value_type,
char>,
"Fmt must be a basic_fixed_string<char>");
55 template<
typename... Args>
56 tt_force_inline
log_message(Args &&...args) noexcept :
64 ttlet local_timestring = format_iso8601(time_point);
65 ttlet cpu_id = _time_stamp.
cpu_id();
66 ttlet thread_id = _time_stamp.
thread_id();
68 if constexpr (
static_cast<bool>(Level & log_level::statistics)) {
70 "{} {:5} {} tid={} cpu={}\n", local_timestring, to_const_string(Level), _what(), thread_id, cpu_id);
73 "{} {:5} {} ({}:{}) tid={} cpu={}\n",
75 to_const_string(Level),
86 return std::make_unique<log_message>(*
this);
100tt_no_inline
void logger_deinit() noexcept;
107tt_no_inline
bool logger_init() noexcept;
109inline
std::atomic<
bool> logger_is_running = false;
115[[nodiscard]]
std::
string get_last_error_message() noexcept;
121tt_no_inline
void logger_flush() noexcept;
127inline
bool logger_start()
129 return start_subsystem(detail::logger_is_running,
false, detail::logger_init, detail::logger_deinit);
135inline void logger_stop()
137 return stop_subsystem(detail::logger_deinit);
148template<log_level Level, basic_fixed_string SourceFile,
int SourceLine, basic_fixed_string Fmt,
typename... Args>
149tt_force_inline
void log(Args &&...args)
noexcept
151 if (!
static_cast<bool>(log_level_global.load(std::memory_order::relaxed) & Level)) {
162 detail::log_fifo.emplace<detail::log_message<Level, SourceFile, SourceLine, Fmt, forward_value_t<Args>...>>(
163 std::forward<Args>(args)...);
165 if (
static_cast<bool>(Level & log_level::fatal) || !detail::logger_is_running.load(std::memory_order::relaxed)) {
168 [[unlikely]] logger_flush();
171 if constexpr (
static_cast<bool>(Level & log_level::fatal)) {
174 }
else if constexpr (
static_cast<bool>(Level & log_level::error)) {
182#define tt_log_debug(fmt, ...) ::tt::log<::tt::log_level::debug, __FILE__, __LINE__, fmt>(__VA_ARGS__)
183#define tt_log_info(fmt, ...) ::tt::log<::tt::log_level::info, __FILE__, __LINE__, fmt>(__VA_ARGS__)
184#define tt_log_statistics(fmt, ...) ::tt::log<::tt::log_level::statistics, __FILE__, __LINE__, fmt>(__VA_ARGS__)
185#define tt_log_trace(fmt, ...) ::tt::log<::tt::log_level::trace, __FILE__, __LINE__, fmt>(__VA_ARGS__)
186#define tt_log_audit(fmt, ...) ::tt::log<::tt::log_level::audit, __FILE__, __LINE__, fmt>(__VA_ARGS__)
187#define tt_log_warning(fmt, ...) ::tt::log<::tt::log_level::warning, __FILE__, __LINE__, fmt>(__VA_ARGS__)
188#define tt_log_error(fmt, ...) ::tt::log<::tt::log_level::error, __FILE__, __LINE__, fmt>(__VA_ARGS__)
189#define tt_log_fatal(fmt, ...) \
190 ::tt::log<::tt::log_level::fatal, __FILE__, __LINE__, fmt>(__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:30
static time_point make(time_stamp_count const &tsc) noexcept
Make a time point from a time stamp count.
Since Window's 10 QueryPerformanceCounter() counts at only 10MHz which is too low to measure performa...
Definition time_stamp_count.hpp:29
constexpr uint32_t thread_id() const noexcept
Get the thread id.
Definition time_stamp_count.hpp:90
ssize_t cpu_id() const noexcept
Get the logical cpu index.
Definition time_stamp_count.hpp:77
Definition time_stamp_count.hpp:32
A wait-free multiple-producer/single-consumer fifo designed for absolute performance.
Definition wfree_fifo.hpp:23