1 #include "stdafx.h" 2 #include "GB_Logger.h" 3 #include <imagehlp.h> 4 #include <time.h> 5 #include <stdarg.h> 6 #include <tchar.h> 7 8 9 10 GB_Logger* GB_Logger::logger = NULL; 11 12 13 TCHAR g_LOGDIRECTORYPATH[MAX_STR_LEN] = {0}; //存放日志目录 14 15 //默认构造函数 16 GB_Logger::GB_Logger() 17 { 18 //初始化 19 //memset(g_LOGDIRECTORYPATH, 0, MAX_STR_LEN); 20 memset(m_strCurLogName, 0, MAX_STR_LEN); 21 22 //设置默认的写日志级别 23 m_nLogLevel = EnumLogLevel::LogLevelNormal; 24 GenerateLogName(); 25 //初始化临界区变量 26 InitializeCriticalSection(&m_cs); 27 28 //创建日志文件名 29 30 } 31 32 //析构函数 33 GB_Logger::~GB_Logger() 34 { 35 //释放临界区 36 DeleteCriticalSection(&m_cs); 37 //关闭文件流 38 if (m_hFile) 39 { 40 CloseHandle(m_hFile); 41 } 42 } 43 44 int GB_Logger::TraceLogger(EnumLogType pLogType, const TCHAR * strInfo, ...) 45 { 46 if (!strInfo) 47 return 0; 48 //TCHAR* str_buffer = (TCHAR *)malloc(sizeof(TCHAR)* MAX_STR_LEN); 49 TCHAR str_Buffer[MAX_STR_LEN] = { 0 }; 50 GetCurrentTimeToTChar(str_Buffer, MAX_STR_LEN); 51 switch (pLogType) 52 { 53 case ErrInfo: 54 if (m_nLogLevel >= EnumLogLevel::LogLevelStop) //不写日志。 55 return 2; 56 lstrcat(str_Buffer, _T(" Error: ")); 57 break; 58 case WarnInfo: 59 if (m_nLogLevel >= EnumLogLevel::LogLevelNormal) //只写错误日志。 60 return 2; 61 lstrcat(str_Buffer, _T(" Warning:")); 62 break; 63 case trackingInfo: 64 if (m_nLogLevel >= EnumLogLevel::LogLevelMid) //当前只记录错误和警告信息。 65 return 2; 66 lstrcat(str_Buffer, _T(" trackingInfo:")); 67 break; 68 default: 69 lstrcat(str_Buffer, _T(":")); 70 return 2; 71 } 72 va_list arg_ptr = NULL; 73 va_start(arg_ptr, strInfo); 74 TCHAR p_Content[MAX_STR_LEN] = { 0 }; 75 _vsntprintf_s(p_Content,sizeof(TCHAR)*MAX_STR_LEN, strInfo, arg_ptr); 76 lstrcat(str_Buffer, p_Content); 77 va_end(arg_ptr); 78 arg_ptr = NULL; 79 WriteStrToLoggerFile(str_Buffer); 80 return 1; 81 } 82 83 //将信息发送到指定的windows窗体 84 int GB_Logger::SendInfoToWindows(HWND hWnd,const TCHAR * strFormat, ...) 85 { 86 //判断当前的写日志级别,若设置只写错误和警告信息则函数返回 87 if (!strFormat) 88 return 0; 89 TCHAR prefix[MAX_STR_LEN] = { 0 }; 90 TCHAR str_Buffer[MAX_STR_LEN] = { 0 }; 91 GetCurrentTimeToTChar(str_Buffer,MAX_STR_LEN); 92 lstrcat(str_Buffer, _T(": ")); 93 va_list arg_ptr = NULL; 94 va_start(arg_ptr, strFormat); //让arg_ptr指向参数列表中的第一参数地址。注意:函数参数是以数据结构,栈的形式存取,从右至左入栈。 95 TCHAR p_Content[MAX_STR_LEN] = { 0 }; 96 _vsntprintf_s(p_Content, MAX_STR_LEN, strFormat, arg_ptr); 97 lstrcat(str_Buffer, p_Content); 98 va_end(arg_ptr); 99 arg_ptr = NULL; 100 ::SendMessage(hWnd, WM_USERDEFINEWINDOWSINFO, 0, (LPARAM)&str_Buffer); //同步 101 return 1; 102 } 103 104 int GB_Logger::SetLogDirectory(const TCHAR * strDirectoryPath) 105 { 106 __try{ 107 //进入临界区 108 EnterCriticalSection(&m_cs); 109 if (m_hFile) 110 { 111 if (CloseHandle(m_hFile) != 0) 112 perror("close file fail!"); 113 else 114 m_hFile = nullptr; 115 } 116 _tcscpy_s(g_LOGDIRECTORYPATH, MAX_STR_LEN, strDirectoryPath); 117 if (0 != _tcslen(g_LOGDIRECTORYPATH)) 118 { 119 lstrcat(g_LOGDIRECTORYPATH, _T("//")); 120 } 121 int hr = CreateDirectory(g_LOGDIRECTORYPATH, NULL); 122 if (hr<0) 123 { 124 return hr; 125 } 126 GenerateLogName(); 127 return 1; 128 } 129 __finally{ 130 LeaveCriticalSection(&m_cs); 131 } 132 } 133 134 //获取系统当前时间 135 int GB_Logger::GetCurrentTimeToTChar(OUT TCHAR* p_ResultBuffer, int p_SizeOfResultBuffer) 136 { 137 time_t curTime; 138 tm pTimeInfo; 139 time(&curTime); 140 localtime_s(&pTimeInfo, &curTime); 141 _stprintf_s(p_ResultBuffer, p_SizeOfResultBuffer, _T("%02d:%02d:%02d"), pTimeInfo.tm_hour, pTimeInfo.tm_min, pTimeInfo.tm_sec); 142 return 1; 143 } 144 145 //写文件操作 146 int GB_Logger::WriteStrToLoggerFile(const TCHAR * strInfo) 147 { 148 if (!strInfo) 149 return 0; 150 try 151 { 152 //进入临界区 153 EnterCriticalSection(&m_cs); 154 //若文件流没有打开,则重新打开 155 if (!m_hFile) 156 { 157 HANDLE hFile; 158 TCHAR stBuffer[1024] = { 0 }; 159 lstrcat(stBuffer, g_LOGDIRECTORYPATH); 160 lstrcat(stBuffer, m_strCurLogName); 161 hFile = CreateFile(stBuffer, //指向文件名的指针 162 GENERIC_WRITE | GENERIC_READ, //访问模式(读/写) 写,读 163 FILE_SHARE_READ, // 共享模式 不共享 164 NULL, //指向安全属性的指针 165 OPEN_ALWAYS, //如何让创建 166 FILE_ATTRIBUTE_NORMAL, //文件属性 167 NULL); //用于复制文件句柄 168 if (hFile == INVALID_HANDLE_VALUE) 169 { 170 AfxMessageBox(_T("创建日志文件失败")); 171 return GetLastError(); 172 } 173 this->m_hFile = hFile; 174 } 175 if (m_hFile) 176 { 177 //写日志信息到文件流 178 TCHAR pLogbuff[MAX_PATH] = { 0 }; 179 _stprintf_s(pLogbuff, _T("%s\n"), strInfo); 180 181 if (SetFilePointer(m_hFile, 0, NULL, FILE_END) == -1) 182 { 183 printf("SetFilePointer error\n"); 184 return 0; 185 } 186 187 DWORD ReturnCharNumber; 188 WriteFile(m_hFile, pLogbuff, _tcslen(pLogbuff)*sizeof(TCHAR), &ReturnCharNumber, NULL); 189 //判断当前日志文件大小,单位是字节。 190 //LONGLONG file_size = 0; 191 //file_size = GetFileSize(m_hFile, NULL); 192 193 LARGE_INTEGER FileSize; 194 GetFileSizeEx(m_hFile, &FileSize); 195 if (FileSize.QuadPart >= MAX_LOGFILESIZE) 196 { 197 CloseHandle(m_hFile); 198 TCHAR str_Buffer[1024] = { 0 }; 199 TCHAR* str_TimeBuffer = (TCHAR *)malloc(sizeof(TCHAR)* MAX_STR_LEN); 200 GetCurrentTimeToTChar(str_TimeBuffer, MAX_STR_LEN); 201 lstrcat(str_Buffer, m_strCurLogName); 202 lstrcat(str_Buffer, str_TimeBuffer); 203 memset(m_strCurLogName, 0, MAX_STR_LEN); 204 lstrcat(m_strCurLogName, str_Buffer); 205 } 206 } 207 208 //离开临界区 209 LeaveCriticalSection(&m_cs); 210 return 1; 211 } 212 //若发生异常,则先离开临界区,防止死锁 213 catch (...) 214 { 215 LeaveCriticalSection(&m_cs); 216 return 0; 217 } 218 return 1; 219 } 220 221 //创建日志文件的名称 222 void GB_Logger::GenerateLogName() 223 { 224 time_t curTime; 225 tm pTimeInfo; 226 time(&curTime); 227 localtime_s(&pTimeInfo, &curTime); 228 TCHAR temp[1024] = { 0 }; 229 //日志的名称如:2013-01-01.log 230 _stprintf_s(temp, _T("%04d-%02d-%02d-%02d.log"), pTimeInfo.tm_year + 1900, pTimeInfo.tm_mon + 1, pTimeInfo.tm_mday,pTimeInfo.tm_hour); 231 if (0 != _tcscmp(m_strCurLogName, temp)) //如果文件名称不存在,创建该文件。 232 { 233 _tcscpy_s(m_strCurLogName, temp); 234 if (m_hFile) 235 CloseHandle(m_hFile); 236 TCHAR temp[1024] = { 0 }; 237 lstrcat(temp, g_LOGDIRECTORYPATH); 238 lstrcat(temp, m_strCurLogName); 239 //以追加的方式打开文件流 240 //_tfopen_s(&m_pFileStream, temp, _T("a+")); 241 } 242 243 } 244 245 GB_Logger* GB_Logger::GetInstance() 246 { 247 if (NULL == logger) 248 { 249 GB_Logger* pLog = new GB_Logger(); 250 logger = pLog; 251 } 252 return logger; 253 }