1 #pragma once 2 3 #include <cstdio> 4 #include <cstdlib> 5 #include <ctime> 6 #include <filesystem> 7 #include <iostream> 8 #include <sstream> 9 #include <string> 10 11 namespace crow 12 { 13 enum class LogLevel 14 { 15 Debug = 0, 16 Info, 17 Warning, 18 Error, 19 Critical, 20 }; 21 22 class Logger 23 { 24 private: 25 // 26 static std::string timestamp() 27 { 28 std::string date; 29 date.resize(32, '\0'); 30 time_t t = time(nullptr); 31 32 tm myTm{}; 33 34 gmtime_r(&t, &myTm); 35 36 size_t sz = 37 strftime(date.data(), date.size(), "%Y-%m-%d %H:%M:%S", &myTm); 38 date.resize(sz); 39 return date; 40 } 41 42 public: 43 Logger([[maybe_unused]] const std::string& prefix, 44 [[maybe_unused]] const std::string& filename, 45 [[maybe_unused]] const size_t line, LogLevel levelIn) : 46 level(levelIn) 47 { 48 #ifdef BMCWEB_ENABLE_LOGGING 49 stringstream << "(" << timestamp() << ") [" << prefix << " " 50 << std::filesystem::path(filename).filename() << ":" 51 << line << "] "; 52 #endif 53 } 54 ~Logger() 55 { 56 if (level >= getCurrentLogLevel()) 57 { 58 #ifdef BMCWEB_ENABLE_LOGGING 59 stringstream << std::endl; 60 std::cerr << stringstream.str(); 61 #endif 62 } 63 } 64 65 Logger(const Logger&) = delete; 66 Logger(Logger&&) = delete; 67 Logger& operator=(const Logger&) = delete; 68 Logger& operator=(const Logger&&) = delete; 69 70 // 71 template <typename T> 72 Logger& operator<<([[maybe_unused]] T const& value) 73 { 74 if (level >= getCurrentLogLevel()) 75 { 76 #ifdef BMCWEB_ENABLE_LOGGING 77 stringstream << value; 78 #endif 79 } 80 return *this; 81 } 82 83 // 84 static void setLogLevel(LogLevel level) 85 { 86 getLogLevelRef() = level; 87 } 88 89 static LogLevel getCurrentLogLevel() 90 { 91 return getLogLevelRef(); 92 } 93 94 private: 95 // 96 static LogLevel& getLogLevelRef() 97 { 98 static auto currentLevel = static_cast<LogLevel>(1); 99 return currentLevel; 100 } 101 102 // 103 std::ostringstream stringstream; 104 LogLevel level; 105 }; 106 } // namespace crow 107 108 #define BMCWEB_LOG_CRITICAL \ 109 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Critical) \ 110 crow::Logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical) 111 #define BMCWEB_LOG_ERROR \ 112 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Error) \ 113 crow::Logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error) 114 #define BMCWEB_LOG_WARNING \ 115 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Warning) \ 116 crow::Logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning) 117 #define BMCWEB_LOG_INFO \ 118 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Info) \ 119 crow::Logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info) 120 #define BMCWEB_LOG_DEBUG \ 121 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Debug) \ 122 crow::Logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug) 123