#pragma once #include #include #include #include namespace wowee { namespace core { enum class LogLevel { DEBUG, INFO, WARNING, ERROR, FATAL }; class Logger { public: static Logger& getInstance(); void log(LogLevel level, const std::string& message); void setLogLevel(LogLevel level); template void debug(Args&&... args) { log(LogLevel::DEBUG, format(std::forward(args)...)); } template void info(Args&&... args) { log(LogLevel::INFO, format(std::forward(args)...)); } template void warning(Args&&... args) { log(LogLevel::WARNING, format(std::forward(args)...)); } template void error(Args&&... args) { log(LogLevel::ERROR, format(std::forward(args)...)); } template void fatal(Args&&... args) { log(LogLevel::FATAL, format(std::forward(args)...)); } private: Logger() = default; ~Logger() = default; Logger(const Logger&) = delete; Logger& operator=(const Logger&) = delete; template std::string format(Args&&... args) { std::ostringstream oss; (oss << ... << args); return oss.str(); } LogLevel minLevel = LogLevel::DEBUG; std::mutex mutex; }; // Convenience macros #define LOG_DEBUG(...) wowee::core::Logger::getInstance().debug(__VA_ARGS__) #define LOG_INFO(...) wowee::core::Logger::getInstance().info(__VA_ARGS__) #define LOG_WARNING(...) wowee::core::Logger::getInstance().warning(__VA_ARGS__) #define LOG_ERROR(...) wowee::core::Logger::getInstance().error(__VA_ARGS__) #define LOG_FATAL(...) wowee::core::Logger::getInstance().fatal(__VA_ARGS__) } // namespace core } // namespace wowee