//! 覆写式创建 LoggerId CLogerManager::CreateLogger(std::string name,std::string path,int nLevel,bool display, bool monthdir, unsigned int limitsize) { std::string _tmp; std::string _pid; GetProcessInfo(_tmp, _pid); if (name.length() == 0) { ShowColorText("log4z: create logger error, name is empty ! \r\n", LOG_LEVEL_FATAL); return -1; } TrimLogConfig(path); FixPath(path); LoggerId newID = -1; { std::map<std::string, LoggerId>::iterator iter = m_ids.find(name); if (iter != m_ids.end()) { newID = iter->second; } } if (newID == -1) { if (m_lastId +1 >= LOG4Z_LOGGER_MAX) { ShowColorText("log4z: CreateLogger can not create|writeover, because loggerid need < LOGGER_MAX! \r\n", LOG_LEVEL_FATAL); return -1; } newID = ++ m_lastId; m_ids[name] = newID; } if (!path.empty()) { m_loggers[newID]._path = path; } if (newID > LOG4Z_MAIN_LOGGER_ID) { m_loggers[newID]._name = name; } m_loggers[newID]._pid = _pid; m_loggers[newID]._level = nLevel; m_loggers[newID]._enable = true; m_loggers[newID]._display = display; m_loggers[newID]._monthdir = monthdir; m_loggers[newID]._limitsize = limitsize; if (limitsize == 0) { m_loggers[newID]._limitsize = 4000; } return newID; }
bool CLogerManager::OpenLogger(LoggerId id) { if (id < 0 || id >m_lastId) { ShowColorText("log4z: OpenLogger can not open, invalide logger id! \r\n", LOG_LEVEL_FATAL); return false; } LoggerInfo * pLogger = &m_loggers[id]; if (pLogger->_handle.IsOpen()) { pLogger->_handle.Close(); } tm t; TimeToTm(pLogger->_curFileCreateTime, &t); std::string path = pLogger->_path; char buf[100]={0}; if (pLogger->_monthdir) { sprintf(buf, "%04d_%02d/", t.tm_year+1900, t.tm_mon+1); path += buf; } if (!IsDirectory(path)) { CreateRecursionDir(path); } sprintf(buf, "%s_%04d%02d%02d%02d%02d_%s_%03d.log", pLogger->_name.c_str(), t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, pLogger->_pid.c_str(), pLogger->_curFileIndex); path += buf; pLogger->_handle.Open(path.c_str(), "ab"); return pLogger->_handle.IsOpen(); }
////////////////////////////////////////////////////////////////////////// //! CThread ////////////////////////////////////////////////////////////////////////// bool CThread::Start() { #ifdef WIN32 unsigned long long ret = _beginthreadex(NULL, 0, ThreadProc, (void *) this, 0, NULL); if (ret == -1 || ret == 1 || ret == 0) { ShowColorText("log4z: create log4z thread error! \r\n", LOG_LEVEL_FATAL); return false; } m_hThreadID = ret; #else int ret = pthread_create(&m_phtreadID, NULL, ThreadProc, (void*)this); if (ret != 0) { ShowColorText("log4z: create log4z thread error! \r\n", LOG_LEVEL_FATAL); return false; } #endif return true; }
void CLogerManager::Run() { m_bRuning = true; m_loggers[LOG4Z_MAIN_LOGGER_ID]._enable = true; PushLog(0, LOG_LEVEL_ALARM, "----------------- log4z thread started! ----------------------------"); for (int i=0; i<LOG4Z_LOGGER_MAX; i++) { if (m_loggers[i]._enable) { std::stringstream ss; ss <<"logger id=" <<i <<" path=" <<m_loggers[i]._path <<" name=" <<m_loggers[i]._name <<" level=" << m_loggers[i]._level <<" display=" << m_loggers[i]._display; PushLog(0, LOG_LEVEL_ALARM, ss.str().c_str()); } } m_semaphore.Post(); LogData * pLog = NULL; char *pWriteBuf = new char[LOG4Z_LOG_BUF_SIZE + 512]; int needFlush[LOG4Z_LOGGER_MAX] = {0}; while (true) { while(PopLog(pLog)) { // m_ullStatusTotalPopLog ++; //discard LoggerInfo & curLogger = m_loggers[pLog->_id]; if (!curLogger._enable || pLog->_level <curLogger._level ) { delete pLog; pLog = NULL; continue; } //update file if (LOG4Z_ALL_WRITE_TO_FILE) { bool sameday = IsSameDay(pLog->_time, curLogger._curFileCreateTime); bool needChageFile = curLogger._curWriteLen > curLogger._limitsize*1024*1024; if (!curLogger._handle.IsOpen() || !sameday || needChageFile) { if (!sameday) { curLogger._curFileIndex = 0; curLogger._curWriteLen = 0; } else if ( needChageFile) { curLogger._curFileIndex ++; curLogger._curWriteLen = 0; } curLogger._curFileCreateTime = pLog->_time; if (!OpenLogger(pLog->_id)) { curLogger._enable = false; delete pLog; pLog = NULL; ShowColorText("log4z: Run can not update file, open file false! \r\n", LOG_LEVEL_FATAL); continue; } } } //record tm tt; if (!TimeToTm(pLog->_time, &tt)) { memset(&tt, 0, sizeof(tt)); } sprintf(pWriteBuf, "%d-%02d-%02d %02d:%02d:%02d.%03d %s %s \r\n", tt.tm_year+1900, tt.tm_mon+1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec, pLog->_precise, LOG_STRING[pLog->_level], pLog->_content); if (LOG4Z_ALL_WRITE_TO_FILE) { size_t writeLen = strlen(pWriteBuf); curLogger._handle.Write(pWriteBuf, writeLen); curLogger._curWriteLen += (unsigned int)writeLen; needFlush[pLog->_id] ++; m_ullStatusTotalWriteFileCount++; m_ullStatusTotalWriteFileBytes += writeLen; } else { size_t writeLen = strlen(pWriteBuf); m_ullStatusTotalWriteFileCount++; m_ullStatusTotalWriteFileBytes += writeLen; } if (curLogger._display && !LOG4Z_ALL_SYNCHRONOUS_DISPLAY) { ShowColorText(pWriteBuf, pLog->_level); } delete pLog; pLog = NULL; } for (int i=0; i<LOG4Z_LOGGER_MAX; i++) { if (m_loggers[i]._enable && needFlush[i] > 0) { m_loggers[i]._handle.Flush(); needFlush[i] = 0; } } //! delay. SleepMillisecond(100); //! quit if (!m_bRuning && m_logs.empty()) { break; } } for (int i=0; i<LOG4Z_LOGGER_MAX; i++) { if (m_loggers[i]._enable) { m_loggers[i]._enable = false; m_loggers[i]._handle.Close(); } } delete []pWriteBuf; pWriteBuf = NULL; }
bool CLogerManager::PushLog(LoggerId id, int level, const char * log) { if (id < 0 || id >= LOG4Z_LOGGER_MAX) { return false; } if (!m_bRuning || !m_loggers[id]._enable) { return false; } if (level < m_loggers[id]._level) { return true; } LogData * pLog = new LogData; pLog->_id =id; pLog->_level = level; { #ifdef WIN32 FILETIME ft; GetSystemTimeAsFileTime(&ft); unsigned long long now = ft.dwHighDateTime; now <<= 32; now |= ft.dwLowDateTime; now /=10; now -=11644473600000000Ui64; now /=1000; pLog->_time = now/1000; pLog->_precise = (unsigned int)(now%1000); #else struct timeval tm; gettimeofday(&tm, NULL); pLog->_time = tm.tv_sec; pLog->_precise = tm.tv_usec/1000; #endif } if (m_loggers[pLog->_id]._display && LOG4Z_ALL_SYNCHRONOUS_DISPLAY) { tm tt; if (!TimeToTm(pLog->_time, &tt)) { memset(&tt, 0, sizeof(tt)); } std::string text; sprintf(pLog->_content, "%d-%02d-%02d %02d:%02d:%02d.%03d %s ", tt.tm_year+1900, tt.tm_mon+1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec, pLog->_precise, LOG_STRING[pLog->_level]); text = pLog->_content; text += log; text += " \r\n"; ShowColorText(text.c_str(), pLog->_level); } int len = (int) strlen(log); if (len >= LOG4Z_LOG_BUF_SIZE) { memcpy(pLog->_content, log, LOG4Z_LOG_BUF_SIZE); pLog->_content[LOG4Z_LOG_BUF_SIZE-1] = '\0'; } else { memcpy(pLog->_content, log, len+1); } CAutoLock l(m_lock); m_logs.push_back(pLog); m_ullStatusTotalPushLog ++; return true; }
virtual void Run() { m_bRuning = true; PushLog(GetMainLogger(), LOG_LEVEL_ALARM, "----------------- log4z thread started! ----------------------------"); for (int i=0; i<LOGGER_MAX; i++) { if (m_loggers[i]._enable) { std::stringstream ss; ss <<" logger id=" <<i <<" path=" <<m_loggers[i]._path <<" name=" <<m_loggers[i]._name <<" level=" << m_loggers[i]._level <<" display=" << m_loggers[i]._display; PushLog(GetMainLogger(), LOG_LEVEL_ALARM, ss.str().c_str()); } } m_semaphore.Post(); LogData * pLog = NULL; #ifdef WIN32 char text[LOG_BUF_SIZE+MAX_PATH+512] = {0}; #else char text[LOG_BUF_SIZE+PATH_MAX+512] = {0}; #endif int needFlush[LOGGER_MAX] = {0}; int maxCount = 0; while (true) { while(PopLog(pLog)) { //discard if (!m_loggers[pLog->_id]._enable || pLog->_level <m_loggers[pLog->_id]._level ) { delete pLog; pLog = NULL; continue; } //update file if (!m_loggers[pLog->_id]._handle.is_open() || !m_loggers[pLog->_id]._handle.good() || !IsSameDay(pLog->_time, m_loggers[pLog->_id]._filetime)) { m_loggers[pLog->_id]._filetime = pLog->_time; if (!OpenLogger(pLog->_id)) { m_loggers[pLog->_id]._enable = false; delete pLog; pLog = NULL; continue; } } //record tm tt; if (!TimeToTm(pLog->_time, &tt)) { memset(&tt, 0, sizeof(tt)); } sprintf(text, "%d-%02d-%02d %02d:%02d:%02d %s %s \r\n", tt.tm_year+1900, tt.tm_mon+1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec, LOG_STRING[pLog->_level], pLog->_content); m_loggers[pLog->_id]._handle.write(text, (std::streamsize)strlen(text)); if (m_loggers[pLog->_id]._display) { ShowColorText(text, pLog->_level); } needFlush[pLog->_id] ++; maxCount++; m_ullStatusTotalWriteCount++; m_ullStatusTotalWriteBytes+=strlen(text); delete pLog; pLog = NULL; if (maxCount > 1000) { //flush maxCount = 0; for (int i=0; i<LOGGER_MAX; i++) { if (m_loggers[i]._enable && needFlush[i] > 0) { m_loggers[i]._handle.flush(); needFlush[i] = 0; } } } } //flush if (maxCount > 0) { //flush maxCount = 0; for (int i=0; i<LOGGER_MAX; i++) { if (m_loggers[i]._enable && needFlush[i] > 0) { m_loggers[i]._handle.flush(); needFlush[i] = 0; } } } //stopped if (!m_bRuning) { break; } //delay. SleepMillisecond(100); } for (int i=0; i<LOGGER_MAX; i++) { if (m_loggers[i]._enable) { m_loggers[i]._handle.close(); } } }