📄 stlogfile.h
字号:
}
::LeaveCriticalSection(&m_crit);
}
protected:
CSTLogFile()
: m_bIsStarted(FALSE), nLastCounter(0)
{
::InitializeCriticalSection(&m_crit);
m_dwTLSIndex = TlsAlloc ();
#ifdef STLOG_USE_PERFORMANCE_COUNTER
::QueryPerformanceFrequency(&m_nPerfFreq);
::QueryPerformanceCounter(&m_nStartTime);
#endif
}
public:
virtual ~CSTLogFile()
{
if (m_bIsStarted)
Stop();
::DeleteCriticalSection(&m_crit);
TlsFree(m_dwTLSIndex);
}
private:
HANDLE m_hFile;
CRITICAL_SECTION m_crit;
BOOL m_bIsStarted;
DWORD m_dwTLSIndex;
#ifdef STLOG_USE_PERFORMANCE_COUNTER
LARGE_INTEGER m_nPerfFreq;
LARGE_INTEGER m_nStartTime;
#endif
BOOL GetTimeString(LPSTR szString, int nStringSize)
{
SYSTEMTIME st;
GetLocalTime(&st);
#ifdef STLOG_USE_PERFORMANCE_COUNTER
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
///*--------------------------原代码----------------------------
//return (0 < _snprintf(szString, nStringSize, "%02u:%02u:%02u(%I64d)", st.wHour, st.wMinute, st.wSecond, counter.QuadPart));
///*------------------------------------------------------------
///*-------------------------修改后代码-------------------------
return (0 < _snprintf(szString, nStringSize, "%02u:%02u:%02u(%08ums)", st.wHour, st.wMinute, st.wSecond, counter.QuadPart*1000/m_nPerfFreq.QuadPart));
///*------------------------------------------------------------
#else
return (0 < _snprintf(szString, nStringSize, "%02u:%02u:%02u:%03u", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds));
#endif
}
public:
inline DWORD GetIndent()
{
return (DWORD)TlsGetValue(m_dwTLSIndex);
}
inline void SetIndent(DWORD dwIndent)
{
TlsSetValue(m_dwTLSIndex, (LPVOID) dwIndent);
}
inline void IncrIndent()
{
DWORD dwIndent = (DWORD)TlsGetValue(m_dwTLSIndex);
dwIndent++;
TlsSetValue(m_dwTLSIndex, (LPVOID) dwIndent);
}
inline void DecrIndent()
{
DWORD dwIndent = (DWORD)TlsGetValue(m_dwTLSIndex);
dwIndent--;
TlsSetValue(m_dwTLSIndex, (LPVOID) dwIndent);
}
private:
void GetLogFileName(LPTSTR szFileName) {
TCHAR wszExecutableFilePath[MAX_PATH];
::GetModuleFileName(NULL, wszExecutableFilePath, MAX_PATH);
#ifdef STLOG_CREATE_FILE_IN_THE_SAME_DIRECTORY
TCHAR *wszExecutableFileName = wszExecutableFilePath;
#else
TCHAR *wszExecutableFileName = ::_tcsrchr(wszExecutableFilePath, _T('\\'));
#endif
TCHAR *wszLastDot = ::_tcsrchr(wszExecutableFileName, _T('.'));
#ifdef STLOG_CREATE_NEW
BOOL bFound = FALSE;
int nFreeNumber = 0;
TCHAR wszTemp[MAX_PATH];
while (!bFound) {
_stprintf(wszTemp, _T("_log%02d.txt"), nFreeNumber);
::_tcscpy(wszLastDot, wszTemp);
if (0xFFFFFFFF == ::GetFileAttributes(wszExecutableFileName))
{
bFound = TRUE;
} else {
nFreeNumber++;
}
}
#else
::_tcscpy(wszLastDot, _T("_log.txt"));
#endif
::_tcscpy(szFileName, wszExecutableFileName);
}
public:
class Counter{
public:
Counter(char *szFile, int nLine) : m_nCounter(0), m_szFile(szFile), m_nLine(nLine)
{
m_nCounterIndex = ___g_nCounterIndex___++;
::InitializeCriticalSection(&m_crit);
CSTLogFile::GetLogFile()->Write("***Counter %d at %s,%d initialized", m_nCounterIndex, szFile, nLine);
m_TotalTime.QuadPart = 0;
///*------------增加如下代码,取频率----------------------
#ifdef STLOG_USE_PERFORMANCE_COUNTER
::QueryPerformanceFrequency(&m_nPerfFreq);
#endif
///*------------增加如下代码,取频率----------------------
}
~Counter()
{
///*--------------------------原代码----------------------------
// CSTLogFile::GetLogFile()->Write("Counter %d statistics\r\n\tCounts: %d,\r\n\tMinTime: %I64d ms,\r\n\tMaxTime: %I64d ms,\r\n\tTotalTime: %I64d ms,\r\n\tAverageTime: %I64d ms",
// m_nCounterIndex, m_nCounter, m_MinTime.QuadPart, m_MaxTime.QuadPart, m_TotalTime.QuadPart, m_TotalTime.QuadPart / m_nCounter);
///*------------------------------------------------------------
///*-------------------------修改后代码-------------------------
unsigned int m_iMinTime=(unsigned int)(m_MinTime.QuadPart*1000/m_nPerfFreq.QuadPart);
unsigned int m_iMaxTime=(unsigned int)(m_MaxTime.QuadPart*1000/m_nPerfFreq.QuadPart);
unsigned int m_iTotalTime=(unsigned int)(m_TotalTime.QuadPart*1000/m_nPerfFreq.QuadPart);
unsigned int m_iAverageTime=(unsigned int)(m_TotalTime.QuadPart / m_nCounter*1000/m_nPerfFreq.QuadPart);
CSTLogFile::GetLogFile()->Write("Counter %d statistics\r\n\tCounts: %d,\r\n\tMinTime: %08u ms,\r\n\tMaxTime: %08u ms,\r\n\tTotalTime: %08u ms,\r\n\tAverageTime: %08u ms",
m_nCounterIndex, m_nCounter, m_iMinTime, m_iMaxTime, m_iTotalTime, m_iAverageTime);
///*------------------------------------------------------------
::DeleteCriticalSection(&m_crit);
}
inline void StartSection()
{
::EnterCriticalSection(&m_crit);
m_nCounter++;
CSTLogFile::GetLogFile()->Write("Counter %d started", m_nCounterIndex);
::QueryPerformanceCounter(&m_StartTime);
m_LastCheckPoint.QuadPart = m_StartTime.QuadPart;
::LeaveCriticalSection(&m_crit);
}
inline void StopSection()
{
::EnterCriticalSection(&m_crit);
LARGE_INTEGER liCurrentTime;
::QueryPerformanceCounter(&liCurrentTime);
CSTLogFile::GetLogFile()->Write("Counter %d stopped %I64dms from start, %I64dms from last checkpoint", m_nCounterIndex, liCurrentTime.QuadPart - m_StartTime.QuadPart, liCurrentTime.QuadPart - m_LastCheckPoint.QuadPart);
liCurrentTime.QuadPart -= m_StartTime.QuadPart;
if (m_nCounter == 1 || m_MinTime.QuadPart > liCurrentTime.QuadPart) m_MinTime.QuadPart = liCurrentTime.QuadPart;
if (m_nCounter == 1 || m_MaxTime.QuadPart < liCurrentTime.QuadPart) m_MaxTime.QuadPart = liCurrentTime.QuadPart;
m_TotalTime.QuadPart += liCurrentTime.QuadPart;
::LeaveCriticalSection(&m_crit);
}
inline void CheckPoint(int nLine)
{
::EnterCriticalSection(&m_crit);
LARGE_INTEGER liCheckPoint; ::QueryPerformanceCounter(&liCheckPoint);
CSTLogFile::GetLogFile()->Write("Counter %d check point at line %d: %I64d ms from start, %I64dms from last checkpoint", m_nCounterIndex, nLine, liCheckPoint.QuadPart - m_StartTime.QuadPart, liCheckPoint.QuadPart - m_LastCheckPoint.QuadPart);
m_LastCheckPoint.QuadPart = liCheckPoint.QuadPart;
::LeaveCriticalSection(&m_crit);
}
inline LARGE_INTEGER GetTimeFromStart()
{
LARGE_INTEGER liCurrentTime;
::QueryPerformanceCounter(&liCurrentTime);
liCurrentTime.QuadPart -= m_StartTime.QuadPart;
return liCurrentTime;
}
private:
LARGE_INTEGER m_StartTime;
LARGE_INTEGER m_MaxTime;
LARGE_INTEGER m_MinTime;
LARGE_INTEGER m_TotalTime;
LARGE_INTEGER m_LastCheckPoint;
int m_nCounter;
CRITICAL_SECTION m_crit;
friend class CounterAux;
char *m_szFile;
int m_nLine;
int m_nCounterIndex ;
///*----增加如下代码,处理器频率
#ifdef STLOG_USE_PERFORMANCE_COUNTER
LARGE_INTEGER m_nPerfFreq;
#endif
};
struct CounterAux
{
CounterAux(Counter *pCounter) : m_pCounter(pCounter) { if (pCounter) pCounter->StartSection();}
~CounterAux() { if (m_pCounter) m_pCounter->StopSection();}
Counter *m_pCounter;
};
Counter *m_counters[STLOG_MAXCOUNTERS];
int nLastCounter;
static Counter *GetStaticCounter(char *szFile, int nLine)
{
CSTLogFile* pLogFile = GetLogFile();
if (pLogFile->nLastCounter == STLOG_MAXCOUNTERS)
{
pLogFile->Write("*****Max counters (%d) reached, the counter at %s, %d will not be created", STLOG_MAXCOUNTERS, szFile, nLine);
return 0;
}
Counter *p = new Counter(szFile, nLine);
pLogFile->m_counters[pLogFile->nLastCounter++] = p;
return p;
}
void DeleteStaticCounters()
{
while (nLastCounter)
{
delete m_counters[--nLastCounter];
}
}
struct Marker
{
Marker(LPCSTR szEntry)
{
m_bWide = FALSE;
m_szEntry = szEntry;
CSTLogFile::GetLogFile()->Write(">>[%s]", m_szEntry);
if (CSTLogFile::GetLogFile()->GetIndent() < STLOG_MAXINDENT)
CSTLogFile::GetLogFile()->IncrIndent();
}
Marker(LPCWSTR szEntry)
{
m_bWide = TRUE;
m_szEntry = (LPCSTR) szEntry;
CSTLogFile::GetLogFile()->Write(L">>[%s]", m_szEntry);
if (CSTLogFile::GetLogFile()->GetIndent() < STLOG_MAXINDENT)
CSTLogFile::GetLogFile()->IncrIndent();
}
~Marker()
{
if (CSTLogFile::GetLogFile()->GetIndent() > 0)
CSTLogFile::GetLogFile()->DecrIndent();
if (m_bWide)
CSTLogFile::GetLogFile()->Write(_T("<<[%s]"), (LPCWSTR)m_szEntry);
else
CSTLogFile::GetLogFile()->Write(_T("<<[%s]"), m_szEntry);
}
private:
LPCSTR m_szEntry;
BOOL m_bWide;
};
};
#endif
#ifdef STLOG_DEBUG
extern CSTLogFile logfile;
#ifdef STLOG_PRINT_COMPILE_INFO
#define STLOG_EXPAND_INFO(file, line) \
CURRENT_FILE = file; CURRENT_LINE=line;
#else
inline void _______DoNothing0() {};
#define STLOG_EXPAND_INFO(file, line) \
1 ? void(0) : _______DoNothing0();
#endif
#define STLOG_WRITE \
STLOG_EXPAND_INFO(__FILE__, __LINE__)\
CSTLogFile::GetLogFile()->Write
#define STLOG_WRITE_DATA \
STLOG_EXPAND_INFO(__FILE__, __LINE__)\
CSTLogFile::GetLogFile()->WriteData
#define STLOG_WRITE_GUID \
STLOG_EXPAND_INFO(__FILE__, __LINE__) \
CSTLogFile::GetLogFile()->WriteGUID
#define STLOG_WRITE_CLSID\
STLOG_EXPAND_INFO(__FILE__, __LINE__) \
CSTLogFile::GetLogFile()->WriteCLSID
#define STLOG_WRITE_IID\
STLOG_EXPAND_INFO(__FILE__, __LINE__) \
CSTLogFile::GetLogFile()->WriteIID
#define STLOG_PROFILE_BLOCK \
STLOG_EXPAND_INFO(__FILE__, __LINE__)\
static CSTLogFile::Counter *___pCounter___ = CSTLogFile::GetStaticCounter( __FILE__, __LINE__); \
CSTLogFile::CounterAux __counter_aux__(___pCounter___);
#define STLOG_PROFILE_FUNCTION(function_name) \
STLOG_EXPAND_INFO(__FILE__, __LINE__)\
{ CSTLogFile *pLog = CSTLogFile::GetLogFile(); \
pLog->Write(_T("Estimating call to function %s"), _T(#function_name)); \
static CSTLogFile::Counter *___pCounter___ = CSTLogFile::GetStaticCounter( __FILE__, __LINE__); \
CSTLogFile::CounterAux __counter_aux__(___pCounter___); \
((void)(function_name)); \
pLog->Write(_T("Function %s finished in %I64d ms"), _T(#function_name), ___pCounter___->GetTimeFromStart()); \
}
#define STLOG_PROFILE_CHECKPOINT \
if (___pCounter___) ___pCounter___->CheckPoint(__LINE__);
#define STLOG_MARKER \
STLOG_EXPAND_INFO(__FILE__, __LINE__)\
CSTLogFile::Marker ____marker____
#define STLOG_LASTERROR \
STLOG_EXPAND_INFO(__FILE__, __LINE__)\
CSTLogFile::GetLogFile()->WriteLastError();
#ifdef STLOG_USE_FOR_TRACE
#ifdef TRACE
#undef TRACE
#undef TRACE0
#undef TRACE1
#undef TRACE2
#undef TRACE3
#endif
#define TRACE STLOG_WRITE
#define TRACE0 STLOG_WRITE
#define TRACE1 STLOG_WRITE
#define TRACE2 STLOG_WRITE
#define TRACE3 STLOG_WRITE
#endif
#else
inline void _______DoNothing( ...) {};
#define STLOG_WRITE 1? void(0) : _______DoNothing
#define STLOG_WRITE_DATA 1? void(0) : _______DoNothing
#define STLOG_PROFILE_FUNCTION(function_name) ((void)(function_name));
#define STLOG_PROFILE_CHECKPOINT ;
#define STLOG_PROFILE_BLOCK ;
#define STLOG_MARKER 1? void(0) : _______DoNothing
#define STLOG_LASTERROR ;
#define STLOG_WRITE_GUID 1? void(0) : _______DoNothing
#define STLOG_WRITE_CLSID 1? void(0) : _______DoNothing
#define STLOG_WRITE_IID 1? void(0) : _______DoNothing
#endif
//For backward compatibility
#define WRITE_LOG STLOG_WRITE
//Some like it quick
#define STLOG STLOG_WRITE
#endif // ___LOGFILE_H__INCLUDED___
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -