升龙物业 老版本 ocx IPO, 加密狗 转值班电话

LoggerEntity.cpp 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. #include "StdAfx.h"
  2. #include "LoggerEntity.h"
  3. #include <io.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. SINGLETON_IMPLEMENT(CLoggerEntity)
  7. ILogger& ILogger::getInstance(void)
  8. {
  9. return CLoggerEntity::GetInstance();
  10. }
  11. CLoggerEntity::CLoggerEntity(void) : m_bStopLog(TRUE), m_bIsLogger(FALSE), m_nFilterClass(LOG_CLASS_GENERAL), m_nFilterLevel(LOG_LEVEL_NORMAL), m_pThread(NULL)
  12. {
  13. m_arClass[0] = "PDU";
  14. m_arClass[1] = "DEV";
  15. m_arClass[2] = "业务";
  16. m_arClass[3] = "基本";
  17. m_arLevel[0] = "";
  18. m_arLevel[1] = "警告";
  19. m_arLevel[2] = "错误";
  20. m_arLevel[3] = "信息";
  21. }
  22. CLoggerEntity::~CLoggerEntity(void)
  23. {
  24. }
  25. /****************************************************************
  26. **【函数名称】 init
  27. **【函数功能】 日志初始化
  28. **【参数】 pList:日志显示的List控件
  29. nDevType:使用日志的系统
  30. lpFilePath:日志记录路径
  31. **【返回值】
  32. *****************************************************************/
  33. void CLoggerEntity::init( CListCtrl* pList, LOG_DEV nDevType, LPCTSTR lpFilePath /*= NULL */ )
  34. {
  35. // 列表控件的初始化
  36. if((m_pListCtrl = pList) != NULL)
  37. __frameControl();
  38. else
  39. __initConsoleWindow();
  40. // 保存设备类型
  41. m_nDevType = nDevType;
  42. switch(m_nDevType)
  43. {
  44. case LOG_DEV_CTI:
  45. m_strLoggerName = _T("log_cti");
  46. break;
  47. case LOG_DEV_IVR:
  48. m_strLoggerName = _T("log_ivr");
  49. break;
  50. case LOG_DEV_ACD:
  51. m_strLoggerName = _T("log_acd");
  52. break;
  53. case LOG_DEV_VS:
  54. m_strLoggerName = _T("log_vs");
  55. break;
  56. case LOG_DEV_FS:
  57. m_strLoggerName = _T("log_fs");
  58. break;
  59. case LOG_DEV_AC:
  60. m_strLoggerName = _T("log_ac");
  61. break;
  62. case LOG_DEV_SC:
  63. m_strLoggerName = _T("log_sc");
  64. break;
  65. case LOG_DEV_GUARD:
  66. m_strLoggerName = _T("log_guard");
  67. break;
  68. default:
  69. m_strLoggerName = _T("log_unknow");
  70. break;
  71. }
  72. if (lpFilePath == NULL)
  73. {
  74. // 默认路径
  75. m_strFileDircet = _T("d:\\middleware_log");
  76. }
  77. else
  78. {
  79. // 指定路径
  80. m_strFileDircet = lpFilePath;
  81. }
  82. m_bStopLog = FALSE;
  83. // 初始化记录日志线程
  84. m_pThread = AfxBeginThread(__logThread, this);
  85. }
  86. /****************************************************************
  87. **【函数名称】 close
  88. **【函数功能】 日志关闭
  89. **【参数】
  90. **【返回值】
  91. *****************************************************************/
  92. void CLoggerEntity::close( void )
  93. {
  94. m_bStopLog = TRUE;
  95. m_bIsLogger = FALSE;
  96. WaitForSingleObject(m_pThread->m_hThread, INFINITE);
  97. __flush();
  98. }
  99. /****************************************************************
  100. **【函数名称】 start
  101. **【函数功能】 开始显示日志
  102. **【参数】
  103. **【返回值】
  104. *****************************************************************/
  105. void CLoggerEntity::start( void )
  106. {
  107. m_bIsLogger = TRUE;
  108. }
  109. /****************************************************************
  110. **【函数名称】 stop
  111. **【函数功能】 停止显示日志
  112. **【参数】
  113. **【返回值】
  114. *****************************************************************/
  115. void CLoggerEntity::stop( void )
  116. {
  117. m_bIsLogger = FALSE;
  118. }
  119. /****************************************************************
  120. **【函数名称】 log
  121. **【函数功能】 添加一条新日志
  122. **【参数】 nClass:日志类型
  123. nLevel:日志级别
  124. format:日志信息
  125. **【返回值】
  126. *****************************************************************/
  127. void CLoggerEntity::log( LOG_CLASS nClass, LOG_LEVEL nLevel, char* format, ... )
  128. {
  129. // 解析日志信息参数
  130. char szMsgBuffer[LOG_BUFFER_LENGTH];
  131. memset(szMsgBuffer, 0, sizeof(szMsgBuffer));
  132. va_list ap;
  133. va_start(ap, format);
  134. vsprintf_s(szMsgBuffer, format, ap);
  135. __pushLog(nClass, nLevel, szMsgBuffer);
  136. }
  137. /****************************************************************
  138. **【函数名称】 filterShow
  139. **【函数功能】 设置日志内容过滤方式
  140. **【参数】 nClass:日志类型
  141. nLevel:日志级别
  142. **【返回值】
  143. *****************************************************************/
  144. void CLoggerEntity::filterShow( LOG_CLASS nClass /*= LOG_CLASS_GENERAL*/, LOG_LEVEL nLevel /*= LOG_LEVEL_NORMAL */ )
  145. {
  146. m_nFilterClass = nClass; // 日志类型过滤
  147. m_nFilterLevel = nLevel; // 日志级别过滤
  148. }
  149. /****************************************************************
  150. **【函数名称】 __frameControl
  151. **【函数功能】 日志界面控制
  152. **【参数】
  153. **【返回值】
  154. *****************************************************************/
  155. void CLoggerEntity::__frameControl()
  156. {
  157. CRect mRect;
  158. m_pListCtrl->GetClientRect(&mRect);
  159. int length = mRect.right - mRect.left - 240;
  160. //加载日志图标信息
  161. CImageList imgList;
  162. imgList.Create(16, 16, ILC_MASK|ILC_COLOR16, 3, 1);
  163. imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_INFORMATION));
  164. imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_WARNING));
  165. imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_ERROR));
  166. imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_INFORMATION));
  167. m_pListCtrl->SetImageList(&imgList, LVSIL_SMALL);
  168. imgList.Detach();
  169. //加载日志列表
  170. m_pListCtrl->SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
  171. m_pListCtrl->InsertColumn(0, (LPCTSTR)"时间", LVCFMT_LEFT, 140, -1);
  172. m_pListCtrl->InsertColumn(1, (LPCTSTR)"类型", LVCFMT_LEFT, 50, -1);
  173. m_pListCtrl->InsertColumn(2, (LPCTSTR)"分类", LVCFMT_LEFT, 50, -1);
  174. m_pListCtrl->InsertColumn(3, (LPCTSTR)"信息", LVCFMT_LEFT, length, -1);
  175. }
  176. /****************************************************************
  177. **【函数名称】 启动控制台窗口
  178. **【函数功能】 __initConsoleWindow
  179. **【参数】
  180. **【返回值】
  181. *****************************************************************/
  182. void CLoggerEntity::__initConsoleWindow( void )
  183. {
  184. if(!AllocConsole())
  185. return;
  186. int nCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
  187. if(nCrt == -1)
  188. return;
  189. FILE* fp = _fdopen(nCrt, "w");
  190. if(fp == NULL)
  191. return;
  192. *stdout = *fp;
  193. setvbuf(stdout, NULL, _IONBF, 0);
  194. }
  195. /****************************************************************
  196. **【函数名称】 创建日志文件
  197. **【函数功能】 __openLoggerFile
  198. **【参数】 lpFile
  199. **【返回值】
  200. *****************************************************************/
  201. FILE* CLoggerEntity::__openLoggerFile( void )
  202. {
  203. static int nCount = 1;
  204. FILE* pFile = NULL;
  205. // 获取当前日期
  206. CTime time = CTime::GetCurrentTime();
  207. // 创建日志总目录
  208. if(_access(m_strFileDircet, 0) == -1) CreateDirectoryA(m_strFileDircet, NULL);
  209. // 创建日期目录
  210. CString strPath = _T("");
  211. strPath.Format(_T("%s\\%d-%d-%d"), m_strFileDircet, time.GetYear(), time.GetMonth(), time.GetDay());
  212. if(_access(strPath, 0) == -1)
  213. {
  214. nCount = 1;
  215. CreateDirectoryA(strPath, NULL);
  216. }
  217. // 如果文件存在且大于指定大小,生成新的文件名
  218. CString strFileName = _T("");
  219. struct stat st;
  220. do
  221. {
  222. memset(&st, 0, sizeof(st));
  223. strFileName.Format(_T("%s\\%s_%d.txt"), strPath, m_strLoggerName, nCount);
  224. if(stat(strFileName, &st) == 0)
  225. {
  226. if(st.st_size > FILE_MAX_SIZE) nCount++;
  227. }
  228. }
  229. while(st.st_size > FILE_MAX_SIZE);
  230. // 打开文件
  231. fopen_s(&pFile, strFileName, "a+");
  232. return pFile;
  233. }
  234. /****************************************************************
  235. **【函数名称】 __pushLog
  236. **【函数功能】 将日志压入链表
  237. **【参数】
  238. **【返回值】
  239. *****************************************************************/
  240. void CLoggerEntity::__pushLog( LOG_CLASS nClass, LOG_LEVEL nLevel, LPCTSTR lpMessage )
  241. {
  242. // 检查过滤标志
  243. if ((m_nFilterClass & nClass) == nClass
  244. && (m_nFilterLevel & nLevel) == nLevel)
  245. {
  246. // 获取当前时间
  247. CTime t1 = CTime::GetCurrentTime();
  248. CString strTime = t1.Format("%Y-%m-%d %H:%M:%S");
  249. PLOG_ITEM pItem = new LOG_ITEM(nClass, nLevel, strTime, lpMessage);
  250. ASSERT(pItem != NULL);
  251. // 日志信息记入缓冲队列
  252. m_LockSection.Lock();
  253. // 保证缓冲区字节大小不超过10M
  254. if(m_ItemList.GetCount() < LOG_BUFFER_SIZE)
  255. m_ItemList.AddTail(pItem);
  256. m_LockSection.Unlock();
  257. }
  258. }
  259. /****************************************************************
  260. **【函数名称】 __pushLog
  261. **【函数功能】 从链表中弹出日志
  262. **【参数】
  263. **【返回值】
  264. *****************************************************************/
  265. CLoggerEntity::PLOG_ITEM CLoggerEntity::__popLog( void )
  266. {
  267. CSingleLock Locker(&m_LockSection, TRUE);
  268. if(!m_ItemList.IsEmpty())
  269. return m_ItemList.RemoveHead();
  270. else
  271. return NULL;
  272. }
  273. /****************************************************************
  274. **【函数名称】 __logShow
  275. **【函数功能】 显示日志
  276. **【参数】
  277. **【返回值】
  278. *****************************************************************/
  279. void CLoggerEntity::__saveLog( PLOG_ITEM pItem, FILE* pFile )
  280. {
  281. LOG_CLASS Class = pItem->Class;
  282. LOG_LEVEL Level = pItem->Level;
  283. CString LogContent;
  284. LogContent.Format(_T("%s %s %s %s\r\n"), pItem->Date, m_arLevel[Level], m_arClass[Class], pItem->Content);
  285. // 写日志文件
  286. fwrite(LogContent, LogContent.GetLength(), 1, pFile);
  287. if(!m_bIsLogger)
  288. return;
  289. // UI展现
  290. if(m_pListCtrl == NULL)
  291. {
  292. cout << LogContent;
  293. }
  294. else
  295. {
  296. // 定义系统日志显示条数的上限为499条
  297. m_pListCtrl->InsertItem(0, pItem->Date, Level);
  298. m_pListCtrl->SetItemText(0, 1, m_arLevel[Level]);
  299. m_pListCtrl->SetItemText(0, 2, m_arClass[Class]);
  300. m_pListCtrl->SetItemText(0, 3, pItem->Content);
  301. // 日志显示行数控制(500)
  302. if(m_pListCtrl->GetItemCount() == 500)
  303. {
  304. m_pListCtrl->DeleteItem(499);
  305. }
  306. }
  307. }
  308. /****************************************************************
  309. **【函数名称】 记录日志线程函数
  310. **【函数功能】 __logThreadFunc
  311. **【参数】 pParam:线程参数
  312. **【返回值】
  313. *****************************************************************/
  314. UINT CLoggerEntity::__logThread( LPVOID pParam )
  315. {
  316. CLoggerEntity* pSelf = (CLoggerEntity*)pParam;
  317. FILE *pFile = NULL;
  318. PLOG_ITEM pItem = NULL;
  319. while(!pSelf->m_bStopLog)
  320. {
  321. // 获取文件指针
  322. pFile = pSelf->__openLoggerFile();
  323. if(pFile != NULL)
  324. {
  325. while((pItem = pSelf->__popLog()) != NULL)
  326. {
  327. pSelf->__saveLog(pItem, pFile);
  328. delete pItem;
  329. }
  330. // 关闭文件
  331. fclose(pFile);
  332. }
  333. // 暂停一秒钟
  334. Sleep(1000);
  335. }
  336. return 0;
  337. }
  338. /****************************************************************
  339. **【函数名称】 __flush
  340. **【函数功能】 保存残留的LOGITEM
  341. **【参数】
  342. **【返回值】
  343. *****************************************************************/
  344. void CLoggerEntity::__flush( void )
  345. {
  346. if(m_ItemList.IsEmpty())
  347. return;
  348. FILE *pFile = __openLoggerFile();
  349. if(pFile == NULL)
  350. return;
  351. while(!m_ItemList.IsEmpty())
  352. {
  353. PLOG_ITEM pItem = m_ItemList.RemoveHead();
  354. ASSERT(pItem != NULL);
  355. __saveLog(pItem, pFile);
  356. delete pItem;
  357. }
  358. fclose(pFile);
  359. }