21#ifdef CCF_DISABLE_VERBOSE_LOGGING
28 static constexpr const char* LevelNames[] = {
29 "trace",
"debug",
"info",
"fail",
"fatal"};
31 static constexpr const char* to_string(
LoggerLevel l)
33 return LevelNames[
static_cast<int>(l)];
36 static constexpr long int ns_per_s = 1'000'000'000;
38 static constexpr auto preamble_length = 45u;
40#ifdef CCF_RAFT_TRACING
41 static size_t logical_clock = 0;
54 std::ostringstream
ss;
59 std::string_view tag_,
60 std::string_view file_name_,
62 std::optional<uint16_t> thread_id_ = std::nullopt) :
68 if (thread_id_.has_value())
101 static std::string get_timestamp(
const std::tm& tm, const ::timespec& ts)
103#ifdef CCF_RAFT_TRACING
104 return std::to_string(logical_clock++);
107 return fmt::format(
"{:%Y-%m-%dT%H:%M:%S}.{:0>6}Z", tm, ts.tv_nsec / 1000);
117 virtual void emit(
const std::string& s)
119 std::cout.write(s.c_str(), s.size());
125 const std::optional<double>& enclave_offset = std::nullopt) = 0;
128#ifndef INSIDE_ENCLAVE
134 const std::optional<double>& enclave_offset = std::nullopt)
override
138 ::timespec_get(&host_ts, TIME_UTC);
140 ::gmtime_r(&host_ts.tv_sec, &host_tm);
142# ifdef CCF_RAFT_TRACING
143 auto escaped_msg = ll.
msg;
144 if (!nlohmann::json::accept(escaped_msg))
149 escaped_msg = nlohmann::json(ll.
msg).dump();
152 const auto escaped_msg = nlohmann::json(ll.
msg).dump();
156 if (enclave_offset.has_value())
158 ::timespec enc_ts = host_ts;
159 enc_ts.tv_sec += (size_t)enclave_offset.value();
161 (
long long)(enclave_offset.value() * ns_per_s) % ns_per_s;
163 if (enc_ts.tv_nsec > ns_per_s)
166 enc_ts.tv_nsec -= ns_per_s;
170 gmtime_r(&enc_ts.tv_sec, &enclave_tm);
173 "{{\"h_ts\":\"{}\",\"e_ts\":\"{}\",\"thread_id\":\"{}\",\"level\":\"{"
174 "}\",\"tag\":\"{}\",\"file\":\"{}\",\"number\":\"{}\",\"msg\":{}}}\n",
175 get_timestamp(host_tm, host_ts),
176 get_timestamp(enclave_tm, enc_ts),
187 "{{\"h_ts\":\"{}\",\"thread_id\":\"{}\",\"level\":\"{}\",\"tag\":\"{}"
188 "\",\"file\":\"{}\",\"number\":\"{}\",\"msg\":{}}}\n",
189 get_timestamp(host_tm, host_ts),
202 static std::string format_to_text(
204 const std::optional<double>& enclave_offset = std::nullopt)
208 ::timespec_get(&host_ts, TIME_UTC);
210 ::gmtime_r(&host_ts.tv_sec, &host_tm);
212 auto file_line = fmt::format(
"{}:{} ", ll.file_name, ll.line_number);
213 auto file_line_data = file_line.data();
217 auto preamble = fmt::format(
219 to_string(ll.log_level),
220 (ll.tag.empty() ?
"" : fmt::format(
"[{}]", ll.tag)))
221 .substr(0, preamble_length);
222 const auto max_file_line_len = preamble_length - preamble.size();
224 const auto len = file_line.size();
225 if (len > max_file_line_len)
227 file_line_data += len - max_file_line_len;
230 preamble += file_line_data;
232 if (enclave_offset.has_value())
238 "{} {:+01.3f} {:<3} {:<45}| {}\n",
239 get_timestamp(host_tm, host_ts),
240 enclave_offset.value(),
250 "{} {:<3} {:<45}| {}\n",
251 get_timestamp(host_tm, host_ts),
263 const std::optional<double>& enclave_offset = std::nullopt)
override
265 emit(format_to_text(ll, enclave_offset));
273 static inline std::vector<std::unique_ptr<AbstractLogger>>&
loggers()
275 return get_loggers();
278#ifndef INSIDE_ENCLAVE
281 get_loggers().emplace_back(std::make_unique<TextConsoleLogger>());
286 get_loggers().emplace_back(std::make_unique<JsonConsoleLogger>());
291 get_loggers().clear();
309 static inline std::vector<std::unique_ptr<AbstractLogger>>& get_loggers()
311 static std::vector<std::unique_ptr<AbstractLogger>> the_loggers;
331#pragma clang diagnostic push
332#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
338#if defined(__clang__) && __clang_major__ >= 12
339# define CCF_FMT_STRING(s) (s)
341# define CCF_FMT_STRING(s) FMT_STRING(s)
351#define CCF_LOG_OUT(LVL, TAG) \
352 ccf::logger::config::ok(LoggerLevel::LVL) && \
353 ccf::logger::Out() == \
354 ccf::logger::LogLine(LoggerLevel::LVL, TAG, __FILE__, __LINE__)
359#define CCF_LOG_FMT_2(s, ...) fmt::format(CCF_FMT_STRING(s), ##__VA_ARGS__)
360#define CCF_LOG_FMT(LVL, TAG) CCF_LOG_OUT(LVL, TAG) << CCF_LOG_FMT_2
366 LOG_INFO_FMT [[deprecated(
"Use CCF_APP_INFO instead")]],
367 LOG_FAIL_FMT [[deprecated(
"Use CCF_APP_FAIL instead")]],
371#ifndef CCF_LOGGER_NO_DEPRECATE
372# define CCF_LOGGER_DEPRECATE(MACRO) ccf::logger::macro::MACRO;
374# define CCF_LOGGER_DEPRECATE(MACRO)
377#ifndef CCF_DISABLE_VERBOSE_LOGGING
378# define LOG_TRACE_FMT \
379 CCF_LOGGER_DEPRECATE(LOG_TRACE_FMT) CCF_LOG_FMT(TRACE, "")
380# define LOG_DEBUG_FMT \
381 CCF_LOGGER_DEPRECATE(LOG_DEBUG_FMT) CCF_LOG_FMT(DEBUG, "")
383# define CCF_APP_TRACE CCF_LOG_FMT(TRACE, "app")
384# define CCF_APP_DEBUG CCF_LOG_FMT(DEBUG, "app")
388# define LOG_TRACE_FMT(...) CCF_LOGGER_DEPRECATE(LOG_TRACE_FMT)((void)0)
389# define LOG_DEBUG_FMT(...) CCF_LOGGER_DEPRECATE(LOG_DEBUG_FMT)((void)0)
391# define CCF_APP_TRACE(...) ((void)0)
392# define CCF_APP_DEBUG(...) ((void)0)
395#define LOG_INFO_FMT CCF_LOGGER_DEPRECATE(LOG_INFO_FMT) CCF_LOG_FMT(INFO, "")
396#define LOG_FAIL_FMT CCF_LOGGER_DEPRECATE(LOG_FAIL_FMT) CCF_LOG_FMT(FAIL, "")
397#define LOG_FATAL_FMT CCF_LOGGER_DEPRECATE(LOG_FATAL_FMT) CCF_LOG_FMT(FATAL, "")
399#define CCF_APP_INFO CCF_LOG_FMT(INFO, "app")
400#define CCF_APP_FAIL CCF_LOG_FMT(FAIL, "app")
401#define CCF_APP_FATAL CCF_LOG_FMT(FATAL, "app")
403#pragma clang diagnostic pop
void write(const LogLine &ll, const std::optional< double > &enclave_offset=std::nullopt) override
Definition logger.h:261
LogLine(LoggerLevel level_, std::string_view tag_, std::string_view file_name_, size_t line_number_, std::optional< uint16_t > thread_id_=std::nullopt)
Definition logger.h:57