Improved Logging

- removed daemon.cpp
- Added additional output logfile to Logger class
This commit is contained in:
Ralf Ramsauer 2015-10-02 17:25:16 +02:00
parent f504cf4e92
commit 54f22393a4
10 changed files with 101 additions and 116 deletions

View File

@ -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

View File

@ -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;

View File

@ -1,50 +0,0 @@
#include <stdexcept>
#include <cstring>
#include <fstream>
#include <sys/resource.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#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");
}
}

View File

@ -1,16 +0,0 @@
#ifndef DAEMON_H
#define DAEMON_H
#include <string>
// 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

View File

@ -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> 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<Logic>(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();

View File

@ -66,7 +66,7 @@ private:
DoorCallback _doorCallback = { };
const Logger &_logger;
Logger &_logger;
// Writed command to AVR board
bool writeCMD(char c);

View File

@ -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<mutex> 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<mutex> lock(_ostreamMutex);
_consoleActive = active;
}
bool Logger::logFile() const
{
return _logFileActive;
}
void Logger::logFile(const bool active)
{
lock_guard<mutex> 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);
}

View File

@ -1,6 +1,7 @@
#ifndef LOGGER_H
#define LOGGER_H
#include <fstream>
#include <ostream>
#include <string>
#include <sstream>
@ -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;
};

View File

@ -62,7 +62,7 @@ private:
void _doorCallback(Doormessage doormessage);
const Logger &_logger;
Logger &_logger;
// The door
Door _door;

View File

@ -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 =