#include #include #include #include namespace newsbeuter { logger::logger() : curlevel(LOG_NONE) { } void logger::set_logfile(const char * logfile) { /* * This sets the filename of the debug logfile */ scope_mutex lock(&mtx); if (f.is_open()) f.close(); f.open(logfile, std::fstream::out); if (!f.is_open()) { throw exception(errno); // the question is whether f.open() sets errno... } } void logger::set_errorlogfile(const char * logfile) { /* * This sets the filename of the error logfile, i.e. the one that can be configured to be generated. */ scope_mutex lock(&mtx); if (ef.is_open()) ef.close(); ef.open(logfile, std::fstream::out); if (!ef.is_open()) { throw exception(errno); } if (LOG_NONE == curlevel) { curlevel = LOG_USERERROR; } } void logger::set_loglevel(loglevel level) { scope_mutex lock(&mtx); curlevel = level; if (curlevel == LOG_NONE) f.close(); } const char * loglevel_str[] = { "NONE", "USERERROR", "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG" }; void logger::log(loglevel level, const char * format, ...) { /* * This function checks the loglevel, creates the error message, and then * writes it to the debug logfile and to the error logfile (if applicable). */ scope_mutex lock(&mtx); if (level <= curlevel && curlevel > LOG_NONE && (f.is_open() || ef.is_open())) { char * buf, * logmsgbuf; char date[128]; time_t t = time(NULL); struct tm * stm = localtime(&t); strftime(date,sizeof(date),"%Y-%m-%d %H:%M:%S",stm); if (curlevel > LOG_DEBUG) curlevel = LOG_DEBUG; va_list ap; va_start(ap, format); unsigned int len = vsnprintf(NULL,0,format,ap); va_end(ap); va_start(ap, format); logmsgbuf = new char[len + 1]; vsnprintf(logmsgbuf, len + 1, format, ap); va_end(ap); len = snprintf(NULL, 0, "[%s] %s: %s",date, loglevel_str[level], logmsgbuf); buf = new char[len + 1]; snprintf(buf,len + 1,"[%s] %s: %s",date, loglevel_str[level], logmsgbuf); if (f.is_open()) { f << buf << std::endl; } if (LOG_USERERROR == level && ef.is_open()) { snprintf(buf, len + 1, "[%s] %s", date, logmsgbuf); ef << buf << std::endl; ef.flush(); } delete[] buf; delete[] logmsgbuf; } } logger& GetLogger() { /* * This is the global logger that everyone uses */ static logger theLogger; return theLogger; } }