#include "../Logger.h" #include "Mutex.h" using namespace std; #ifdef EXTERNAL_DISTRO namespace NAMESPACE { #endif namespace Base { const char file_sep = '\\'; Logger::Logger(const char *prefix, int level, unsigned size, bool rollDate) : m_defaultLevel(level), m_defaultSize(size), m_dirPrefix(prefix), m_rollDate(rollDate) { char buf[1024]; FILE *logDir = NULL; logDir = fopen(m_dirPrefix.c_str(), "r+"); if(errno == ENOENT) { cmkdir(m_dirPrefix.c_str(), 0755); } else if(logDir != NULL) { fclose(logDir); } tm now; time_t t = time(NULL); memcpy(&now, localtime(&t), sizeof(tm)); memcpy(&m_lastDateTime, &now, sizeof(tm)); if(m_rollDate) { sprintf(buf, "%s%c%2.2d-%2.2d-%2.2d", m_dirPrefix.c_str(), file_sep, (now.tm_mon + 1), now.tm_mday, (now.tm_year % 100)); } else { sprintf(buf, "%s", m_dirPrefix.c_str()); } logDir = fopen(buf, "r+"); if(errno == ENOENT) { cmkdir(buf, 0755); } else if(logDir != NULL) { fclose(logDir); } m_logPrefix = buf; } Logger::~Logger() { map::iterator iter; for(iter = m_logTable.begin(); iter != m_logTable.end(); ++iter) { log((*iter).first, LOG_FILEONLY, "---=== Log Stopped ===---"); fflush((*iter).second->file); fclose((*iter).second->file); delete((*iter).second); } m_logTable.clear(); } void Logger::flush(unsigned logenum) { map::iterator iter = m_logTable.find(logenum); if(iter != m_logTable.end()) { LogInfo *info = (*iter).second; fflush(info->file); info->used = 0; } } void Logger::flushAll() { map::iterator iter; for(iter = m_logTable.begin(); iter != m_logTable.end(); ++iter) { LogInfo *info = (*iter).second; fflush(info->file); info->used = 0; } } void Logger::addLog(const char *id, unsigned logenum, int level, unsigned size) { LogInfo *newLog = new LogInfo; newLog->filename = m_logPrefix + file_sep + id + ".log"; newLog->name = id; newLog->used = 0; newLog->max = size; newLog->last = 0; newLog->level = level; m_logTable.insert(pair(logenum, newLog)); if(strcmp("stdout", id) == 0) { newLog->file = stdout; } else if(strcmp("stderr", id) == 0) { newLog->file = stderr; } else { newLog->file = fopen(newLog->filename.c_str(), "a+"); } log(logenum, LOG_FILEONLY, "---=== Log Started ===---"); } void Logger::addLog(const char *id, unsigned logenum) { LogInfo *newLog = new LogInfo; newLog->filename = m_logPrefix + file_sep + id + ".log"; newLog->name = id; newLog->used = 0; newLog->max = m_defaultSize; newLog->last = 0; newLog->level = m_defaultLevel; m_logTable.insert(pair(logenum, newLog)); if(strcmp("stdout", id) == 0) { newLog->file = stdout; } else if(strcmp("stderr", id) == 0) { newLog->file = stderr; } else { newLog->file = fopen(newLog->filename.c_str(), "a+"); } log(logenum, LOG_FILEONLY, "---=== Log Started ===---"); } void Logger::updateLog(unsigned logenum, int level, unsigned size) { map::iterator iter = m_logTable.find(logenum); if(iter != m_logTable.end()) { (*iter).second->level = level; (*iter).second->max = size; } } void Logger::removeLog(unsigned logenum) { map::iterator iter = m_logTable.find(logenum); if(iter != m_logTable.end()) { log((*iter).first, LOG_FILEONLY, "---=== Log Stopped ===---"); fflush((*iter).second->file); fclose((*iter).second->file); delete((*iter).second); } } void Logger::logSimple(unsigned logenum, int level, const char *message) { map::iterator iter = m_logTable.find(logenum); char dateBuffer[256]; if(iter == m_logTable.end()) { return; } time_t t = time(NULL); LogInfo *info = (*iter).second; if(level >= info->level) { return; } if(info->last != t) { memcpy(&info->ts, localtime(&t), sizeof(tm)); info->last = t; } if(m_rollDate && info->ts.tm_mday != m_lastDateTime.tm_mday) { #if defined(_MT) rLock.Lock(); #endif if(info->ts.tm_mday != m_lastDateTime.tm_mday) { memcpy(&m_lastDateTime, &info->ts, sizeof(tm)); rollDate(t); } #if defined(_MT) rLock.Unlock(); #endif } if(iter != m_logTable.end()) { if(info->max > 0) { sprintf(dateBuffer, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] " , (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec); info->used += fputs(dateBuffer, info->file); info->used += fputs(message, info->file); fputc('\n', info->file); if(info->used > info->max) { fflush(info->file); info->used = 0; } } else { sprintf(dateBuffer, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] " , (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec); fputs(dateBuffer, info->file); fputs(message, info->file); fputc('\n', info->file); fflush(info->file); } } } void Logger::log(unsigned logenum, int level, const char *message, ...) { char buf[2048]; char dateBuffer[256]; va_list varg; va_start(varg, message); _vsnprintf(buf, 2047, message, varg); buf[2047] = 0; va_end(varg); map::iterator iter = m_logTable.find(logenum); if(iter == m_logTable.end()) { return; } time_t t = time(NULL); LogInfo *info = (*iter).second; if(level >= info->level) { return; } if(level == LOG_FILEONLY && ((info->file == stderr) || (info->file == stdout))) { return; } if(info->last != t) { memcpy(&info->ts, localtime(&t), sizeof(tm)); info->last = t; } if(m_rollDate && info->ts.tm_mday != m_lastDateTime.tm_mday) { #if defined(_MT) rLock.Lock(); #endif if(info->ts.tm_mday != m_lastDateTime.tm_mday) { memcpy(&m_lastDateTime, &info->ts, sizeof(tm)); rollDate(t); } #if defined(_MT) rLock.Unlock(); #endif } if(iter != m_logTable.end()) { if(info->max > 0) { sprintf(dateBuffer, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] " , (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec); info->used += fputs(dateBuffer, info->file); info->used += fputs(buf, info->file); fputc('\n', info->file); if(info->used > info->max) { fflush(info->file); info->used = 0; } } else { sprintf(dateBuffer, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] " , (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec); info->used += fputs(dateBuffer, info->file); info->used += fputs(buf, info->file); fputc('\n', info->file); fflush(info->file); } } } void Logger::rollDate(time_t t) { char buf[80]; FILE *logDir = NULL; logDir = fopen(m_dirPrefix.c_str(), "r+"); if(errno == ENOENT) { cmkdir(m_dirPrefix.c_str(), 0755); } else if(logDir != NULL) { fclose(logDir); } tm now; memcpy(&now, localtime(&t), sizeof(tm)); sprintf(buf, "%s%c%2.2d-%2.2d-%2.2d", m_dirPrefix.c_str(), file_sep, (now.tm_mon + 1), now.tm_mday, (now.tm_year % 100)); logDir = fopen(buf, "r+"); if(errno == ENOENT) { cmkdir(buf, 0755); } else if(logDir != NULL) { fclose(logDir); } m_logPrefix = buf; map::iterator iter; for(iter = m_logTable.begin(); iter != m_logTable.end(); ++iter) { (*iter).second->filename = m_logPrefix + file_sep + (*iter).second->name.c_str() + ".log"; fflush((*iter).second->file); fclose((*iter).second->file); (*iter).second->file = fopen((*iter).second->filename.c_str(), "a+"); memcpy(&((*iter).second->ts), &now, sizeof(tm)); } } // mkdir function that creates intermediate directories void Logger::cmkdir(const char *dir, int mode) { char dirbuf[128]; strncpy(dirbuf, dir, 127); dirbuf[127] = 0; char *j = dirbuf, *i = dirbuf; int handle; while(*i) { if(*i == file_sep) { (*i) = 0; handle = _open(j, O_EXCL); if((handle > 0) || (errno != EISDIR && errno != ENOENT && errno != EACCES)) { perror("Logger::cmkdir():"); abort(); } _mkdir(j); _close(handle); (*i) = file_sep; } else if(*(i + 1) == 0) { _mkdir(j); } i++; } } }; #ifdef EXTERNAL_DISTRO }; #endif