23 static constexpr const char* LevelNames[] = {
24 "trace",
"debug",
"info",
"fail",
"fatal"};
26 static constexpr const char* to_string(
LoggerLevel l)
28 return LevelNames[
static_cast<int>(l)];
31 static constexpr long int ns_per_s = 1'000'000'000;
33 static constexpr auto preamble_length = 45u;
35#ifdef CCF_RAFT_TRACING
36 static size_t logical_clock = 0;
49 std::ostringstream
ss;
54 std::string_view tag_,
55 std::string_view file_name_,
56 size_t line_number_) :
84 static std::string get_timestamp(
const std::tm& tm, const ::timespec& ts)
86#ifdef CCF_RAFT_TRACING
87 return std::to_string(logical_clock++);
90 return fmt::format(
"{:%Y-%m-%dT%H:%M:%S}.{:0>6}Z", tm, ts.tv_nsec / 1000);
100 virtual void emit(
const std::string& s)
102 std::cout.write(s.c_str(), s.size());
108 const std::optional<double>& enclave_offset = std::nullopt) = 0;
116 const std::optional<double>& enclave_offset = std::nullopt)
override
120 ::timespec_get(&host_ts, TIME_UTC);
122 ::gmtime_r(&host_ts.tv_sec, &host_tm);
124#ifdef CCF_RAFT_TRACING
125 auto escaped_msg = ll.
msg;
126 if (!nlohmann::json::accept(escaped_msg))
131 escaped_msg = nlohmann::json(ll.
msg).dump();
134 const auto escaped_msg = nlohmann::json(ll.
msg).dump();
138 if (enclave_offset.has_value())
140 ::timespec enc_ts = host_ts;
141 enc_ts.tv_sec += (size_t)enclave_offset.value();
143 (
long long)(enclave_offset.value() * ns_per_s) % ns_per_s;
145 if (enc_ts.tv_nsec > ns_per_s)
148 enc_ts.tv_nsec -= ns_per_s;
152 gmtime_r(&enc_ts.tv_sec, &enclave_tm);
155 "{{\"h_ts\":\"{}\",\"e_ts\":\"{}\",\"thread_id\":\"{}\",\"level\":\"{"
156 "}\",\"tag\":\"{}\",\"file\":\"{}\",\"number\":\"{}\",\"msg\":{}}}\n",
157 get_timestamp(host_tm, host_ts),
158 get_timestamp(enclave_tm, enc_ts),
169 "{{\"h_ts\":\"{}\",\"thread_id\":\"{}\",\"level\":\"{}\",\"tag\":\"{}"
170 "\",\"file\":\"{}\",\"number\":\"{}\",\"msg\":{}}}\n",
171 get_timestamp(host_tm, host_ts),
184 static std::string format_to_text(
186 const std::optional<double>& enclave_offset = std::nullopt)
190 ::timespec_get(&host_ts, TIME_UTC);
192 ::gmtime_r(&host_ts.tv_sec, &host_tm);
194 auto file_line = fmt::format(
"{}:{} ", ll.file_name, ll.line_number);
195 auto file_line_data = file_line.data();
199 auto preamble = fmt::format(
201 to_string(ll.log_level),
202 (ll.tag.empty() ?
"" : fmt::format(
"[{}]", ll.tag)))
203 .substr(0, preamble_length);
204 const auto max_file_line_len = preamble_length - preamble.size();
206 const auto len = file_line.size();
207 if (len > max_file_line_len)
209 file_line_data += len - max_file_line_len;
212 preamble += file_line_data;
214 if (enclave_offset.has_value())
220 "{} {:+01.3f} {:<3} {:<45}| {}\n",
221 get_timestamp(host_tm, host_ts),
222 enclave_offset.value(),
232 "{} {:<3} {:<45}| {}\n",
233 get_timestamp(host_tm, host_ts),
245 const std::optional<double>& enclave_offset = std::nullopt)
override
247 emit(format_to_text(ll, enclave_offset));
254 static inline std::vector<std::unique_ptr<AbstractLogger>>&
loggers()
256 return get_loggers();
261 get_loggers().emplace_back(std::make_unique<TextConsoleLogger>());
266 get_loggers().emplace_back(std::make_unique<JsonConsoleLogger>());
271 get_loggers().clear();
288 static inline std::vector<std::unique_ptr<AbstractLogger>>& get_loggers()
290 static std::vector<std::unique_ptr<AbstractLogger>> the_loggers;
310#pragma clang diagnostic push
311#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
317#if defined(__clang__) && __clang_major__ >= 12
318# define CCF_FMT_STRING(s) (s)
320# define CCF_FMT_STRING(s) FMT_STRING(s)
330#define CCF_LOG_OUT(LVL, TAG) \
331 ccf::logger::config::ok(ccf::LoggerLevel::LVL) && \
332 ccf::logger::Out() == \
333 ccf::logger::LogLine(ccf::LoggerLevel::LVL, TAG, __FILE__, __LINE__)
338#define CCF_LOG_FMT_2(s, ...) fmt::format(CCF_FMT_STRING(s), ##__VA_ARGS__)
339#define CCF_LOG_FMT(LVL, TAG) CCF_LOG_OUT(LVL, TAG) << CCF_LOG_FMT_2
345 LOG_INFO_FMT [[deprecated(
"Use CCF_APP_INFO instead")]],
346 LOG_FAIL_FMT [[deprecated(
"Use CCF_APP_FAIL instead")]],
350#ifndef CCF_LOGGER_NO_DEPRECATE
351# define CCF_LOGGER_DEPRECATE(MACRO) ccf::logger::macro::MACRO;
353# define CCF_LOGGER_DEPRECATE(MACRO)
356#define LOG_TRACE_FMT CCF_LOGGER_DEPRECATE(LOG_TRACE_FMT) CCF_LOG_FMT(TRACE, "")
357#define LOG_DEBUG_FMT CCF_LOGGER_DEPRECATE(LOG_DEBUG_FMT) CCF_LOG_FMT(DEBUG, "")
359#define CCF_APP_TRACE CCF_LOG_FMT(TRACE, "app")
360#define CCF_APP_DEBUG CCF_LOG_FMT(DEBUG, "app")
362#define LOG_INFO_FMT CCF_LOGGER_DEPRECATE(LOG_INFO_FMT) CCF_LOG_FMT(INFO, "")
363#define LOG_FAIL_FMT CCF_LOGGER_DEPRECATE(LOG_FAIL_FMT) CCF_LOG_FMT(FAIL, "")
364#define LOG_FATAL_FMT CCF_LOGGER_DEPRECATE(LOG_FATAL_FMT) CCF_LOG_FMT(FATAL, "")
366#define CCF_APP_INFO CCF_LOG_FMT(INFO, "app")
367#define CCF_APP_FAIL CCF_LOG_FMT(FAIL, "app")
368#define CCF_APP_FATAL CCF_LOG_FMT(FATAL, "app")
370#pragma clang diagnostic pop
void write(const LogLine &ll, const std::optional< double > &enclave_offset=std::nullopt) override
Definition logger.h:243