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 }

 

posted on 2017-07-14 15:23  蒙遥  阅读(178)  评论(0编辑  收藏  举报