#include "Logger.hpp" #include #include namespace Plains { namespace Core { using std::cout; using std::cerr; using std::endl; // Static method to get the single instance of the class Logger& Logger::getInstance() { static Logger instance; return instance; } Logger::Logger(enum Level logLevel) : _logLevel(logLevel), debug(DEBUG, *this), info (INFO, *this), warn (WARN, *this), fatal(FATAL, *this) { _output = new ofstream("plains.log", std::ios_base::app); if (!(*_output)) { cout << "Unable to open Logfile! writing to /tmp/plains.log" << endl; _output = new ofstream("/tmp/plains.log"); } else { debug << "============================" << commit; debug << "Logfile successfully opened!" << commit; } } Logger::Logger() : Logger(Level::FATAL) {} Logger::~Logger() { _output->close(); delete _output; } string Logger::genTimeStamp() { time_t rawtime; struct tm * timeinfo; char buffer[80]; time (&rawtime); timeinfo = localtime(&rawtime); strftime(buffer,sizeof(buffer),"%b %d %H:%M:%S",timeinfo); return string(buffer); } void Logger::setLogLevel(Level level) { _logLevel = level; } void Logger::log(Level lvl, const string& msg) { log ( lvl, msg.c_str() ); } void Logger::log(Level lvl, const char* msg) { switch ( lvl ) { case DEBUG: debug.ln (msg); break; case INFO: info.ln (msg); break; case WARN: warn.ln (msg); break; case FATAL: fatal.ln (msg); break; } } Logger::Sink::Sink (const Level level, Logger& parent) : _level(level), _parent(parent), _lineIsPrefixed(false) {} void Logger::Sink::ln ( const string& msg ) { ln (msg.c_str()); } void Logger::Sink::ln ( const char* msg ) { _parent._mutex.lock(); if ( _level >= _parent._logLevel ) { // If line has already been started, abort it and start new one: if(_lineIsPrefixed) *_parent._output << endl; prefixLine(true); *(_parent._output) << msg << endl; cout << msg << CC_RESET "\n"; } _parent._mutex.unlock(); } void Logger::Sink::prefixLine(bool resetToFalse) { if (!_lineIsPrefixed) { const string timestamp = Logger::genTimeStamp(); switch ( _level) { case DEBUG: *(_parent._output) << timestamp << " " << "DEBUG "; cout << timestamp << " " << CC_BLUE "DEBUG "; break; case INFO: *(_parent._output) << timestamp << " " << "INFO "; cout << timestamp << " " << CC_GREEN "INFO "; break; case WARN: *(_parent._output) << timestamp << " " << "WARN "; cout << timestamp << " " << CC_YELLOW "WARN "; break; case FATAL: *(_parent._output) << timestamp << " " << "FATAL "; cout << timestamp << " " << CC_RED "FATAL "; break; } _lineIsPrefixed = resetToFalse ? false : true; } } Logger::Sink& Logger::Sink::operator<<(const string& msg) { _parent._mutex.try_lock(); if ( _level >= _parent._logLevel ) { prefixLine(); *(_parent._output) << msg; cout << msg; } return *this; } Logger::Sink& Logger::Sink::operator<<(const char* msg) { _parent._mutex.try_lock(); if ( _level >= _parent._logLevel ) { prefixLine(); *(_parent._output) << msg; cout << msg; } return *this; } Logger::Sink& Logger::Sink::operator<<(const int msg) { _parent._mutex.try_lock(); if ( _level >= _parent._logLevel ) { prefixLine(); *(_parent._output) << msg; cout << msg; } return *this; } Logger::Sink& Logger::Sink::operator<<(const unsigned msg) { _parent._mutex.try_lock(); if ( _level >= _parent._logLevel ) { prefixLine(); *(_parent._output) << msg; cout << msg; } return *this; } Logger::Sink& Logger::Sink::operator<<(const long msg) { _parent._mutex.try_lock(); if ( _level >= _parent._logLevel ) { prefixLine(); *(_parent._output) << msg; cout << msg; } return *this; } Logger::Sink& Logger::Sink::operator<<(const unsigned long msg) { _parent._mutex.try_lock(); if ( _level >= _parent._logLevel ) { prefixLine(); *(_parent._output) << msg; cout << msg; } return *this; } Logger::Sink& Logger::Sink::operator<<(const char character) { _parent._mutex.try_lock(); if ( _level >= _parent._logLevel ) { switch(character) { // COMMIT - End message line case 0: *(_parent._output) << endl; cout << CC_RESET "\n"; _lineIsPrefixed = false; break; } } _parent._mutex.unlock(); return *this; } }}