| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- #include "StdAfx.h"
- #include "LoggerEntity.h"
- #include <io.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- SINGLETON_IMPLEMENT(CLoggerEntity)
- ILogger& ILogger::getInstance(void)
- {
- return CLoggerEntity::GetInstance();
-
- }
- CLoggerEntity::CLoggerEntity(void) : m_bStopLog(TRUE), m_bIsLogger(FALSE), m_nFilterClass(LOG_CLASS_GENERAL), m_nFilterLevel(0x07), m_pThread(NULL)
- {
- m_arClass[0] = "PDU";
- m_arClass[1] = "DEV";
- m_arClass[2] = "业务";
- m_arClass[3] = "基本";
- m_arLevel[0] = "";
- m_arLevel[1] = "警告";
- m_arLevel[2] = "错误";
- m_arLevel[3] = "信息";
- m_arLevel[4] = "详细";
- }
- CLoggerEntity::~CLoggerEntity(void)
- {
- }
- /****************************************************************
- **【函数名称】 init
- **【函数功能】 日志初始化
- **【参数】 pList:日志显示的List控件
- nDevType:使用日志的系统
- lpFilePath:日志记录路径
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::init( CListCtrl* pList, LOG_DEV nDevType, LPCTSTR lpFilePath /*= NULL */ )
- {
- // 列表控件的初始化
- if((m_pListCtrl = pList) != NULL)
- __frameControl();
- else
- __initConsoleWindow();
- // 保存设备类型
- m_nDevType = nDevType;
- switch(m_nDevType)
- {
- case LOG_DEV_CTI:
- m_strLoggerName = _T("log_cti");
- break;
- case LOG_DEV_IVR:
- m_strLoggerName = _T("log_ivr");
- break;
- case LOG_DEV_ACD:
- m_strLoggerName = _T("log_acd");
- break;
- case LOG_DEV_VS:
- m_strLoggerName = _T("log_vs");
- break;
- case LOG_DEV_FS:
- m_strLoggerName = _T("log_fs");
- break;
- case LOG_DEV_AC:
- m_strLoggerName = _T("log_ac");
- break;
- case LOG_DEV_SC:
- m_strLoggerName = _T("log_sc");
- break;
- case LOG_DEV_GUARD:
- m_strLoggerName = _T("log_guard");
- break;
- case LOG_DEV_SERVER:
- m_strLoggerName = _T("log_http");
- break;
- default:
- m_strLoggerName = _T("log_unknow");
- break;
- }
- if (lpFilePath == NULL)
- {
- // 默认路径
- m_strFileDircet = _T("d:\\middleware_log");
- }
- else
- {
- // 指定路径
- m_strFileDircet = lpFilePath;
- }
- m_bStopLog = FALSE;
- // 初始化记录日志线程
- m_pThread = AfxBeginThread(__logThread, this);
- }
- /****************************************************************
- **【函数名称】 close
- **【函数功能】 日志关闭
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::close( void )
- {
- m_bStopLog = TRUE;
- m_bIsLogger = FALSE;
- WaitForSingleObject(m_pThread->m_hThread, INFINITE);
- __flush();
- }
- /****************************************************************
- **【函数名称】 start
- **【函数功能】 开始显示日志
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::start( void )
- {
- m_bIsLogger = TRUE;
- }
- /****************************************************************
- **【函数名称】 stop
- **【函数功能】 停止显示日志
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::stop( void )
- {
- m_bIsLogger = FALSE;
- }
- /****************************************************************
- **【函数名称】 log
- **【函数功能】 添加一条新日志
- **【参数】 nClass:日志类型
- nLevel:日志级别
- format:日志信息
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::log( LOG_CLASS nClass, LOG_LEVEL nLevel, char* format, ... )
- {
- // 检查过滤标志
- if ((m_nFilterClass & nClass) == nClass &&(m_nFilterLevel & nLevel) == nLevel && nLevel < 5)
- {
- // 解析日志信息参数
- char szMsgBuffer[LOG_BUFFER_LENGTH];
- memset(szMsgBuffer, 0, sizeof(szMsgBuffer));
- va_list ap;
- va_start(ap, format);
- vsprintf_s(szMsgBuffer, format, ap);
- __pushLog(nClass, nLevel, szMsgBuffer);
- }
- }
- /****************************************************************
- **【函数名称】 filterShow
- **【函数功能】 设置日志内容过滤方式
- **【参数】 nClass:日志类型
- nLevel:日志级别
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::filterShow( LOG_CLASS nClass /*= LOG_CLASS_GENERAL*/, LOG_LEVEL nLevel /*= LOG_LEVEL_NORMAL */ )
- {
- m_nFilterClass = nClass; // 日志类型过滤
- m_nFilterLevel = nLevel; // 日志级别过滤
- }
- /****************************************************************
- **【函数名称】 __frameControl
- **【函数功能】 日志界面控制
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::__frameControl()
- {
- CRect mRect;
- m_pListCtrl->GetClientRect(&mRect);
- int length = mRect.right - mRect.left - 240;
- //加载日志图标信息
- CImageList imgList;
- imgList.Create(16, 16, ILC_MASK|ILC_COLOR16, 3, 1);
- imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_INFORMATION));
- imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_WARNING));
- imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_ERROR));
- imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_INFORMATION));
- m_pListCtrl->SetImageList(&imgList, LVSIL_SMALL);
- imgList.Detach();
- //加载日志列表
- m_pListCtrl->SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
- m_pListCtrl->InsertColumn(0, (LPCTSTR)"时间", LVCFMT_LEFT, 140, -1);
- m_pListCtrl->InsertColumn(1, (LPCTSTR)"类型", LVCFMT_LEFT, 50, -1);
- m_pListCtrl->InsertColumn(2, (LPCTSTR)"分类", LVCFMT_LEFT, 50, -1);
- m_pListCtrl->InsertColumn(3, (LPCTSTR)"信息", LVCFMT_LEFT, length, -1);
- }
- /****************************************************************
- **【函数名称】 启动控制台窗口
- **【函数功能】 __initConsoleWindow
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::__initConsoleWindow( void )
- {
- if(!AllocConsole())
- return;
- int nCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
- if(nCrt == -1)
- return;
- FILE* fp = _fdopen(nCrt, "w");
- if(fp == NULL)
- return;
- *stdout = *fp;
- setvbuf(stdout, NULL, _IONBF, 0);
- }
- /****************************************************************
- **【函数名称】 创建日志文件
- **【函数功能】 __openLoggerFile
- **【参数】 lpFile
- **【返回值】
- *****************************************************************/
- FILE* CLoggerEntity::__openLoggerFile( void )
- {
- static int nCount = 1;
- FILE* pFile = NULL;
- // 获取当前日期
- CTime time = CTime::GetCurrentTime();
- // 创建日志总目录
- if(_access(m_strFileDircet, 0) == -1) CreateDirectoryA(m_strFileDircet, NULL);
- // 创建日期目录
- CString strPath = _T("");
- strPath.Format(_T("%s\\%d-%d-%d"), m_strFileDircet, time.GetYear(), time.GetMonth(), time.GetDay());
- if(_access(strPath, 0) == -1)
- {
- nCount = 1;
- CreateDirectoryA(strPath, NULL);
- }
- // 如果文件存在且大于指定大小,生成新的文件名
- CString strFileName = _T("");
- struct stat st;
- do
- {
- memset(&st, 0, sizeof(st));
- strFileName.Format(_T("%s\\%s_%d.txt"), strPath, m_strLoggerName, nCount);
- if(stat(strFileName, &st) == 0)
- {
- if(st.st_size > FILE_MAX_SIZE) nCount++;
- }
- }
- while(st.st_size > FILE_MAX_SIZE);
- // 打开文件
- fopen_s(&pFile, strFileName, "a+");
- return pFile;
- }
- /****************************************************************
- **【函数名称】 __pushLog
- **【函数功能】 将日志压入链表
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::__pushLog( LOG_CLASS nClass, LOG_LEVEL nLevel, LPCTSTR lpMessage )
- {
- // 获取当前时间
- CTime t1 = CTime::GetCurrentTime();
- CString strTime = t1.Format("%Y-%m-%d %H:%M:%S");
- PLOG_ITEM pItem = new LOG_ITEM(nClass, nLevel, strTime, lpMessage);
- ASSERT(pItem != NULL);
- // 日志信息记入缓冲队列
- m_LockSection.Lock();
- // 保证缓冲区字节大小不超过10M
- if(m_ItemList.GetCount() < LOG_BUFFER_SIZE)
- m_ItemList.AddTail(pItem);
- m_LockSection.Unlock();
- }
- /****************************************************************
- **【函数名称】 __pushLog
- **【函数功能】 从链表中弹出日志
- **【参数】
- **【返回值】
- *****************************************************************/
- CLoggerEntity::PLOG_ITEM CLoggerEntity::__popLog( void )
- {
- CSingleLock Locker(&m_LockSection, TRUE);
- if(!m_ItemList.IsEmpty())
- return m_ItemList.RemoveHead();
- else
- return NULL;
- }
- /****************************************************************
- **【函数名称】 __logShow
- **【函数功能】 显示日志
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::__saveLog( PLOG_ITEM pItem, FILE* pFile )
- {
- LOG_CLASS Class = pItem->Class;
- LOG_LEVEL Level = pItem->Level;
- CString LogContent;
- LogContent.Format(_T("%s %s %s %s\r\n"), pItem->Date, m_arLevel[Level], m_arClass[Class], pItem->Content);
- // 写日志文件
- fwrite(LogContent, LogContent.GetLength(), 1, pFile);
- if(!m_bIsLogger)
- return;
- if (Level > LOG_LEVEL_NORMAL)
- return;
- // UI展现
- if(m_pListCtrl == NULL)
- {
- cout << LogContent;
- }
- else
- {
- // 定义系统日志显示条数的上限为499条
- m_pListCtrl->InsertItem(0, pItem->Date, Level);
- m_pListCtrl->SetItemText(0, 1, m_arLevel[Level]);
- m_pListCtrl->SetItemText(0, 2, m_arClass[Class]);
- m_pListCtrl->SetItemText(0, 3, pItem->Content);
- // 日志显示行数控制(500)
- if(m_pListCtrl->GetItemCount() == 500)
- {
- m_pListCtrl->DeleteItem(499);
- }
- }
- }
- /****************************************************************
- **【函数名称】 记录日志线程函数
- **【函数功能】 __logThreadFunc
- **【参数】 pParam:线程参数
- **【返回值】
- *****************************************************************/
- UINT CLoggerEntity::__logThread( LPVOID pParam )
- {
- CLoggerEntity* pSelf = (CLoggerEntity*)pParam;
- FILE *pFile = NULL;
- PLOG_ITEM pItem = NULL;
- while(!pSelf->m_bStopLog)
- {
- // 获取文件指针
- pFile = pSelf->__openLoggerFile();
- if(pFile != NULL)
- {
- while((pItem = pSelf->__popLog()) != NULL)
- {
- pSelf->__saveLog(pItem, pFile);
- delete pItem;
- }
- // 关闭文件
- fclose(pFile);
- }
- // 暂停一秒钟
- Sleep(1000);
- }
- return 0;
- }
- /****************************************************************
- **【函数名称】 __flush
- **【函数功能】 保存残留的LOGITEM
- **【参数】
- **【返回值】
- *****************************************************************/
- void CLoggerEntity::__flush( void )
- {
- if(m_ItemList.IsEmpty())
- return;
- FILE *pFile = __openLoggerFile();
- if(pFile == NULL)
- return;
- while(!m_ItemList.IsEmpty())
- {
- PLOG_ITEM pItem = m_ItemList.RemoveHead();
- ASSERT(pItem != NULL);
- __saveLog(pItem, pFile);
- delete pItem;
- }
- fclose(pFile);
- }
|