rendered paste body// log.h#ifndef LOG_H_INCLUDED#define LOG_H_INCLUDED#include <string>#include <sstream>#include <fstream>using std::string;enum loglevel { LOGLEVEL_INFO, LOGLEVEL_STATUS, LOGLEVEL_WARN, LOGLEVEL_ERROR, LOGLEVEL_CRITICAL};enum logopt { LOGOPT_USE_FILE = 0x1, LOGOPT_USE_CONSOLE = 0x2, LOGOPT_USE_STDOUT = 0x4, LOGOPT_LOG_TIME = 0x8, LOGOPT_LOG_LEVEL = 0x10, LOGOPT_OVERWRITE_FILE = 0x20};class Log { public: Log(int, string = ""); ~Log(); string log(loglevel, string); std::string formatLog(loglevel, string); template<typename T> Log& operator<<(T t); private: std::fstream logfile; std::ostringstream msgStream; bool usingFile, usingConsole, usingStdout, loggingTime, loggingLevel;};#endif // LOG_H_INCLUDED// log.cpp#include <iostream>#include <ostream>#include <fstream>#include <string>#include <time.h>#include "log.h"using std::string;using std::cout;using std::cerr;Log::Log(int options, string path) { usingFile = false; usingConsole = false; usingStdout = false; loggingLevel = false; loggingTime = false; if(options & LOGOPT_USE_FILE) { usingFile = true; if(options & LOGOPT_OVERWRITE_FILE) // Append by default, overwrite if specified. logfile.open(path.data(), std::fstream::trunc); else logfile.open(path.data(), std::fstream::app); } if(options & LOGOPT_USE_CONSOLE) usingConsole = true; if(options & LOGOPT_USE_STDOUT) usingStdout = true; if(options & LOGOPT_LOG_TIME) loggingTime = true; if(options & LOGOPT_LOG_LEVEL) loggingLevel = true;}string Log::formatLog(loglevel level, string message) { static time_t timer = time(NULL); string logMessage; if(loggingTime) logMessage = asctime(localtime(&timer)); logMessage += " | "; if(loggingLevel) { switch(level) { case LOGLEVEL_INFO: break; case LOGLEVEL_STATUS: logMessage += "STATUS: "; break; case LOGLEVEL_WARN: logMessage += "WARNING: "; break; case LOGLEVEL_ERROR: logMessage += "ERROR: "; break; case LOGLEVEL_CRITICAL: logMessage += "***CRITICAL***: "; break; default: break; } } logMessage += message; return message.data();}string Log::log(loglevel level, string message) { string formatted = formatLog(level, message); if(usingFile) logfile << formatted; //if(usingConsole) // Output to GUI console - NOT IMPLEMENTED if(usingStdout) { if(level < LOGLEVEL_WARN) cout << formatted; else cerr << formatted; } return formatted;}template<typename T> Log& Log::operator<<(T t) { msgStream << t; return *this;}Log::~Log() { if(logfile.is_open()) logfile.close();}