diff --git a/DGWTimeServer/DGWTimeServerApp.cpp b/DGWTimeServer/DGWTimeServerApp.cpp index 7fb39d2..eebb8d2 100644 --- a/DGWTimeServer/DGWTimeServerApp.cpp +++ b/DGWTimeServer/DGWTimeServerApp.cpp @@ -29,6 +29,8 @@ #include "Version.h" #include "Log.h" #include "Daemon.h" +#include "LogConsoleTarget.h" +#include "LogFileTarget.h" CDGWTimeServerApp * CDGWTimeServerApp::g_app = nullptr; const std::string BANNER_1 = CStringUtils::string_format("%s v%s Copyright (C) %s\n", APPLICATION_NAME.c_str(), LONG_VERSION.c_str(), VENDOR_NAME.c_str()); @@ -57,11 +59,13 @@ int main(int argc, char * argv[]) return 0; } + // Load config std::string configfile(argv[1]); CTimeServerConfig config(configfile); if(!config.load()) return 1; + // Do daemon stuff TDaemon daemon; config.getDameon(daemon); if (daemon.daemon) { @@ -83,14 +87,21 @@ int main(int argc, char * argv[]) } } - CDGWTimeServerApp app(&config); + // Setup Log + TLog logConf; + config.getLog(logConf); + CLog::finalise(); + if(logConf.displayLevel != LOG_NONE && !daemon.daemon) CLog::addTarget(new CLogConsoleTarget(logConf.displayLevel)); + if(logConf.fileLevel != LOG_NONE) CLog::addTarget(new CLogFileTarget(logConf.fileLevel, logConf.logDir, logConf.fileRoot, logConf.fileRotate)); - if(!app.init()) + // Start the app + CDGWTimeServerApp app(&config); + if(app.init()) { + app.run(); return 0; + } - app.run(); - - return 0; + return 1; } CDGWTimeServerApp::CDGWTimeServerApp(const CTimeServerConfig * config) : diff --git a/DGWTimeServer/TimeServerConfig.cpp b/DGWTimeServer/TimeServerConfig.cpp index dd03332..d2c4fab 100644 --- a/DGWTimeServer/TimeServerConfig.cpp +++ b/DGWTimeServer/TimeServerConfig.cpp @@ -20,7 +20,6 @@ #include #include "TimeServerConfig.h" -#include "Log.h" #include "StringUtils.h" CTimeServerConfig::CTimeServerConfig(const std::string &pathname) : @@ -50,6 +49,7 @@ bool CTimeServerConfig::load() ret = loadRepeaters(cfg) && ret; ret = loadDaemon(cfg) && ret; ret = loadPaths(cfg) && ret; + ret = loadLog(cfg) && ret; } return ret; @@ -150,6 +150,42 @@ bool CTimeServerConfig::loadPaths(const CConfig & cfg) return ret; } +bool CTimeServerConfig::loadLog(const CConfig & cfg) +{ + bool ret = cfg.getValue("log", "path", m_log.logDir, 0, 2048, "/var/log/dstargateway/"); + if(ret && m_log.logDir[m_log.logDir.length() - 1] != '/') { + m_log.logDir.push_back('/'); + } + + ret = cfg.getValue("log", "fileRoot", m_log.fileRoot, 0, 64, "dgwtimeserver") && ret; + ret = cfg.getValue("log", "fileRotate", m_log.fileRotate, true) && ret; + + std::string levelStr; + ret = cfg.getValue("log", "fileLevel", levelStr, "info", {"trace", "debug", "info", "warning", "error", "fatal", "none"}) && ret; + if(ret) { + if(levelStr == "trace") m_log.fileLevel = LOG_TRACE; + else if(levelStr == "debug") m_log.fileLevel = LOG_DEBUG; + else if(levelStr == "info") m_log.fileLevel = LOG_INFO; + else if(levelStr == "warning") m_log.fileLevel = LOG_WARNING; + else if(levelStr == "error") m_log.fileLevel = LOG_ERROR; + else if(levelStr == "fatal") m_log.fileLevel = LOG_FATAL; + else if(levelStr == "none") m_log.fileLevel = LOG_NONE; + } + + ret = cfg.getValue("log", "displayLevel", levelStr, "info", {"trace", "debug", "info", "warning", "error", "fatal", "none"}) && ret; + if(ret) { + if(levelStr == "trace") m_log.displayLevel = LOG_TRACE; + else if(levelStr == "debug") m_log.displayLevel = LOG_DEBUG; + else if(levelStr == "info") m_log.displayLevel = LOG_INFO; + else if(levelStr == "warning") m_log.displayLevel = LOG_WARNING; + else if(levelStr == "error") m_log.displayLevel = LOG_ERROR; + else if(levelStr == "fatal") m_log.displayLevel = LOG_FATAL; + else if(levelStr == "none") m_log.displayLevel = LOG_NONE; + } + + return ret; +} + void CTimeServerConfig::getTimeServer(TTimeServer& timeserver) const { timeserver = m_timeServer; @@ -174,3 +210,8 @@ void CTimeServerConfig::getPaths(TPaths& paths) const { paths = m_paths; } + +void CTimeServerConfig::getLog(TLog& log) const +{ + log = m_log; +} diff --git a/DGWTimeServer/TimeServerConfig.h b/DGWTimeServer/TimeServerConfig.h index a28d36d..7eeaacf 100644 --- a/DGWTimeServer/TimeServerConfig.h +++ b/DGWTimeServer/TimeServerConfig.h @@ -23,6 +23,7 @@ #include "Config.h" #include "TimeServerDefs.h" +#include "Log.h" typedef struct { std::string callsign; @@ -46,6 +47,14 @@ typedef struct { std::string data; } TPaths; +typedef struct { + std::string logDir; + LOG_SEVERITY displayLevel; + LOG_SEVERITY fileLevel; + std::string fileRoot; + bool fileRotate; +} TLog; + class CTimeServerConfig { public: @@ -58,6 +67,7 @@ public: unsigned int getRepeaterCount() const; void getRepeater(unsigned int idx, TRepeater& repeater) const; void getPaths(TPaths& paths) const; + void getLog(TLog& log) const; private: bool open(CConfig & cfg); @@ -65,10 +75,12 @@ private: bool loadTimeServer(const CConfig & cfg); bool loadDaemon(const CConfig & cfg); bool loadPaths(const CConfig & cfg); + bool loadLog(const CConfig & cfg); std::string m_fileName; std::vector m_repeaters; TTimeServer m_timeServer; TDaemon m_daemon; TPaths m_paths; + TLog m_log; }; diff --git a/DGWTimeServer/example.cfg b/DGWTimeServer/example.cfg index a643d60..94a823a 100644 --- a/DGWTimeServer/example.cfg +++ b/DGWTimeServer/example.cfg @@ -25,6 +25,12 @@ band= # Module letter of the repeater enabled=false # enable time beacons on this repeater band= # Module letter of the repeater +[Log] +path=/var/log/dstargateway/ +fileRoot= # defaults to dgwtimeserver +fileRotate= # rotate log files daily, defaults to true +fileLevel= # defaults to info, valid values are trace, debug, info, warning, error, fatal, none +displayLevel= # defaults to info, valid values are trace, debug, info, warning, error, fatal, none # Provided install routines install the program as a systemd unit. SystemD does not recommand "old-school" forking daemons nor does systemd # require a pid file. Moreover systemd handles the user under which the program is started. This is provided as convenience for people who might diff --git a/DStarGateway/DStarGatewayApp.cpp b/DStarGateway/DStarGatewayApp.cpp index d0d5c52..634dd41 100644 --- a/DStarGateway/DStarGatewayApp.cpp +++ b/DStarGateway/DStarGatewayApp.cpp @@ -115,8 +115,8 @@ int main(int argc, char *argv[]) TLog logConf; config->getLog(logConf); CLog::finalise(); - if(logConf.m_displayLevel != LOG_NONE && !daemon.daemon) CLog::addTarget(new CLogConsoleTarget(logConf.m_displayLevel)); - if(logConf.m_fileLevel != LOG_NONE) CLog::addTarget(new CLogFileTarget(logConf.m_fileLevel, logConf.logDir, logConf.m_fileRotate)); + if(logConf.displayLevel != LOG_NONE && !daemon.daemon) CLog::addTarget(new CLogConsoleTarget(logConf.displayLevel)); + if(logConf.fileLevel != LOG_NONE) CLog::addTarget(new CLogFileTarget(logConf.fileLevel, logConf.logDir, logConf.fileRoot, logConf.fileRotate)); //write banner in log file if we are dameon if(daemon.daemon) { diff --git a/DStarGateway/DStarGatewayConfig.cpp b/DStarGateway/DStarGatewayConfig.cpp index 0afd547..77f8086 100644 --- a/DStarGateway/DStarGatewayConfig.cpp +++ b/DStarGateway/DStarGatewayConfig.cpp @@ -153,34 +153,32 @@ bool CDStarGatewayConfig::loadLog(const CConfig & cfg) m_log.logDir.push_back('/'); } - ret = cfg.getValue("log", "fileRoot", m_log.m_fileRoot, 0, 64, "dstargateway") && ret; - ret = cfg.getValue("log", "fileRotate", m_log.m_fileRotate, true) && ret; + ret = cfg.getValue("log", "fileRoot", m_log.fileRoot, 0, 64, "dstargateway") && ret; + ret = cfg.getValue("log", "fileRotate", m_log.fileRotate, true) && ret; std::string levelStr; ret = cfg.getValue("log", "fileLevel", levelStr, "info", {"trace", "debug", "info", "warning", "error", "fatal", "none"}) && ret; if(ret) { - if(levelStr == "trace") m_log.m_fileLevel = LOG_TRACE; - else if(levelStr == "debug") m_log.m_fileLevel = LOG_DEBUG; - else if(levelStr == "info") m_log.m_fileLevel = LOG_INFO; - else if(levelStr == "warning") m_log.m_fileLevel = LOG_WARNING; - else if(levelStr == "error") m_log.m_fileLevel = LOG_ERROR; - else if(levelStr == "fatal") m_log.m_fileLevel = LOG_FATAL; - else if(levelStr == "none") m_log.m_fileLevel = LOG_NONE; + if(levelStr == "trace") m_log.fileLevel = LOG_TRACE; + else if(levelStr == "debug") m_log.fileLevel = LOG_DEBUG; + else if(levelStr == "info") m_log.fileLevel = LOG_INFO; + else if(levelStr == "warning") m_log.fileLevel = LOG_WARNING; + else if(levelStr == "error") m_log.fileLevel = LOG_ERROR; + else if(levelStr == "fatal") m_log.fileLevel = LOG_FATAL; + else if(levelStr == "none") m_log.fileLevel = LOG_NONE; } ret = cfg.getValue("log", "displayLevel", levelStr, "info", {"trace", "debug", "info", "warning", "error", "fatal", "none"}) && ret; if(ret) { - if(levelStr == "trace") m_log.m_displayLevel = LOG_TRACE; - else if(levelStr == "debug") m_log.m_displayLevel = LOG_DEBUG; - else if(levelStr == "info") m_log.m_displayLevel = LOG_INFO; - else if(levelStr == "warning") m_log.m_displayLevel = LOG_WARNING; - else if(levelStr == "error") m_log.m_displayLevel = LOG_ERROR; - else if(levelStr == "fatal") m_log.m_displayLevel = LOG_FATAL; - else if(levelStr == "none") m_log.m_displayLevel = LOG_NONE; + if(levelStr == "trace") m_log.displayLevel = LOG_TRACE; + else if(levelStr == "debug") m_log.displayLevel = LOG_DEBUG; + else if(levelStr == "info") m_log.displayLevel = LOG_INFO; + else if(levelStr == "warning") m_log.displayLevel = LOG_WARNING; + else if(levelStr == "error") m_log.displayLevel = LOG_ERROR; + else if(levelStr == "fatal") m_log.displayLevel = LOG_FATAL; + else if(levelStr == "none") m_log.displayLevel = LOG_NONE; } - //TODO 20211226 check if directories are accessible - return ret; } diff --git a/DStarGateway/DStarGatewayConfig.h b/DStarGateway/DStarGatewayConfig.h index dec8ca5..1bfce6c 100644 --- a/DStarGateway/DStarGatewayConfig.h +++ b/DStarGateway/DStarGatewayConfig.h @@ -86,10 +86,10 @@ typedef struct { typedef struct { std::string logDir; - LOG_SEVERITY m_displayLevel; - LOG_SEVERITY m_fileLevel; - std::string m_fileRoot; - bool m_fileRotate; + LOG_SEVERITY displayLevel; + LOG_SEVERITY fileLevel; + std::string fileRoot; + bool fileRotate; } TLog; typedef struct {