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 // 66 template <typename T> 67 Logger& operator<<([[maybe_unused]] T const& value) 68 { 69 if (level >= getCurrentLogLevel()) 70 { 71 #ifdef BMCWEB_ENABLE_LOGGING 72 stringstream << value; 73 #endif 74 } 75 return *this; 76 } 77 78 // 79 static void setLogLevel(LogLevel level) 80 { 81 getLogLevelRef() = level; 82 } 83 84 static LogLevel getCurrentLogLevel() 85 { 86 return getLogLevelRef(); 87 } 88 89 private: 90 // 91 static LogLevel& getLogLevelRef() 92 { 93 static auto currentLevel = static_cast<LogLevel>(1); 94 return currentLevel; 95 } 96 97 // 98 std::ostringstream stringstream; 99 LogLevel level; 100 }; 101 } // namespace crow 102 103 #define BMCWEB_LOG_CRITICAL \ 104 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Critical) \ 105 crow::Logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical) 106 #define BMCWEB_LOG_ERROR \ 107 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Error) \ 108 crow::Logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error) 109 #define BMCWEB_LOG_WARNING \ 110 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Warning) \ 111 crow::Logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning) 112 #define BMCWEB_LOG_INFO \ 113 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Info) \ 114 crow::Logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info) 115 #define BMCWEB_LOG_DEBUG \ 116 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Debug) \ 117 crow::Logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug) 118