Log类
该log类是在tlbb代码中拿出来的,自己整理下以便以后工作中用到,该类功能是输出必要信息到log文件中,打印信息方便调试用。 如有问题请指正,谢谢。
//log.h
1 #ifndef _LOG_H_ 2 #define _LOG_H_ 3 4 #include "type.h" 5 #include "util.h" 6 7 enum LOG_FILE_NAME_ID 8 { 9 LOG_Debug =0 , 10 LOG_Error =1 , 11 LOG_Assert =2 , 12 13 LOG_FILE_NUMBER , 14 }; 15 16 17 #define SERVER_LOGFILE "./Log/Debug.log" 18 #define SERVER_ERRORFILE "./Log/Error.log" 19 #define ASSERT_LOGFILE "./Log/assert.log" 20 21 22 #define DEFAULT_LOG_CACHE_SIZE 1024*1024*4 23 24 25 class Log 26 { 27 public: 28 Log(INT model); 29 ~Log(); 30 31 public: 32 BOOL Init(); 33 34 //向日志缓存写入日志信息 35 VOID FastSaveLog(INT logid, CHAR* msg, ...); 36 37 //将日志内存数据写入日志 38 VOID FlushLog(INT logid); 39 40 //取得日志有效数据大小 41 INT GetLogSize(INT logid) 42 { 43 return m_LogPos[logid]; 44 } 45 46 //取得保存日志的文件名称 47 VOID GetLogName(INT logid, CHAR *filename); 48 49 //刷新每个日志文件 50 VOID FlushLog_ALL(); 51 52 //取得日期天数 53 UINT GetDayTime() 54 { 55 return m_DayTime; 56 } 57 58 //设置日期天数 59 VOID SetDayTime(UINT daytime) 60 { 61 m_DayTime = daytime; 62 } 63 64 //支持异步写入操作的日志写入 65 static VOID SaveLog(CHAR* filename, CHAR* msg, ...); 66 67 //删除日志内容 68 static VOID RemoveLog(CHAR *filename); 69 70 private: 71 CHAR* m_LogCache[LOG_FILE_NUMBER]; //日志内存区 72 INT m_LogPos[LOG_FILE_NUMBER]; //日志当前有效数据位置 73 LockLock m_LogLock[LOG_FILE_NUMBER]; //日志读写锁 74 INT m_CacheSize; 75 UINT m_DayTime; 76 INT m_Model; 77 }; 78 79 extern Log* g_pLog; 80 81 #endif
//log.cpp
1 #include <assert.h> 2 #include "Log.h" 3 4 #define _TRY_ {try{ 5 #define _CATCH_ }catch(...){ assert(FALSE); return ;}} 6 #define _CATCH_BOOL_ }catch(...){ assert(FALSE); return FALSE; }} 7 8 9 CHAR* g_pLogFileName[] = 10 { 11 "./Log/debug", //0 LOG_FILE_0 12 "./Log/error", //1 LOG_FILE_1 13 "./Log/assert", //2 LOG_FILE_2 14 '\0' 15 }; 16 17 Log *g_pLog = NULL; 18 19 LockLock g_LogLock; 20 21 Log::Log(INT model) : m_CacheSize(0), m_DayTime(0), m_Model(model) 22 { 23 _TRY_ 24 for (int i=0; i<LOG_FILE_NUMBER; ++i) 25 { 26 m_LogCache[i] = NULL; 27 m_LogPos[i] = 0; 28 } 29 _CATCH_ 30 } 31 32 Log::~Log() 33 { 34 _TRY_ 35 for (int i=0; i<LOG_FILE_NUMBER; ++i) 36 { 37 if (NULL != m_LogCache[i]) 38 { 39 delete [] m_LogCache[i]; 40 m_LogCache[i] = NULL; 41 } 42 m_LogPos[i] = 0; 43 } 44 45 m_CacheSize = 0; 46 m_DayTime = 0; 47 _CATCH_ 48 } 49 50 BOOL Log::Init() 51 { 52 _TRY_ 53 m_CacheSize = DEFAULT_LOG_CACHE_SIZE; 54 55 //最小化内存占用 56 if (0 != m_Model) 57 { 58 for (int i=0; i<LOG_FILE_NUMBER; ++i) 59 { 60 m_LogCache[i] = new CHAR[m_CacheSize]; 61 if (NULL == m_LogCache[i]) 62 { 63 return FALSE; 64 } 65 m_LogPos[i] = 0; 66 } 67 } 68 69 m_DayTime = 0; 70 71 _CATCH_BOOL_ 72 73 return TRUE; 74 } 75 76 //取得保存日志的文件名称 77 VOID Log::GetLogName(INT logid, CHAR *filename) 78 { 79 sprintf(filename, "%s.log", g_pLogFileName[logid]); 80 } 81 82 //向日志缓存写入日志信息 83 VOID Log::FastSaveLog(INT logid, CHAR* msg, ...) 84 { 85 _TRY_ 86 if (0 > logid || logid >= LOG_FILE_NUMBER) 87 { 88 printf("logid: %d is error.\n", logid); 89 return ; 90 } 91 92 CHAR buffer[2048] = {0}; 93 va_list argptr; 94 95 try 96 { 97 va_start(argptr, msg); 98 vsprintf(buffer, msg, argptr); 99 va_end(argptr); 100 101 if (TRUE) 102 { 103 CHAR szTime[64] ; 104 sprintf( szTime, " (%d)(T=%.4f)\r\n", logid, 10.0 ) ; 105 strcat( buffer, szTime ) ; 106 } 107 } 108 catch (...) 109 { 110 assert(FALSE); 111 return ; 112 } 113 114 INT iLen = static_cast<INT>(strlen(buffer)); 115 if (iLen < 0) 116 { 117 return; 118 } 119 120 //最小化内存占用 121 if (0 == m_Model) 122 { 123 CHAR szName[_MAX_PATH] = {0}; 124 GetLogName(logid, szName); 125 126 SaveLog(szName, buffer); 127 return ; 128 } 129 130 m_LogLock[logid].Lock(); 131 try 132 { 133 memcpy(m_LogCache[logid] + m_LogPos[logid], buffer, iLen); 134 m_LogPos[logid] += iLen; 135 } 136 catch (...) 137 { 138 assert(FALSE); 139 m_LogLock[logid].Unlock(); 140 return ; 141 } 142 m_LogLock[logid].Unlock(); 143 144 if( m_LogPos[logid] > 10/*(DEFAULT_LOG_CACHE_SIZE*2)/3*/ ) 145 { 146 FlushLog( logid ) ; 147 } 148 return ; 149 150 _CATCH_ 151 return ; 152 } 153 154 //将日志内存数据写入日志 155 VOID Log::FlushLog(INT logid) 156 { 157 _TRY_ 158 CHAR szName[_MAX_PATH] = {0}; 159 GetLogName(logid, szName); 160 161 m_LogLock[logid].Lock(); 162 FILE *f = NULL; 163 try 164 { 165 f = fopen(szName, "ab"); 166 assert(f); 167 fwrite(m_LogCache[logid], 1, m_LogPos[logid], f); 168 fclose(f); 169 m_LogPos[logid] = 0; 170 } 171 catch(...) 172 { 173 assert(FALSE); 174 fclose(f); 175 m_LogPos[logid] = 0; 176 m_LogLock[logid].Unlock(); 177 return ; 178 } 179 m_LogLock[logid].Unlock(); 180 _CATCH_ 181 } 182 183 //刷新每个日志文件 184 VOID Log::FlushLog_ALL() 185 { 186 _TRY_ 187 for (int i=0; i<LOG_FILE_NUMBER; ++i) 188 { 189 FlushLog(i); 190 } 191 _CATCH_ 192 } 193 194 //支持异步写入操作的日志写入 195 VOID Log::SaveLog(CHAR* filename, CHAR* msg, ...) 196 { 197 g_LogLock.Lock(); 198 try 199 { 200 CHAR buffer[2048] = {0}; 201 va_list argptr; 202 FILE *f = NULL; 203 204 try 205 { 206 va_start(argptr, msg); 207 vsprintf(buffer, msg, argptr); 208 va_end(argptr); 209 210 CHAR szTime[64] ; 211 if(TRUE) 212 { 213 memset( szTime, 0, 64 ) ; 214 sprintf( szTime, " (%d)(T=%.4f)\r\n", 1, 20.0) ; 215 strcat( buffer, szTime ) ; 216 } 217 218 f = fopen(filename, "ab"); 219 assert(f); 220 fwrite( buffer, 1, strlen(buffer), f ) ; 221 fclose(f) ; 222 } 223 catch (...) 224 { 225 assert(FALSE); 226 fclose(f) ; 227 g_LogLock.Unlock(); 228 } 229 } 230 catch (...) 231 { 232 assert(FALSE); 233 g_LogLock.Unlock(); 234 return ; 235 } 236 237 g_LogLock.Unlock(); 238 } 239 240 //删除日志内容 241 VOID Log::RemoveLog(CHAR *filename) 242 { 243 g_LogLock.Lock(); 244 try 245 { 246 FILE* f = fopen( filename, "w" ) ; 247 fclose(f) ; 248 } 249 catch (...) 250 { 251 assert(FALSE); 252 g_LogLock.Unlock(); 253 } 254 g_LogLock.Unlock(); 255 }
//util.h
1 #ifndef _UTIL_H_ 2 #define _UTIL_H_ 3 4 5 //共享锁 6 class LockLock 7 { 8 public : 9 LockLock( ) 10 { 11 InitializeCriticalSection(&m_Lock); 12 } 13 14 ~LockLock( ) 15 { 16 DeleteCriticalSection(&m_Lock); 17 } 18 19 VOID Lock( ) 20 { 21 EnterCriticalSection(&m_Lock); 22 } 23 24 VOID Unlock( ) 25 { 26 LeaveCriticalSection(&m_Lock); 27 } 28 29 private: 30 CRITICAL_SECTION m_Lock ; 31 }; 32 33 34 //自动加锁解锁器 35 class AutoLock 36 { 37 public: 38 AutoLock(LockLock& rLock) 39 { 40 m_pLock = &rLock; 41 m_pLock->Lock(); 42 } 43 44 ~AutoLock() 45 { 46 m_pLock->Unlock(); 47 } 48 49 private: 50 AutoLock(); 51 LockLock* m_pLock; 52 }; 53 54 #endif
//type.h
1 #ifndef _TYPE_H_ 2 #define _TYPE_H_ 3 4 5 #include <Windows.h> 6 #include "crtdbg.h" 7 8 9 #include <stdio.h> 10 #include <iostream> 11 #include <fstream> 12 #include <string> 13 #include <time.h> 14 #include <math.h> 15 #include <stdarg.h> 16 17 using namespace std; 18 19 20 #define VOID void 21 typedef unsigned char UCHAR; 22 typedef char CHAR; 23 typedef unsigned int UINT; 24 typedef int INT; 25 typedef unsigned short USHORT; 26 typedef short SHORT; 27 typedef unsigned long ULONG; 28 typedef long LONG; 29 typedef float FLOAT; 30 31 typedef UCHAR uchar; 32 typedef USHORT ushort; 33 typedef UINT uint; 34 typedef ULONG ulong; 35 typedef ULONG IP_t; 36 typedef USHORT PacketID_t; 37 typedef INT BOOL; 38 typedef UCHAR BYTE; 39 40 41 42 #endif
//main.cpp
1 #include <stdio.h> 2 #include "Log.h" 3 4 int main(int argc, char **argv) 5 { 6 printf("MyLog...\n"); 7 8 Log::SaveLog("./Log/debug.log", "main" ); 9 Log::SaveLog("./Log/debug.log", "****" ); 10 11 g_pLog = new Log(1); 12 if(FALSE == g_pLog->Init()) 13 { 14 Log::SaveLog("./Log/error.log", "初始化log失败"); 15 return -1; 16 } 17 18 g_pLog->FastSaveLog(LOG_Assert, "test MyLog : %d, %s.\n", 1, "hello"); 19 g_pLog->FastSaveLog(LOG_Assert, "test MyLog : %d, %s.\n", 2, "world"); 20 21 if(NULL != g_pLog) 22 { 23 delete g_pLog; 24 g_pLog = NULL; 25 } 26 27 return 0; 28 };
使用时,需要在输出文件夹中创建log目录,在目录中把相关*.log文件建立好,比如此log类中的assert.log,error.log,debug.log