#include "Logstdafx.h" #include "CLogFile.h" CCLogFile::CCLogFile(LPCTSTR szFileName, bool bLogNeedManage) :m_bFileNameCommited(!bLogNeedManage) { SYSTEMTIME __sTime; ::GetLocalTime(&__sTime); if (NULL != szFileName) { m_szFile = szFileName; CString str; str.Format("%s %04d%02d%02d%02d%02d%02d%03d.log", m_szFile, __sTime.wYear, __sTime.wMonth, __sTime.wDay, __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds); m_szFile = str; } else { m_szFile = "hc_trace"; } } CCLogFile::~CCLogFile() { } /** 纪录操作处理信息,以及信息对应的文件名和所在行,其他同C的printf用法 比如在A.CPP文件的第11行进行如下调用: TraceProgress( __FILE__, __LINE__, "hi test[%d]", 3 ); 则相当于: Print( TRACER_OPE_PROGRESS, "%s:%d hi test[%d]", "A.CPP", 11, 3 ); @param szFile 信息对应的源文件名 @param lLine 信息所对应的行数 @param szData 格式字符串 @param ... 后续内容 @return 无 @see Print(TRACER_TYPE nType, LPCTSTR szData, ...) */ ///@endcond ///@cond CHS /** Log process type information example: TraceProgress( __FILE__, __LINE__, "hi test[%d]", 3 ); @param szFile File name @param lLine Program line @param szData Format string @param ... Other param */ void CCLogFile::TraceProgress(LPCTSTR szFile, long lLine, LPCTSTR szData, ...) { CString str; str.Format("%s(%ld) ", szFile, lLine); str.Append(szData); va_list pArgList; va_start(pArgList, szData); PrintV(TRACER_OPE_PROGRESS, str, pArgList); va_end(pArgList); } /** 纪录错误信息,以及信息对应的文件名和所在行,其他同C的printf用法 比如在A.CPP文件的第11行进行如下调用: TraceError( __FILE__, __LINE__, "hi test[%d]", 3 ); 则相当于: Print( TRACER_OPE_ERROR, "%s:%d hi test[%d]", "A.CPP", 11, 3 ); @param szFile 信息对应的源文件名 @param lLine 信息所对应的行数 @param szData 格式字符串 @param ... 后续内容 @return 无 @see Print(TRACER_TYPE nType, LPCTSTR szData, ...) */ ///@endcond ///@cond ENG /** Log error information example: TraceError( __FILE__, __LINE__, "hi test[%d]", 3 ); @param szFile File name @param lLine Program line @param szData Format string @param ... Other param */ ///@endcond void CCLogFile::TraceError(LPCTSTR szFile, long lLine, LPCTSTR szData, ...) { CString str; str.Format("%s(%ld) ", szFile, lLine); str.Append(szData); va_list pArgList; va_start(pArgList, szData); PrintV(TRACER_OPE_ERROR, str, pArgList); va_end(pArgList); } /** 纪录例外信息,以及信息对应的文件名和所在行,其他同C的printf用法 比如在A.CPP文件的第11行进行如下调用: TraceException( __FILE__, __LINE__, "hi test[%d]", 3 ); 则相当于: Print( TRACER_OPE_EXCEPTION, "%s:%d hi test[%d]", "A.CPP", 11, 3 ); @param szFile 信息对应的源文件名 @param lLine 信息所对应的行数 @param szData 格式字符串 @param ... 后续内容 @return 无 @see Print(TRACER_TYPE nType, LPCTSTR szData, ...) */ ///@endcond ///@cond ENG /** Log exception information example: TraceException( __FILE__, __LINE__, "hi test[%d]", 3 ); @param szFile File name @param lLine Program line @param szData Format string @param ... Other param */ ///@endcond void CCLogFile::TraceException(LPCTSTR szFile, long lLine, LPCTSTR szData, ...) { CString str; str.Format("%s(%ld) ", szFile, lLine); str.Append(szData); va_list pArgList; va_start(pArgList, szData); PrintV(TRACER_OPE_EXCEPTION, str, pArgList); va_end(pArgList); } /** Log normal information example: TraceMessage( __FILE__, __LINE__, "hi test[%d]", 3 ); @param szFile File name @param lLine Program line @param szData Format string @param ... Other param */ ///@endcond void CCLogFile::TraceMessage(LPCTSTR szFile, long lLine, LPCTSTR szData, ...) { CString str; str.Format("%s(%ld) ", szFile, lLine); str.Append(szData); va_list pArgList; va_start(pArgList, szData); PrintV(TRACER_OPE_MESSAGE, str, pArgList); va_end(pArgList); } /** 记录二进制数据 @param szHead 信息头 @param pbyData 数据 @param nLen 数据长度 */ ///@endcond ///@cond ENG /** Log binary data @param szHead Information @param pbyData Binary data @param nLen Data length */ ///@endcond void CCLogFile::LogBinaryData(LPCTSTR szHead, BYTE* pbyData, UINT nLen) { SYSTEMTIME __sTime; ::GetLocalTime(&__sTime); CString str; str.Format("%s.%04d%02d%02d", m_szFile, __sTime.wYear, __sTime.wMonth, __sTime.wDay); CSingleLock lock(&this->m_csBinLog, TRUE); HANDLE hLog = this->CreateLogFile(str); if (INVALID_HANDLE_VALUE == hLog) { return; } if (!szHead) { szHead = __T(" "); } str.Format("%02d:%02d:%02d.%03d|%4d| ---> %s\r\n ----------------------------------------------------------------------------\r\n", __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds , GetCurrentThreadId(), szHead); DWORD iLen = str.GetLength(); DWORD unBytesWritten = 0; WriteFile(hLog, str, iLen, &unBytesWritten, NULL); int iSeq = 0; CString strBin; const int BYTES_PER_LINE = 16; const int SEQ_LEN = 6; char szWkBuf[128], szCharBuf[BYTES_PER_LINE + 1]; for (unsigned int iIndex = 0; iIndex < nLen; ) { //000001: 12 34 56 78 AB CD EF 12 34 56 78 12 12 12 12 12 ............... sprintf(szWkBuf, " %0*d: ", SEQ_LEN, iSeq++); strBin = szWkBuf; memset(szCharBuf, 0, sizeof(szCharBuf)); for (unsigned int i = 0; i < BYTES_PER_LINE && iIndex < nLen; ++i) { sprintf(szWkBuf, "%02X ", pbyData[iIndex]); strBin += szWkBuf; sprintf(szCharBuf + strlen(szCharBuf), "%c", pbyData[iIndex] < 0x20 ? '.' : pbyData[iIndex]); ++iIndex; } if (iIndex % 16) { strBin += CString(' ', 3 * (16 - iIndex % 16)); } str.Format("%s; %s\r\n", strBin, szCharBuf); iLen = str.GetLength(); unBytesWritten = 0; WriteFile(hLog, str, iLen, &unBytesWritten, NULL); } str = " ----------------------------------------------------------------------------\r\n\r\n"; iLen = str.GetLength(); WriteFile(hLog, str, iLen, &unBytesWritten, NULL); if (INVALID_HANDLE_VALUE != hLog) { CloseHandle(hLog); } } /** 采用va_list形式的可变参数打印 @param nType 纪录类型 - TRACER_OPE_PROGRESS - TRACER_OPE_ERROR - TRACER_OPE_EXCEPTION - TRACER_OPE_MESSAGE @param pszFormat 打印格式 @param pArgList 可变参数列表指针 */ ///@endcond //@cond ENG /** Use va_list to Log information @param nType Information type - TRACER_OPE_PROGRESS - TRACER_OPE_ERROR - TRACER_OPE_EXCEPTION - TRACER_OPE_MESSAGE @param pszFormat Format string @param pArgList arguments */ ///@endcond void CCLogFile::PrintV(TRACER_TYPE nType, LPCTSTR pszFormat, va_list pArgList) { CString strFormat; switch (nType) { case TRACER_OPE_PROGRESS: strFormat = TRACER_OPE_PROGRESS_STR; break; case TRACER_OPE_ERROR: strFormat = TRACER_OPE_ERROR_STR; break; case TRACER_OPE_EXCEPTION: strFormat = TRACER_OPE_EXCEPTION_STR; break; case TRACER_OPE_MESSAGE: strFormat = TRACER_OPE_MESSAGE_STR; break; default: strFormat = ("$$ UNKONW: "); } strFormat.Append(pszFormat); PrintV(strFormat, pArgList); } //@cond CHS /** 采用va_list形式的可变参数打印 @param pszFormat 打印格式 @param pArgList 可变参数列表指针 */ ///@endcond //@cond ENG /** Use va_list to Log information @param pszFormat Format string @param pArgList arguments */ ///@endcond void CCLogFile::PrintV(LPCTSTR pszFormat, va_list pArgList) { CString str; str.FormatV(pszFormat, pArgList); str.Append(("\r\n")); //TRACE( str ); LogFile(str); } /** 生成文件 @param szData 数据 */ ///@endcond ///@cond ENG ///Log file ///@param szData Data need log to file ///@endcond void CCLogFile::LogFile(LPCTSTR szData) { SYSTEMTIME __sTime; ::GetLocalTime(&__sTime); /* CString str; str.Format(L"%s %04d%02d%02d%02d:%02d:%02d.%03d.log", m_szFile, __sTime.wYear, __sTime.wMonth, __sTime.wDay, __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds); */ CString str; str.Format("%s", m_szFile); CSingleLock lock(&this->m_csLog, TRUE); HANDLE hLog = this->CreateLogFile(str); if (INVALID_HANDLE_VALUE == hLog) { return; } str.Format("%02d:%02d:%02d.%03d | ", __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds); // str = ""; DWORD iLen = str.GetLength(); DWORD unBytesWritten = 0; WriteFile(hLog, str, iLen, &unBytesWritten, NULL); iLen = (DWORD)_tcslen(szData) * sizeof(TCHAR); WriteFile(hLog, szData, iLen, &unBytesWritten, NULL); OutputDebugString(szData); if (INVALID_HANDLE_VALUE != hLog) { CloseHandle(hLog); } } /** 创建日志文件 /@param str 文件名 */ ///@endcond ///@cond ENG ///Create log file ///@param str File Name ///@endcond HANDLE CCLogFile::CreateLogFile(const CString& str) { HANDLE hLog = INVALID_HANDLE_VALUE; hLog = CreateFile(str, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hLog) { if (CheckFilePath(str)) { hLog = CreateFile(str, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } } if (INVALID_HANDLE_VALUE != hLog) { SetFilePointer(hLog, 0, NULL, FILE_END); } if (!this->m_bFileNameCommited) { this->m_bFileNameCommited = true; } return hLog; } bool CCLogFile::CheckFilePath(const CString& strPath) { if (strPath.IsEmpty()) { return false; } int iPos = strPath.ReverseFind('\\'); if (iPos < 0) { iPos = strPath.ReverseFind('/'); if (iPos < 0) { return false; } } CString cstrPath = strPath.Left(iPos); return TRUE; } void CUtilityTools::WaitingWithEventLoop(int iWaitTime) { /* if (a_bWithEventLoop) { auto* pApp = AfxGetApp(); if (pApp) { AMICS::UI::CAMICSAppBase* pBaseApp = dynamic_cast(pApp); if (pBaseApp) { pBaseApp->WaitingWithEventLoop(a_nMilliseconds); return; } } }*/ //LogTrace(_T("Waiting %d milliseconds ..."), a_nMilliseconds); #pragma warning(disable: 28159) DWORD nStart = GetTickCount(); DWORD nEnd = nStart; do { nEnd = GetTickCount(); } while (nEnd >= nStart && nEnd <= (nStart + iWaitTime + 1)); #pragma warning(default: 28159) }