#pragma once #include #include #include #include #include #include #include #include enum class LogLevel { DEBUG_LEVEL_TRACE = 0, DEBUG_LEVEL_INFO = 1, DEBUG_LEVEL_WARN = 2, DEBUG_LEVEL_ERROR = 3, DEBUG_LEVEL_OFF = 4 }; inline LogLevel getLogLevelFromEnv() { const char *env = std::getenv("DEBUG_LEVEL"); if (!env) { return LogLevel::DEBUG_LEVEL_ERROR; } std::string level(env); std::transform(level.begin(), level.end(), level.begin(), ::tolower); if (level == "trace" || level == "0") return LogLevel::DEBUG_LEVEL_TRACE; if (level == "info" || level == "1") return LogLevel::DEBUG_LEVEL_INFO; if (level == "warn" || level == "2") return LogLevel::DEBUG_LEVEL_WARN; if (level == "error" || level == "3") return LogLevel::DEBUG_LEVEL_ERROR; if (level == "off" || level == "4") return LogLevel::DEBUG_LEVEL_OFF; return LogLevel::DEBUG_LEVEL_ERROR; } namespace Logger { inline LogLevel getCurrentLevel() { static const LogLevel currentLevel = getLogLevelFromEnv(); return currentLevel; } inline void info(std::string_view message) { if (static_cast(LogLevel::DEBUG_LEVEL_INFO) < static_cast(getCurrentLevel())) { return; } std::cout << "\033[32m[Info]\033[0m " << message << std::endl; } inline void warn(std::string_view message) { if (static_cast(LogLevel::DEBUG_LEVEL_WARN) < static_cast(getCurrentLevel())) { return; } std::clog << "\033[33m[Warn]\033[0m " << message << std::endl; } inline void error(std::string_view message) { if (static_cast(LogLevel::DEBUG_LEVEL_ERROR) < static_cast(getCurrentLevel())) { return; } std::cerr << "\033[31m[Error] " << message << "\033[0m" << std::endl; } } // namespace Logger inline void MessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { static const LogLevel currentLevel = getLogLevelFromEnv(); LogLevel msgLevel; std::string prefix; std::string color; std::string reset = "\033[0m"; switch (type) { case QtDebugMsg: msgLevel = LogLevel::DEBUG_LEVEL_TRACE; prefix = "[Trace]"; color = "\033[36m"; break; case QtInfoMsg: msgLevel = LogLevel::DEBUG_LEVEL_INFO; prefix = "[Info]"; color = "\033[32m"; break; case QtWarningMsg: msgLevel = LogLevel::DEBUG_LEVEL_WARN; prefix = "[Warn]"; color = "\033[33m"; break; case QtCriticalMsg: msgLevel = LogLevel::DEBUG_LEVEL_ERROR; prefix = "[Error]"; color = "\033[31m"; break; case QtFatalMsg: msgLevel = LogLevel::DEBUG_LEVEL_ERROR; prefix = "[Fatal]"; color = "\033[35m"; break; } if (static_cast(msgLevel) < static_cast(currentLevel)) { return; } std::string context_str = " "; if (context.file && context.line) { context_str = std::format(" ({}:{}) ", context.file, context.line); } std::cerr << color << prefix << reset << context_str << msg.toStdString() << std::endl; if (type == QtFatalMsg) { std::abort(); } }