?? stlogfile.h
字號:
::SetFilePointer(m_hFile, 0, 0, FILE_END);
m_bIsStarted = TRUE;
TCHAR szExecutable[MAX_PATH];
GetModuleFileName(NULL, szExecutable, MAX_PATH);
DWORD dwProcID = GetCurrentProcessId();
SYSTEMTIME st;
GetLocalTime(&st);
Write(TEXT("============================================="));
Write(TEXT("Log is started on %02u.%02u.%04u, at %02u:%02u:%02u:%03u, executable: %s (ProcID: 0x%08x), compile time : %s %s"), st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, szExecutable, dwProcID, TEXT(__DATE__) , TEXT(__TIME__));
}
::LeaveCriticalSection(&m_crit);
}
void Stop()
{
::EnterCriticalSection(&m_crit);
DeleteStaticCounters();
if (m_bIsStarted) {
Write(TEXT("Log finished"));
// ::CloseHandle(m_hFile);
m_bIsStarted = FALSE;
}
::LeaveCriticalSection(&m_crit);
}
protected:
CSTLogFile()
: m_bIsStarted(FALSE), nLastCounter(0)
{
::InitializeCriticalSection(&m_crit);
#ifdef STLOG_USE_PERFORMANCE_COUNTER
::QueryPerformanceFrequency(&m_nPerfFreq);
::QueryPerformanceCounter(&m_nStartTime);
#endif
}
public:
virtual ~CSTLogFile()
{
if (m_bIsStarted)
Stop();
::DeleteCriticalSection(&m_crit);
}
private:
HANDLE m_hFile;
CRITICAL_SECTION m_crit;
BOOL m_bIsStarted;
#ifdef STLOG_USE_PERFORMANCE_COUNTER
LARGE_INTEGER m_nPerfFreq;
LARGE_INTEGER m_nStartTime;
#endif
BOOL GetTimeString(LPSTR szString, int nStringSize)
{
SYSTEMTIME st;
GetLocalTime(&st);
return (0 < _snprintf(szString, nStringSize, "%02u:%02u:%02u:%03u", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds));
}
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;
WCHAR wszTemp[10];
while (!bFound) {
swprintf(wszTemp, _T("%02d_log.log"), 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;
}
~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);
::DeleteCriticalSection(&m_crit);
}
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);
}
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);
}
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, GetTimeFromStart(), liCheckPoint.QuadPart - m_LastCheckPoint.QuadPart);
m_LastCheckPoint.QuadPart = liCheckPoint.QuadPart;
::LeaveCriticalSection(&m_crit);
}
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 ;
};
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);
}
Marker(LPCWSTR szEntry)
{
m_bWide = TRUE;
m_szEntry = (LPCSTR) szEntry;
CSTLogFile::GetLogFile()->Write(L">>[%s]", m_szEntry);
}
~Marker()
{
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(LPCTSTR, ...) {};
#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 + -