Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:02:33

0001 #pragma once
0002 
0003 #include <iostream>
0004 #include <memory>
0005 #include <syslog.h>
0006 
0007 namespace nopayloadclient {
0008 namespace logging {
0009 
0010 enum class LogLevel {
0011     DEBUG,
0012     INFO,
0013     WARNING,
0014     ERROR
0015 };
0016 
0017 
0018 class ILogger {
0019 public:
0020     virtual ~ILogger() {}
0021     virtual void log(LogLevel level, const std::string& message) = 0;
0022 
0023     void setLogLevel(LogLevel level) {
0024         log_level_ = level;
0025     }
0026 
0027     void setLogLevel(const std::string& level_string) {
0028         LogLevel level = stringToLogLevel(level_string);
0029         setLogLevel(level);
0030     }
0031 
0032 protected:
0033     LogLevel log_level_ = LogLevel::INFO; // Default log level
0034     std::string mode_ = "terminal"; // one of [terminal, file, syslog]
0035 
0036     std::string logLevelToString(LogLevel level) {
0037         switch(level) {
0038             case LogLevel::DEBUG: return "DEBUG";
0039             case LogLevel::INFO: return "INFO";
0040             case LogLevel::WARNING: return "WARNING";
0041             case LogLevel::ERROR: return "ERROR";
0042             default: return "UNKNOWN";
0043         }
0044     }
0045 
0046     LogLevel stringToLogLevel(const std::string& level_string) {
0047         if (level_string == "DEBUG") return LogLevel::DEBUG;
0048         else if (level_string == "INFO") return LogLevel::INFO;
0049         else if (level_string == "WARNING") return LogLevel::WARNING;
0050         else if (level_string == "ERROR") return LogLevel::ERROR;
0051         throw std::invalid_argument("Invalid LogLevel string");
0052     }
0053 };
0054 
0055 
0056 class TerminalLogger : public ILogger {
0057 public:
0058     void log(LogLevel level, const std::string& message) override {
0059         if (level < log_level_) return; // Don't log messages below the set log level
0060         std::cout << "[" + logLevelToString(level) + "] " + message << std::endl;
0061     }
0062 };
0063 
0064 
0065 class SyslogLogger : public ILogger {
0066 private:
0067     bool is_open_ = false;
0068 
0069 public:
0070     ~SyslogLogger() {
0071         if (is_open_) closelog();
0072     }
0073 
0074     void log(LogLevel level, const std::string& message) override {
0075         if (!is_open_) {
0076             openlog("nopayloadclient", LOG_PID | LOG_CONS, LOG_USER);
0077             is_open_ = true;
0078         }
0079         int sys_log_level;
0080         switch(level) {
0081             case LogLevel::DEBUG: sys_log_level = LOG_DEBUG; break;
0082             case LogLevel::INFO: sys_log_level = LOG_INFO; break;
0083             case LogLevel::WARNING: sys_log_level = LOG_WARNING; break;
0084             case LogLevel::ERROR: sys_log_level = LOG_ERR; break;
0085             default: sys_log_level = LOG_WARNING; break;
0086         }
0087         syslog(sys_log_level, "%s", message.c_str());
0088     }
0089 };
0090 
0091 
0092 class LoggerManager {
0093 private:
0094     static std::unique_ptr<ILogger>& getLoggerInstance() {
0095         static std::unique_ptr<ILogger> logger = std::make_unique<TerminalLogger>();
0096         return logger;
0097     }
0098 
0099 public:
0100     static void setLogger(std::unique_ptr<ILogger> newLogger) {
0101         getLoggerInstance() = std::move(newLogger);
0102     }
0103 
0104     static ILogger& getLogger() {
0105         return *getLoggerInstance();
0106     }
0107 };
0108 
0109 
0110 inline void info(const std::string& msg) {
0111     LoggerManager::getLogger().log(LogLevel::INFO, msg);
0112 }
0113 inline void warning(const std::string& msg) {
0114     LoggerManager::getLogger().log(LogLevel::WARNING, msg);
0115 }
0116 inline void error(const std::string& msg) {
0117     LoggerManager::getLogger().log(LogLevel::ERROR, msg);
0118 }
0119 inline void debug(const std::string& msg) {
0120     LoggerManager::getLogger().log(LogLevel::DEBUG, msg);
0121 }
0122 
0123 inline void setLogger(const std::string& name) {
0124     if (name == "terminal") {
0125         LoggerManager::setLogger(std::make_unique<TerminalLogger>());
0126     }
0127     else if (name == "syslog") {
0128         LoggerManager::setLogger(std::make_unique<SyslogLogger>());
0129     }
0130     else {
0131         throw std::invalid_argument("Invalid logger choice");
0132     }
0133 }
0134 
0135 inline void setLogLevel(const std::string& level_string) {
0136     LoggerManager::getLogger().setLogLevel(level_string);
0137 }
0138 
0139 } // logging namespace
0140 } // nopayloadclient namespace