From 54f22393a4a433a9b8600a218709d7f17e1feec5 Mon Sep 17 00:00:00 2001 From: Ralf Ramsauer Date: Fri, 2 Oct 2015 17:25:16 +0200 Subject: [PATCH] Improved Logging - removed daemon.cpp - Added additional output logfile to Logger class --- doorlockd/CMakeLists.txt | 2 - doorlockd/client/doorlock-client.cpp | 2 +- doorlockd/daemon/daemon.cpp | 50 --------------- doorlockd/daemon/daemon.h | 16 ----- doorlockd/daemon/doorlockd.cpp | 26 +++----- doorlockd/lib/door.h | 2 +- doorlockd/lib/logger.cpp | 94 +++++++++++++++++++++------- doorlockd/lib/logger.h | 21 ++++++- doorlockd/lib/logic.h | 2 +- doorlockd/lib/request.cpp | 2 +- 10 files changed, 101 insertions(+), 116 deletions(-) delete mode 100644 doorlockd/daemon/daemon.cpp delete mode 100644 doorlockd/daemon/daemon.h diff --git a/doorlockd/CMakeLists.txt b/doorlockd/CMakeLists.txt index 710f555..2a166a2 100644 --- a/doorlockd/CMakeLists.txt +++ b/doorlockd/CMakeLists.txt @@ -75,8 +75,6 @@ set(LIBDOORLOCK_SRCS lib/util.h) set(DOORLOCKD_SRCS - daemon/daemon.cpp - daemon/daemon.h daemon/doorlockd.cpp) set(DOORLOCK_CLIENT_SRCS diff --git a/doorlockd/client/doorlock-client.cpp b/doorlockd/client/doorlock-client.cpp index 496f937..28d3283 100644 --- a/doorlockd/client/doorlock-client.cpp +++ b/doorlockd/client/doorlock-client.cpp @@ -22,7 +22,7 @@ const static std::string version = const static std::string gitversion = DOORLOCK_GIT_BRANCH "-" DOORLOCK_GIT_COMMIT_HASH; -const static Logger &l = Logger::get(); +static Logger &l = Logger::get(); namespace po = boost::program_options; namespace ba = boost::asio; diff --git a/doorlockd/daemon/daemon.cpp b/doorlockd/daemon/daemon.cpp deleted file mode 100644 index 8f43ca9..0000000 --- a/doorlockd/daemon/daemon.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include - -#include "daemon.h" - -void daemonize(const std::string &dir, - const std::string &stdinfile, - const std::string &stdoutfile, - const std::string &stderrfile) -{ - umask(0); - - rlimit rl; - if (getrlimit(RLIMIT_NOFILE, &rl) < 0) - { - throw std::runtime_error(strerror(errno)); - } - - if (!dir.empty() && chdir(dir.c_str()) < 0) - { - throw std::runtime_error(strerror(errno)); - } - - if (rl.rlim_max == RLIM_INFINITY) - { - rl.rlim_max = 1024; - } - - for (unsigned int i = 0; i < rl.rlim_max; i++) - { - close(i); - } - - int fd0 = open(stdinfile.c_str(), O_RDONLY); - int fd1 = open(stdoutfile.c_str(), - O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR); - int fd2 = open(stderrfile.c_str(), - O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR); - - if (fd0 != STDIN_FILENO || fd1 != STDOUT_FILENO || fd2 != STDERR_FILENO) - { - throw std::runtime_error("new standard file descriptors were not opened as expected"); - } -} diff --git a/doorlockd/daemon/daemon.h b/doorlockd/daemon/daemon.h deleted file mode 100644 index 83060ea..0000000 --- a/doorlockd/daemon/daemon.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef DAEMON_H -#define DAEMON_H - -#include - -// Daemonizes the process if daemonize is true. -// If daemonize is true, it will write the new PID to the file "pidFile" -// -// This function will also redirect stdin, out and err to the -// specified files -void daemonize(const std::string &dir, - const std::string &stdinfile, - const std::string &stdoutfile, - const std::string &stderrfile); - -#endif diff --git a/doorlockd/daemon/doorlockd.cpp b/doorlockd/daemon/doorlockd.cpp index c8abadb..619dd27 100644 --- a/doorlockd/daemon/doorlockd.cpp +++ b/doorlockd/daemon/doorlockd.cpp @@ -9,7 +9,6 @@ #include "../lib/logic.h" #include "config.h" -#include "daemon.h" namespace po = boost::program_options; namespace ba = boost::asio; @@ -24,7 +23,7 @@ const static std::string gitversion = // The receive buffer length of the TCP socket const int constexpr SOCKET_BUFFERLENGTH = 2048; -const static Logger &l = Logger::get(); +static Logger &l = Logger::get(); static std::unique_ptr logic = nullptr; static ba::io_service io_service; @@ -167,10 +166,6 @@ int main(int argc, char** argv) std::string serDev; unsigned int baudrate; - l((std::string)"Hello, this is " + version + " built on " + gitversion, - LogLevel::info); - l(LogLevel::notice, "Starting doorlockd"); - try { unsigned int timeout; po::options_description desc("doorlockd (" + version + " built on " + gitversion + ")"); @@ -209,26 +204,25 @@ int main(int argc, char** argv) { std::cout << desc << std::endl; retval = 0; - goto out; + exit(0); } po::notify(vm); tokenTimeout = std::chrono::seconds(timeout); + + l.setLogFile(logfile); + l.logFile(true); } catch(const std::exception &e) { std::cerr << "Error: " << e.what() << "\n"; - goto out; + exit(-1); } - daemonize("/", - "/dev/null", - logfile, - logfile); - // Resend version string after redirection stdout l((std::string)"Hello, this is " + version + " built on " + gitversion, LogLevel::info); + l(LogLevel::notice, "Starting doorlockd"); signal(SIGINT, signal_handler); signal(SIGKILL, signal_handler); @@ -237,6 +231,8 @@ int main(int argc, char** argv) signal(SIGUSR2, signal_handler); l(LogLevel::info, "Starting Doorlock Logic"); + + retval = 0; try { logic = std::unique_ptr(new Logic(tokenTimeout, ldapUri, @@ -250,12 +246,8 @@ int main(int argc, char** argv) catch (...) { l(LogLevel::error, "Fatal error, shutting down"); retval = -1; - goto out; } - retval = 0; - -out: if (logic) { l(LogLevel::info, "Stopping Doorlock Logic"); logic.reset(); diff --git a/doorlockd/lib/door.h b/doorlockd/lib/door.h index 45a3e85..3c516a0 100644 --- a/doorlockd/lib/door.h +++ b/doorlockd/lib/door.h @@ -66,7 +66,7 @@ private: DoorCallback _doorCallback = { }; - const Logger &_logger; + Logger &_logger; // Writed command to AVR board bool writeCMD(char c); diff --git a/doorlockd/lib/logger.cpp b/doorlockd/lib/logger.cpp index 0f2735c..bd469b2 100644 --- a/doorlockd/lib/logger.cpp +++ b/doorlockd/lib/logger.cpp @@ -65,6 +65,8 @@ Logger::Logger(const LogLevel level) : Logger::~Logger() { + if (_logFile.is_open()) + _logFile.close(); } Logger &Logger::get() @@ -73,7 +75,7 @@ Logger &Logger::get() return l; } -void Logger::operator ()(const std::string &message, const LogLevel level) const +void Logger::operator ()(const std::string &message, const LogLevel level) { if(level > _level) { @@ -104,44 +106,59 @@ void Logger::operator ()(const std::string &message, const LogLevel level) const lock_guard lock(_ostreamMutex); #if defined(USE_COLORIZED_LOGS) && !defined(_WIN32) - cerr << prefix.str() << message << suffix_ansireset << endl; - cerr.flush(); + if (_consoleActive) { + cerr << prefix.str() << message << suffix_ansireset << endl; + cerr.flush(); + } + if (_logFileActive && _logFile.is_open()) { + _logFile << prefix.str() << message << suffix_ansireset << endl; + } #elif defined(USE_COLORIZED_LOGS) && defined(_WIN32) - // taken from GTEST - const HANDLE stdout_handle = GetStdHandle(STD_ERROR_HANDLE); + if (_consoleActive) { + // taken from GTEST + const HANDLE stdout_handle = GetStdHandle(STD_ERROR_HANDLE); - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; - // We need to flush the stream buffers into the console before each - // SetConsoleTextAttribute call lest it affect the text that is already - // printed but has not yet reached the console. - cerr.flush(); - SetConsoleTextAttribute(stdout_handle, - colorAttribute.at(level) | FOREGROUND_INTENSITY); + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + cerr.flush(); + SetConsoleTextAttribute(stdout_handle, + colorAttribute.at(level) | FOREGROUND_INTENSITY); - cerr << prefix.str() << message << endl; - cerr.flush(); + cerr << prefix.str() << message << endl; + cerr.flush(); - // Restores the text color. - SetConsoleTextAttribute(stdout_handle, old_color_attrs); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); + } + if (_logFileActive && _logFile.is_open()) { + _logFile << prefix.str() << message << endl; + } #else - cerr << prefix.str() << message << endl; - cerr.flush(); + if (_consoleActive) { + cerr << prefix.str() << message << endl; + cerr.flush(); + } + if (_logFileActive && _logFile.is_open()) { + _logFile << prefix.str() << message << endl; + } #endif } } -void Logger::operator ()(const std::ostringstream &message, const LogLevel level) const +void Logger::operator ()(const std::ostringstream &message, const LogLevel level) { (*this)(message.str(), level); } -void Logger::operator ()(const LogLevel level, const char* format, ...) const +void Logger::operator ()(const LogLevel level, const char* format, ...) { if(level > _level) { @@ -188,5 +205,34 @@ LogLevel Logger::level() const return _level; } -void foo(void) { +bool Logger::console() const +{ + return _consoleActive; +} + +void Logger::console(const bool active) +{ + lock_guard lock(_ostreamMutex); + _consoleActive = active; +} + +bool Logger::logFile() const +{ + return _logFileActive; +} + +void Logger::logFile(const bool active) +{ + lock_guard lock(_ostreamMutex); + _logFileActive = active; +} + +void Logger::setLogFile(const std::string &logFile) +{ + if (_logFile.is_open()) + _logFile.close(); + + _logFile.open(logFile, std::ofstream::out | std::ofstream::app); + if (!_logFile.is_open()) + throw std::runtime_error("Unable to open " + logFile); } diff --git a/doorlockd/lib/logger.h b/doorlockd/lib/logger.h index 95febf5..0a2dc80 100644 --- a/doorlockd/lib/logger.h +++ b/doorlockd/lib/logger.h @@ -1,6 +1,7 @@ #ifndef LOGGER_H #define LOGGER_H +#include #include #include #include @@ -32,19 +33,28 @@ public: static Logger &get(); /// Log a string - void operator() (const std::string &message, const LogLevel level = LogLevel::debug) const; + void operator() (const std::string &message, const LogLevel level = LogLevel::debug); /// Log a ostringstream - void operator() (const std::ostringstream &message, const LogLevel level = LogLevel::debug) const; + void operator() (const std::ostringstream &message, const LogLevel level = LogLevel::debug); /// Log a format string - void operator() (const LogLevel level, const char* format, ...) const; + void operator() (const LogLevel level, const char* format, ...); /// Set minimum required log level to generate output void level(const LogLevel level); /// Get minimum required log level to generate output LogLevel level() const; + /// Getter/Setter for console output + bool console() const; + void console(const bool active); + + /// Getter/Setter for logfile output + bool logFile() const; + void logFile(const bool active); + void setLogFile(const std::string &logFile); + private: /** @@ -54,6 +64,11 @@ private: Logger(const LogLevel level); ~Logger(); + bool _consoleActive = { true }; + bool _logFileActive = { false }; + + std::ofstream _logFile = {}; + LogLevel _level; mutable std::mutex _ostreamMutex; }; diff --git a/doorlockd/lib/logic.h b/doorlockd/lib/logic.h index d8f369b..60c5b84 100644 --- a/doorlockd/lib/logic.h +++ b/doorlockd/lib/logic.h @@ -62,7 +62,7 @@ private: void _doorCallback(Doormessage doormessage); - const Logger &_logger; + Logger &_logger; // The door Door _door; diff --git a/doorlockd/lib/request.cpp b/doorlockd/lib/request.cpp index bc670b9..909bc94 100644 --- a/doorlockd/lib/request.cpp +++ b/doorlockd/lib/request.cpp @@ -23,7 +23,7 @@ Request::Command Request::_commandFromString(const std::string &command) Request Request::fromJson(const Json::Value &root) { Request retval; - const auto &l = Logger::get(); + auto &l = Logger::get(); try { const auto commandStr =