diff --git a/configs/config.example.yml b/configs/config.example.yml index b3f027b7..d1046423 100644 --- a/configs/config.example.yml +++ b/configs/config.example.yml @@ -23,6 +23,8 @@ log: displayLevel: 1 # File logging level. fileLevel: 1 + # Flag indicating file logs should be sent to syslog instead of a file. + useSyslog: false # Full path for the directory to store the log files. filePath: . # Full path for the directory to store the activity log files. diff --git a/configs/fne-config.example.yml b/configs/fne-config.example.yml index c73ae380..a46b1f03 100644 --- a/configs/fne-config.example.yml +++ b/configs/fne-config.example.yml @@ -24,6 +24,8 @@ log: fileLevel: 1 # Full path for the directory to store the log files. filePath: . + # Flag indicating file logs should be sent to syslog instead of a file. + useSyslog: false # Full path for the directory to store the activity log files. activityFilePath: . # Log filename prefix. diff --git a/src/common/Log.cpp b/src/common/Log.cpp index 3610865d..08e6c5c8 100644 --- a/src/common/Log.cpp +++ b/src/common/Log.cpp @@ -16,6 +16,7 @@ #include "network/BaseNetwork.h" #include +#include #if defined(CATCH2_TEST_COMPILATION) #include @@ -52,6 +53,8 @@ static FILE* m_fpLog = nullptr; uint32_t g_logDisplayLevel = 2U; bool g_disableTimeDisplay = false; +bool g_useSyslog = false; + static struct tm m_tm; static std::ostream m_outStream { std::cerr.rdbuf() }; @@ -92,27 +95,52 @@ static bool LogOpen() if (m_fileLevel == 0U) return true; - time_t now; - ::time(&now); + if (!g_useSyslog) { + time_t now; + ::time(&now); - struct tm* tm = ::gmtime(&now); + struct tm* tm = ::gmtime(&now); - if (tm->tm_mday == m_tm.tm_mday && tm->tm_mon == m_tm.tm_mon && tm->tm_year == m_tm.tm_year) { - if (m_fpLog != nullptr) - return true; - } - else { - if (m_fpLog != nullptr) - ::fclose(m_fpLog); - } + if (tm->tm_mday == m_tm.tm_mday && tm->tm_mon == m_tm.tm_mon && tm->tm_year == m_tm.tm_year) { + if (m_fpLog != nullptr) + return true; + } + else { + if (m_fpLog != nullptr) + ::fclose(m_fpLog); + } - char filename[200U]; - ::sprintf(filename, "%s/%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + char filename[200U]; + ::sprintf(filename, "%s/%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); - m_fpLog = ::fopen(filename, "a+t"); - m_tm = *tm; + m_fpLog = ::fopen(filename, "a+t"); + m_tm = *tm; - return m_fpLog != nullptr; + return m_fpLog != nullptr; + } + else { + switch (m_fileLevel) { + case 1U: + setlogmask(LOG_UPTO(LOG_DEBUG)); + break; + case 2U: + setlogmask(LOG_UPTO(LOG_INFO)); + break; + case 3U: + setlogmask(LOG_UPTO(LOG_NOTICE)); + break; + case 4U: + setlogmask(LOG_UPTO(LOG_WARNING)); + break; + case 5U: + default: + setlogmask(LOG_UPTO(LOG_ERR)); + break; + } + + openlog(m_fileRoot.c_str(), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON); + return true; + } } /// @@ -153,13 +181,16 @@ void LogSetNetwork(void* network) /// File logging level. /// Console logging level. /// Disable display of date/time on the console log. -bool LogInitialise(const std::string& filePath, const std::string& fileRoot, uint32_t fileLevel, uint32_t displayLevel, bool disableTimeDisplay) +/// Flag indicating whether or not logging should be sent to the syslog. +bool LogInitialise(const std::string& filePath, const std::string& fileRoot, uint32_t fileLevel, uint32_t displayLevel, bool disableTimeDisplay, bool useSyslog) { m_filePath = filePath; m_fileRoot = fileRoot; m_fileLevel = fileLevel; g_logDisplayLevel = displayLevel; g_disableTimeDisplay = disableTimeDisplay; + if (!g_useSyslog) + g_useSyslog = useSyslog; return ::LogOpen(); } @@ -173,6 +204,8 @@ void LogFinalise() #endif if (m_fpLog != nullptr) ::fclose(m_fpLog); + if (g_useSyslog) + closelog(); } /// @@ -189,7 +222,7 @@ void Log(uint32_t level, const char *module, const char* fmt, ...) g_disableTimeDisplay = true; #endif char buffer[LOG_BUFFER_LEN]; - if (!g_disableTimeDisplay) { + if (!g_disableTimeDisplay && !g_useSyslog) { struct timeval now; ::gettimeofday(&now, NULL); @@ -243,22 +276,52 @@ void Log(uint32_t level, const char *module, const char* fmt, ...) #endif if (level >= m_fileLevel && m_fileLevel != 0U) { - bool ret = ::LogOpen(); - if (!ret) - return; + if (!g_useSyslog) { + bool ret = ::LogOpen(); + if (!ret) + return; + + ::fprintf(m_fpLog, "%s\n", buffer); + ::fflush(m_fpLog); + } else { + // convert our log level into syslog level + int syslogLevel = LOG_INFO; + switch (level) { + case 1U: + syslogLevel = LOG_DEBUG; + break; + case 2U: + syslogLevel = LOG_NOTICE; + break; + case 3U: + syslogLevel = LOG_INFO; + break; + case 4U: + syslogLevel = LOG_WARNING; + break; + case 5U: + syslogLevel = LOG_ERR; + break; + default: + syslogLevel = LOG_EMERG; + break; + } - ::fprintf(m_fpLog, "%s\n", buffer); - ::fflush(m_fpLog); + syslog(syslogLevel, "%s", buffer); + } } - if (level >= g_logDisplayLevel && g_logDisplayLevel != 0U) { + if (!g_useSyslog && level >= g_logDisplayLevel && g_logDisplayLevel != 0U) { ::fprintf(stdout, "%s" EOL, buffer); ::fflush(stdout); } // fatal error (specially allow any log levels above 9999) if (level >= 6U && level < 9999U) { - ::fclose(m_fpLog); + if (m_fpLog != nullptr) + ::fclose(m_fpLog); + if (g_useSyslog) + ::closelog(); exit(1); } } diff --git a/src/common/Log.h b/src/common/Log.h index 866ac43f..ff1247e3 100644 --- a/src/common/Log.h +++ b/src/common/Log.h @@ -53,6 +53,8 @@ extern uint32_t g_logDisplayLevel; extern bool g_disableTimeDisplay; +extern bool g_useSyslog; + // --------------------------------------------------------------------------- // Global Functions // --------------------------------------------------------------------------- @@ -73,7 +75,7 @@ extern HOST_SW_API void* LogGetNetwork(); extern HOST_SW_API void LogSetNetwork(void* network); /// Initializes the diagnostics log. -extern HOST_SW_API bool LogInitialise(const std::string& filePath, const std::string& fileRoot, uint32_t fileLevel, uint32_t displayLevel, bool disableTimeDisplay = false); +extern HOST_SW_API bool LogInitialise(const std::string& filePath, const std::string& fileRoot, uint32_t fileLevel, uint32_t displayLevel, bool disableTimeDisplay = false, bool useSyslog = false); /// Finalizes the diagnostics log. extern HOST_SW_API void LogFinalise(); /// Writes a new entry to the diagnostics log. diff --git a/src/fne/FNEMain.cpp b/src/fne/FNEMain.cpp index 63408a1f..6c6be169 100644 --- a/src/fne/FNEMain.cpp +++ b/src/fne/FNEMain.cpp @@ -100,12 +100,15 @@ void usage(const char* message, const char* arg) ::fprintf(stdout, "usage: %s [-vhf]" + "[--syslog]" "[-c ]" "\n\n" " -v show version information\n" " -h show this screen\n" " -f foreground mode\n" "\n" + " --syslog force logging to syslog\n" + "\n" " -c specifies the configuration file to use\n" "\n" " -- stop handling options\n", @@ -140,6 +143,9 @@ int checkArgs(int argc, char* argv[]) else if (IS("-f")) { g_foreground = true; } + else if (IS("--syslog")) { + g_useSyslog = true; + } else if (IS("-c")) { if (argc-- <= 0) usage("error: %s", "must specify the configuration file to use"); diff --git a/src/fne/HostFNE.cpp b/src/fne/HostFNE.cpp index c82ffd96..9d433b8a 100644 --- a/src/fne/HostFNE.cpp +++ b/src/fne/HostFNE.cpp @@ -99,7 +99,7 @@ int HostFNE::run() // initialize system logging yaml::Node logConf = m_conf["log"]; ret = ::LogInitialise(logConf["filePath"].as(), logConf["fileRoot"].as(), - logConf["fileLevel"].as(0U), logConf["displayLevel"].as(0U)); + logConf["fileLevel"].as(0U), logConf["displayLevel"].as(0U), false, logConf["useSyslog"].as(false)); if (!ret) { ::fatal("unable to open the log file\n"); } diff --git a/src/host/Host.cpp b/src/host/Host.cpp index 31b9f25c..81895731 100644 --- a/src/host/Host.cpp +++ b/src/host/Host.cpp @@ -174,7 +174,7 @@ int Host::run() // initialize system logging yaml::Node logConf = m_conf["log"]; ret = ::LogInitialise(logConf["filePath"].as(), logConf["fileRoot"].as(), - logConf["fileLevel"].as(0U), logConf["displayLevel"].as(0U)); + logConf["fileLevel"].as(0U), logConf["displayLevel"].as(0U), false, logConf["useSyslog"].as(false)); if (!ret) { ::fatal("unable to open the log file\n"); } diff --git a/src/host/HostMain.cpp b/src/host/HostMain.cpp index 30b05c94..2404ce19 100644 --- a/src/host/HostMain.cpp +++ b/src/host/HostMain.cpp @@ -119,6 +119,7 @@ void usage(const char* message, const char* arg) ::fprintf(stdout, "usage: %s [-vhdf]" + "[--syslog]" #if defined(ENABLE_SETUP_TUI) "[--setup]" #else @@ -132,6 +133,8 @@ void usage(const char* message, const char* arg) " -d force modem debug\n" " -f foreground mode\n" "\n" + " --syslog force logging to syslog\n" + "\n" #if defined(ENABLE_SETUP_TUI) " --setup setup and calibration mode\n" #else @@ -179,6 +182,9 @@ int checkArgs(int argc, char* argv[]) else if (IS("-f")) { g_foreground = true; } + else if (IS("--syslog")) { + g_useSyslog = true; + } else if (IS("--cal")) { g_calibrate = true; }