| #pragma once |
| |
| #include <cstdio> |
| #include <cstdlib> |
| #include <ctime> |
| #include <iostream> |
| #include <sstream> |
| #include <string> |
| |
| namespace crow { |
| enum class LogLevel { |
| #ifndef ERROR |
| DEBUG = 0, |
| INFO, |
| WARNING, |
| ERROR, |
| CRITICAL, |
| #endif |
| |
| Debug = 0, |
| Info, |
| Warning, |
| Error, |
| Critical, |
| }; |
| |
| class ILogHandler { |
| public: |
| virtual void log(std::string message, LogLevel level) = 0; |
| }; |
| |
| class CerrLogHandler : public ILogHandler { |
| public: |
| void log(std::string message, LogLevel /*level*/) override { |
| std::cerr << message; |
| } |
| }; |
| |
| class logger { |
| private: |
| // |
| static std::string timestamp() { |
| char date[32]; |
| time_t t = time(0); |
| |
| tm myTm{}; |
| |
| #ifdef _MSC_VER |
| gmtime_s(&my_tm, &t); |
| #else |
| gmtime_r(&t, &myTm); |
| #endif |
| |
| size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &myTm); |
| return std::string(date, date + sz); |
| } |
| |
| public: |
| logger(const std::string& prefix, LogLevel level) : level(level) { |
| #ifdef BMCWEB_ENABLE_LOGGING |
| stringstream << "(" << timestamp() << ") [" << prefix << "] "; |
| #endif |
| } |
| ~logger() { |
| #ifdef BMCWEB_ENABLE_LOGGING |
| if (level >= get_current_log_level()) { |
| stringstream << std::endl; |
| getHandlerRef()->log(stringstream.str(), level); |
| } |
| #endif |
| } |
| |
| // |
| template <typename T> |
| logger& operator<<(T const& value) { |
| #ifdef BMCWEB_ENABLE_LOGGING |
| if (level >= get_current_log_level()) { |
| stringstream << value; |
| } |
| #endif |
| return *this; |
| } |
| |
| // |
| static void setLogLevel(LogLevel level) { getLogLevelRef() = level; } |
| |
| static void setHandler(ILogHandler* handler) { getHandlerRef() = handler; } |
| |
| static LogLevel get_current_log_level() { return getLogLevelRef(); } |
| |
| private: |
| // |
| static LogLevel& getLogLevelRef() { |
| static auto currentLevel = static_cast<LogLevel>(1); |
| return currentLevel; |
| } |
| static ILogHandler*& getHandlerRef() { |
| static CerrLogHandler defaultHandler; |
| static ILogHandler* currentHandler = &defaultHandler; |
| return currentHandler; |
| } |
| |
| // |
| std::ostringstream stringstream; |
| LogLevel level; |
| }; |
| } // namespace crow |
| |
| #define BMCWEB_LOG_CRITICAL \ |
| if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \ |
| crow::logger("CRITICAL", crow::LogLevel::Critical) |
| #define BMCWEB_LOG_ERROR \ |
| if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \ |
| crow::logger("ERROR ", crow::LogLevel::Error) |
| #define BMCWEB_LOG_WARNING \ |
| if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \ |
| crow::logger("WARNING ", crow::LogLevel::Warning) |
| #define BMCWEB_LOG_INFO \ |
| if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \ |
| crow::logger("INFO ", crow::LogLevel::Info) |
| #define BMCWEB_LOG_DEBUG \ |
| if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \ |
| crow::logger("DEBUG ", crow::LogLevel::Debug) |