#pragma once #include #ifdef __linux__ #include #endif #include #include "third-party/fmt/core.h" namespace lg { #ifdef __linux__ struct LogTime { timeval tv; }; #else struct LogTime { time_t tim; }; #endif // Logging API enum class level { trace = 0, debug = 1, info = 2, warn = 3, error = 4, die = 5, off = 6 }; namespace internal { // log implementation stuff, not to be called by the user void log_message(level log_level, LogTime& now, const char* message); } // namespace internal void set_file(const std::string& filename); void set_flush_level(level log_level); void set_file_level(level log_level); void set_stdout_level(level log_level); void set_max_debug_levels(); void initialize(); void finish(); template void log(level log_level, const std::string& format, Args&&... args) { LogTime now; #ifdef __linux__ gettimeofday(&now.tv, nullptr); #else now.tim = time(nullptr); #endif std::string formatted_message = fmt::format(format, std::forward(args)...); internal::log_message(log_level, now, formatted_message.c_str()); } template void trace(const std::string& format, Args&&... args) { log(level::trace, format, std::forward(args)...); } template void debug(const std::string& format, Args&&... args) { log(level::debug, format, std::forward(args)...); } template void info(const std::string& format, Args&&... args) { log(level::info, format, std::forward(args)...); } template void warn(const std::string& format, Args&&... args) { log(level::warn, format, std::forward(args)...); } template void error(const std::string& format, Args&&... args) { log(level::error, format, std::forward(args)...); } template void die(const std::string& format, Args&&... args) { log(level::die, format, std::forward(args)...); } } // namespace lg