#include "buflog.h" #include #ifdef WIN32 #include #endif //WIN32 const ELogLev g_logLev = LOG_LEV_WARNING; //用户调用的记日志函数; void DsLog( ELogLev logLevel/*日志等级*/, CDsBufLog* pLogBuf, const char *fmt, ...) { if ( logLevel < g_logLev ) { //无需记录的日志; return; } if ( ( NULL == pLogBuf ) || ( NULL == fmt ) ) { printf( "error : DsLog, NULL == pLogBUf || NULL == fmt !!!\n" ); return; } char lpszBuf[1024] = {0}; tm curTm; #ifdef WIN32 _timeb curTime; _ftime_s( &curTime ); localtime_s( &curTm, &(curTime.time) ); sprintf_s( lpszBuf, sizeof(lpszBuf), "%x(%d:%d.%d.%d)", ::GetCurrentThreadId(), curTm.tm_hour, curTm.tm_min, curTm.tm_sec, curTime.millitm ); #else //WIN32 timeval curTime; gettimeofday( &curTime, NULL ); localtime_r( &(curTime.tv_sec), &curTm ); sprintf( lpszBuf, "%x(%d:%d.%d.%d)", pthread_self(), curTm.tm_hour, curTm.tm_min, curTm.tm_sec, curTime.tv_usec ); #endif //WIN32 size_t timelen = strlen( lpszBuf );//覆盖末尾的'\0' va_list ap; va_start(ap, fmt); #ifdef WIN32 vsprintf_s( &(lpszBuf[timelen]), sizeof(lpszBuf)-timelen-1, fmt, ap); #else //WIN32 vsprintf( &(lpszBuf[timelen]), fmt, ap); #endif //WIN32 va_end(ap); size_t curlen = strlen(lpszBuf); if ( curlen >= 450 ) { //printf( "!!!!!,DsLog写入日志内存越界\n" ); cout << "!!!!!,DsLog写入日志内存越界\n" << endl; return; } lpszBuf[curlen] = '\n';//'\0'换成回车; lpszBuf[curlen+1] = '\0';//补上'\0' if ( !(pLogBuf->AddLog( lpszBuf )) ) //写入缓存失败,可能是日志到来太快,或缓存太小所致; { const char* tmpWarn = "!FAILLOG!\n"; memcpy( &(lpszBuf[curlen]), tmpWarn, strlen(tmpWarn)+1 ); //printf( lpszBuf ); cout << lpszBuf << endl; } return; } void* LogThread( void* pInParam ) { if ( NULL == pInParam ) { return NULL; } CDsBufLog* pBufLog = (CDsBufLog*) pInParam; char* pthreadbuf = NEW char[INNER_BUF_SIZE];//线程写缓存; while ( ! pBufLog->m_isstop ) { pBufLog->m_event.BlockWaitEventByTime( 5000 );//每5秒或缓存满时写一次 unsigned int curtail = pBufLog->m_tail;//当前尾,该值可能会由于主线程AddLog而改变,因此需要保存快照,而m_head只会由写日志线程改变,因此无需保存; curtail = (curtail < INNER_BUF_SIZE) ? curtail:0; //取得当前已记日志的大小,只要有可写日志,则写IO; unsigned int cursize = ( pBufLog->m_head <= curtail ) ? (curtail-pBufLog->m_head) : ( curtail + (INNER_BUF_SIZE-pBufLog->m_head) ); if ( cursize <= 0 ) { //当前没有可写日志; continue; } //有可写日志,将可写日志输至IO; if ( pBufLog->m_head <= curtail ) { memcpy( pthreadbuf, &(pBufLog->m_pBufqueue[pBufLog->m_head]), cursize ); pthreadbuf[cursize] = '\0';//加上末尾处的结束符 pBufLog->m_head += cursize; pBufLog->m_head = (pBufLog->m_head < INNER_BUF_SIZE) ? pBufLog->m_head:0; } else { //可写部分绕过了尾部; int tailsize = INNER_BUF_SIZE - pBufLog->m_head;//尾部待取字符数; memcpy( pthreadbuf, &(pBufLog->m_pBufqueue[pBufLog->m_head]), tailsize ); memcpy( &(pthreadbuf[tailsize]), &(pBufLog->m_pBufqueue[0]), cursize-tailsize ); pthreadbuf[cursize] = '\0';//加上末尾处结束符; pBufLog->m_head = cursize-tailsize;//从头开始数起取的字符个数,即为尾部位置(0起,也就是下一个可写位置); } //printf( pthreadbuf ); cout << pthreadbuf << endl; } delete [] pthreadbuf; pthreadbuf = NULL; return NULL; }