6#include "TTauri/Foundation/counters.hpp"
7#include "TTauri/Foundation/cpu_counter_clock.hpp"
8#include "TTauri/Foundation/hires_utc_clock.hpp"
9#include "TTauri/Foundation/polymorphic_value.hpp"
10#include "TTauri/Foundation/wfree_message_queue.hpp"
11#include "TTauri/Foundation/atomic.hpp"
12#include "TTauri/Foundation/meta.hpp"
13#include "TTauri/Foundation/format.hpp"
14#include "TTauri/Foundation/os_detect.hpp"
16#include <fmt/format.h>
17#include <fmt/ostream.h>
27[[noreturn]]
void terminateOnFatalError(
std::string &&message)
noexcept;
30void trace_record() noexcept;
33 const char *source_path;
37 source_path(source_path), source_line(source_line) {}
42enum class log_level: uint8_t {
67constexpr char const *to_const_string(log_level level)
noexcept
70 case log_level::Debug:
return "DEBUG";
71 case log_level::Info:
return "INFO";
72 case log_level::Trace:
return "TRACE";
73 case log_level::Counter:
return "COUNT";
74 case log_level::Exception:
return "THROW";
75 case log_level::Audit:
return "AUDIT";
76 case log_level::Warning:
return "WARN";
77 case log_level::Error:
return "ERROR";
78 case log_level::Assert:
return "ASSERT";
79 case log_level::Critical:
return "CRIT";
80 case log_level::Fatal:
return "FATAL";
81 default:
return "<unknown>";
85inline int command_line_argument_to_log_level(std::string_view str)
noexcept
88 return static_cast<int>(log_level::Debug);
89 }
else if (str ==
"info") {
90 return static_cast<int>(log_level::Info);
91 }
else if (str ==
"audit") {
92 return static_cast<int>(log_level::Audit);
93 }
else if (str ==
"warning") {
94 return static_cast<int>(log_level::Warning);
95 }
else if (str ==
"error") {
96 return static_cast<int>(log_level::Error);
97 }
else if (str ==
"critical") {
98 return static_cast<int>(log_level::Critical);
99 }
else if (str ==
"fatal") {
100 return static_cast<int>(log_level::Fatal);
106constexpr bool operator<(log_level lhs, log_level rhs)
noexcept {
return static_cast<int>(lhs) <
static_cast<int>(rhs); }
107constexpr bool operator>(log_level lhs, log_level rhs)
noexcept {
return rhs < lhs; }
108constexpr bool operator==(log_level lhs, log_level rhs)
noexcept {
return static_cast<int>(lhs) ==
static_cast<int>(rhs); }
109constexpr bool operator!=(log_level lhs, log_level rhs)
noexcept {
return !(lhs == rhs); }
110constexpr bool operator<=(log_level lhs, log_level rhs)
noexcept {
return !(lhs > rhs); }
111constexpr bool operator>=(log_level lhs, log_level rhs)
noexcept {
return !(lhs < rhs); }
118 timestamp(timestamp), format(format) {}
122 virtual log_level level()
const noexcept = 0;
125template<log_level Level,
typename... Args>
130 log_message_base(timestamp, format), format_args(std::forward<Args>(args)...) {}
132 log_level level()
const noexcept override {
140 if (format_uses_arg_ids(format)) {
141 constexpr size_t source_index = index_of_type<
source_code_ptr, Args...>();
145 format_str +=
" ({})";
149 auto f = [format_str=format_str](ttlet&... args) {
150 return fmt::format(format_str, args...);
154 return std::apply(f, format_args);
155 }
catch (fmt::format_error &e) {
166 static constexpr size_t MAX_MESSAGE_SIZE = 224;
167 static constexpr size_t MESSAGE_ALIGNMENT = 256;
168 static constexpr size_t MAX_NR_MESSAGES = 4096;
179 log_level minimum_log_level = log_level::Debug;
182 void logger_tick()
noexcept;
183 void gather_tick(
bool last)
noexcept;
185 template<log_level Level,
typename... Args>
187 if (Level >= minimum_log_level) {
195 message->emplace<
log_message<Level, Args...>>(timestamp, format, std::forward<Args>(args)...);
201 if constexpr (Level >= log_level::Fatal) {
202 ttlet message =
log_message<Level, Args...>(timestamp, format, std::forward<Args>(args)...);
204 terminateOnFatalError(message.message());
206 }
else if constexpr (Level >= log_level::Error) {
217 void display_time_calibration()
noexcept;
218 void display_counters()
noexcept;
219 void display_trace_statistics()
noexcept;
226#define TTAURI_LOG(level, ...) ::tt::logger.log<level>(::tt::cpu_counter_clock::now(), __VA_ARGS__, ::tt::source_code_ptr(__FILE__, __LINE__))
228#define LOG_DEBUG(...) TTAURI_LOG(::tt::log_level::Debug, __VA_ARGS__)
229#define LOG_INFO(...) TTAURI_LOG(::tt::log_level::Info, __VA_ARGS__)
230#define LOG_AUDIT(...) TTAURI_LOG(::tt::log_level::Audit, __VA_ARGS__)
231#define LOG_EXCEPTION(...) TTAURI_LOG(::tt::log_level::Exception, __VA_ARGS__)
232#define LOG_WARNING(...) TTAURI_LOG(::tt::log_level::Warning, __VA_ARGS__)
233#define LOG_ERROR(...) TTAURI_LOG(::tt::log_level::Error, __VA_ARGS__)
234#define LOG_ASSERT(...) TTAURI_LOG(::tt::log_level::Assert, __VA_ARGS__)
235#define LOG_CRITICAL(...) TTAURI_LOG(::tt::log_level::Critical, __VA_ARGS__)
236#define LOG_FATAL(...) TTAURI_LOG(::tt::log_level::Fatal, __VA_ARGS__); tt_unreachable()
Definition logger.hpp:113
Definition logger.hpp:126
Definition logger.hpp:161
Definition logger.hpp:165
Definition polymorphic_value.hpp:20
scoped_write_operation write() noexcept
Definition wfree_message_queue.hpp:128