#pragma once #include #include #include #include #include #include namespace jlog { enum class severity { none, verbose, debug, warning, error, fatal }; static std::string get_timestamp() { using namespace std::chrono; auto const timestamp = current_zone()->to_local(system_clock::now()); auto dp = floor(timestamp); year_month_day ymd{floor(timestamp)}; hh_mm_ss time{floor(timestamp-dp)}; auto y = ymd.year(); auto m = ymd.month(); auto d = ymd.day(); auto h = time.hours(); auto M = time.minutes(); auto s = time.seconds(); auto ms = time.subseconds(); return std::format("{}-{}-{} {}:{}:{}.{}", y, m, d, h.count(), M.count(), s.count(), ms.count()); } static bool lib_initialized = false; static std::vector> outputs; static void add_output(std::ostream* output) { if (!lib_initialized) throw std::runtime_error("jlog::init() ya dumbfuck!!!"); outputs.push_back(std::shared_ptr(output)); } static void add_output(std::shared_ptr output) { outputs.push_back(std::move(output)); } struct LogEntry { severity level; std::string content; std::string timestamp; }; static void log_to_console(const std::string& message) { std::cout << message << std::endl; } static void log_to_file(const std::string& message) { std::ofstream latest_log("latest.log"); latest_log << message << std::endl; } static Event on_log; static std::vector log_history; static void log(const std::string& message) { auto output = std::format("[{}] {}", get_timestamp(), message); log_to_console(output); log_to_file(output); on_log({.level = severity::none, .content = message, .timestamp = get_timestamp()}); } static void log(const std::string& contextColorCode, const std::string& context, const std::string& message) { log_to_console(std::format("[{}] {}[{}]{} {}", get_timestamp(), contextColorCode, context, ansi_escape_codes::RESET, message)); log_to_file(std::format("[{}] [{}] {}", get_timestamp(), context, message)); on_log({.level = severity::none, .content = message, .timestamp = get_timestamp()}); } void direct(const std::string& message) { log(message);}; void info(const std::string& message) {log(ansi_escape_codes::FG_WHITE, "INFO", message); } static void verbose(const std::string& message) { log(ansi_escape_codes::FG_CYAN, "VERBOSE", message); } static void debug (const std::string& message) { log(ansi_escape_codes::FG_GREEN, "DEBUG", message); } static void warning(const std::string& message) { log(ansi_escape_codes::FG_YELLOW, "WARNING", message); } static void error (const std::string& message) { log(ansi_escape_codes::FG_BRIGHT_RED, "ERROR", message); } static void fatal (const std::string& message) { log(ansi_escape_codes::FG_RED, "FATAL", message); } static void init() {} static void flush() {} }