/******************************************************************************
* RunnigLog.h - easy log
*
* Copyright (c) 2007 xxxx (Hangzhou) Software Corp. Ltd.
*
* DESCRIPTION:
* easy log file
* Modification history:
*
* 07 Jan 2009, written by Yanqingwu
* Note: 1.you can use easy log by a macro LOG_LOG(0,0,5)
* 2.if you want specify log path and file use LOG_LOG("C://", "name.log", 5)
******************************************************************************/
/******************************************************************************
* include file here:
* eg. #include <xxx.h>
******************************************************************************/
/******************************************************************************
* define MACRO here:
* eg. DEFINE XXX ()
******************************************************************************/
/******************************************************************************
* define global variable here:
* eg. tpye g_xxx;
******************************************************************************/
/******************************************************************************
* define function/class/.etc here:
* eg. void xxx();
******************************************************************************/
#define _LOG_ON 1
#define LOG_ERROR -1
#define LOG_OK 0
#define LOG_MAX_NODES 50
#define LOG_MAX_MSG_LEN 260
#define LOG_LEVEL_NO 0
#define LOG_LEVEL_INFO 1
#define LOG_LEVEL_WARNING 2
#define LOG_LEVEL_DEBUG 3
#define LOG_LEVEL_ERROR 4
#define LOG_LEVEL_ALL 5
#define THREAD_EXIT_WAIT_TIME 1000
#if _LOG_ON
#define LOG_LOG(path, name, level) do {/
CEasyLog log;/
log.LogInst()->SetPath(path);/
log.LogInst()->SetName(name);/
log.LogInst()->SetLogLevel(level);/
log.LogInst()->DoLog();/
} while (0);
#define INFO_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_INFO, szMsg);/
}while(0);
#define WARNING_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_WARNING, szMsg);/
}while(0);
#define DEBUG_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_DEBUG, szMsg);/
}while(0);
#define ERROR_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_ERROR, szMsg);/
}while(0);
#else
#define LOG_LOG(path, name, level)
#define INFO_LOG(x)
#define WARNING_LOG(x)
#define DEBUG_LOG(x)
#define ERROR_LOG(x)
#endif
typedef struct LogMsgNode
{
unsigned short iNum;
struct LogMsgNode *pNext;
} LOGMSGNODE;
typedef LOGMSGNODE* LOGMSGLIST;
class CLogCriticalSection
{
public:
CLogCriticalSection()
{
::InitializeCriticalSection(&m_cs);
}
~CLogCriticalSection()
{
::DeleteCriticalSection(&m_cs);
}
bool Lock()
{
::EnterCriticalSection(&m_cs);
return true;
}
bool UnLock()
{
::LeaveCriticalSection(&m_cs);
return true;
}
protected:
CRITICAL_SECTION m_cs;
};
class CEasyLogLock
{
public:
CEasyLogLock(CLogCriticalSection &lcs)
:m_lcs(lcs)
{
m_lcs.Lock();
}
~CEasyLogLock()
{
m_lcs.UnLock();
}
protected:
CLogCriticalSection &m_lcs;
};
class CRunnigLog
{
public:
void ReleaseLog();
int SetLogLevel(unsigned short sLevel);
unsigned short GetLogLevel();
int SetPath(char *szPath);
char* GetPath();
int SetName(char *szName);
char* GetName();
bool DoLog();
void PutMsg(unsigned short slevel, char *szMsg);
void SerialMsg();
char *GetMsg();
public:
static CRunnigLog* Instance();
protected:
CRunnigLog();
CRunnigLog(const CRunnigLog &lg);
CRunnigLog &operator=(const CRunnigLog &other);
static int ThreadEntry(void **ppv)
{
(reinterpret_cast <CRunnigLog *> (ppv))->ThreadProc();
return 1;
}
void ThreadProc();
protected:
static CRunnigLog* _instance;
CLogCriticalSection m_lcs;
char m_szLogPath[MAX_PATH];
char m_szLogName[MAX_PATH];
LONG m_lLostMsgCount;
LONG m_lRef;
unsigned short m_sLevel;
HANDLE m_hNewMsg;
bool m_bRunningThread;
HANDLE m_hThread;
FILE* m_pStream;
char m_ppMsgBuffer[LOG_MAX_NODES][LOG_MAX_MSG_LEN];
int m_nMsgCount;
int m_nMsgRead;
int m_nMsgWrite;
};
class CEasyLog
{
public:
CEasyLog()
{
m_log = CRunnigLog::Instance();
}
~CEasyLog()
{
m_log->ReleaseLog();
}
CRunnigLog *LogInst()
{
return m_log;
}
protected:
CRunnigLog* m_log;
};
//
/******************************************************************************
* RunnigLog.cpp - running log module
*
* Copyright (c) 2007 xxxx (Hangzhou) Software Corp. Ltd.
*
* DESCRIPTION:
* easy running log module
* Modification history:
*
* 07 Jan 2009, written by Yanqingwu
* Note: 1.
* 2.
******************************************************************************/
/******************************************************************************
* include file here:
* eg. #include <xxx.h>
******************************************************************************/
/******************************************************************************
* define MACRO here:
* eg. DEFINE XXX ()
******************************************************************************/
/******************************************************************************
* define global variable here:
* eg. tpye g_xxx;
******************************************************************************/
/******************************************************************************
* define function/class/.etc here:
* eg. void xxx();
******************************************************************************/
#include "stdafx.h"
#include "RunnigLog.h"
#include "stdio.h"
#if _LOG_ON
CEasyLog g_EasyLog;
#endif
CRunnigLog* CRunnigLog::_instance = NULL;
/******************************************************************************
* Function: CRunnigLog.Instance
* Purpose: -
* singleton instance
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
CRunnigLog* CRunnigLog::Instance()
{
if (NULL == _instance)
{
_instance = new CRunnigLog;
}
::InterlockedIncrement(&_instance->m_lRef);
return _instance;
}
/******************************************************************************
* Function: CRunnigLog.CRunnigLog
* Purpose: -
* construct running log class
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
CRunnigLog::CRunnigLog()
{
m_sLevel = LOG_LEVEL_NO;
m_lRef = 0;
m_pStream = NULL;
m_hNewMsg = CreateEvent(NULL, FALSE, FALSE, NULL);
memset(m_szLogPath, 0, MAX_PATH);
memset(m_szLogName, 0, MAX_PATH);
strcpy(m_szLogPath, "C://");
SYSTEMTIME t;
::GetLocalTime(&t);
sprintf(m_szLogName,"%04d-%02d-%02d-%02d-%02d-%02d-%04d.txt",t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond,t.wMilliseconds);
m_lLostMsgCount = 0;
m_nMsgCount = 0;
m_nMsgRead = 0;
m_nMsgWrite = 0;
for (int j = 0; j < LOG_MAX_NODES; j++)
{
memset(m_ppMsgBuffer[j], 0, LOG_MAX_MSG_LEN);
}
m_pStream = NULL;
m_bRunningThread = false;
m_hThread = NULL;
}
/******************************************************************************
* Function: CRunnigLog.ReleaseLog
* Purpose: -
* realse running log
* it olny delete log class while reference count less than 0
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::ReleaseLog()
{
::InterlockedDecrement(&m_lRef);
if (m_lRef <= 0)
{
m_bRunningThread = false;
if (m_hThread)
{
SetEvent(m_hNewMsg);
WaitForSingleObject(m_hThread, THREAD_EXIT_WAIT_TIME);
CloseHandle(m_hThread);
}
SerialMsg();
if (m_pStream)
{
fputs("====end log======/r/n", m_pStream);
char szTmp[MAX_PATH] = {0};
sprintf(szTmp, "lost msg cout: %d/r/n", m_lLostMsgCount);
fputs(szTmp, m_pStream);
fclose(m_pStream);
}
delete _instance;
_instance = NULL;
}
}
/******************************************************************************
* Function: CRunnigLog.SetLogLevel
* Purpose: -
* set log level
* Parameter:
* unsigned short sLevel:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
int CRunnigLog::SetLogLevel(unsigned short sLevel)
{
if (NULL == _instance)
{
return LOG_ERROR;
}
if (sLevel < LOG_LEVEL_NO
|| sLevel > LOG_LEVEL_ALL)
{
return LOG_ERROR;
}
m_sLevel = sLevel;
return LOG_OK;
}
/******************************************************************************
* Function: CRunnigLog.GetLogLevel
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
unsigned short CRunnigLog::GetLogLevel()
{
if (NULL == _instance)
{
return LOG_ERROR;
}
return m_sLevel;
}
/******************************************************************************
* Function: CRunnigLog.SetPath
* Purpose: -
*
* Parameter:
* char *szPath:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
int CRunnigLog::SetPath(char *szPath)
{
if (!szPath)
{
return LOG_ERROR;
}
if (strlen(szPath) < MAX_PATH)
{
strcpy(m_szLogPath, szPath);
return LOG_OK;
}
return LOG_ERROR;
}
/******************************************************************************
* Function: CRunnigLog.GetPath
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
char *CRunnigLog::GetPath()
{
return m_szLogPath;
}
/******************************************************************************
* Function: CRunnigLog.SetName
* Purpose: -
*
* Parameter:
* char *szName:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
int CRunnigLog::SetName(char *szName)
{
if (!szName)
{
return LOG_ERROR;
}
if (strlen(szName) < MAX_PATH)
{
strcpy(m_szLogName, szName);
return LOG_OK;
}
return LOG_ERROR;
}
/******************************************************************************
* Function: CRunnigLog.GetName
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
char *CRunnigLog::GetName()
{
return m_szLogName;
}
/******************************************************************************
* Function: CRunnigLog.DoLog
* Purpose: -
* running log thread
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
bool CRunnigLog::DoLog()
{
char szfullpath[MAX_PATH] = {0};
strcpy(szfullpath, m_szLogPath);
if ('//' != szfullpath[strlen(szfullpath)])
{
strcat(szfullpath, "//");
}
strcat(szfullpath, m_szLogName);
m_pStream = fopen(szfullpath, "a+t");
if (m_pStream)
{
fputs("====begin log======/r/n", m_pStream);
}
m_bRunningThread = true;
DWORD dwId;
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadEntry, this, 0, &dwId);
if (m_hThread)
{
return true;
}
else
{
fputs("failed to create log thread!/r/n", m_pStream);
}
return false;
}
/******************************************************************************
* Function: CRunnigLog.PutMsg
* Purpose: -
* buffer a log message
* Parameter:
* unsigned short slevel:
* char *szMsg:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::PutMsg(unsigned short slevel, char *szMsg)
{
if (NULL == szMsg || 0 >= strlen(szMsg))
{
return;
}
if (slevel <= m_sLevel)
{
CEasyLogLock lock(m_lcs);
if (m_nMsgCount >= LOG_MAX_NODES)
{
int nRead;
int nWritecount = 0;
while (m_nMsgCount > 0)
{
nRead = m_nMsgRead;
m_nMsgRead = ++m_nMsgRead % LOG_MAX_NODES;
m_nMsgCount--;
//write to file
if (m_pStream)
{
fputs(m_ppMsgBuffer[nRead], m_pStream);
memset(m_ppMsgBuffer[nRead], 0, LOG_MAX_MSG_LEN);
nWritecount++;
}
}
if (nWritecount)
{
fflush(m_pStream);
}
}
if (m_nMsgCount < LOG_MAX_NODES)
{
int nWrite = m_nMsgWrite;
m_nMsgWrite = ++m_nMsgWrite % LOG_MAX_NODES;
strncpy(m_ppMsgBuffer[nWrite], szMsg, LOG_MAX_MSG_LEN - 1);
m_nMsgCount++;
SetEvent(m_hNewMsg);
}
else
{
m_lLostMsgCount++;
}
}
}
/******************************************************************************
* Function: CRunnigLog.SerialMsg
* Purpose: -
* out put log messages in buffer
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::SerialMsg()
{
int nRead;
int nWritecount = 0;
while (1)
{
CEasyLogLock lock(m_lcs);
if (m_nMsgCount <= 0)
{
break;
}
nRead = m_nMsgRead;
m_nMsgRead = ++m_nMsgRead % LOG_MAX_NODES;
m_nMsgCount--;
//write to file
if (m_pStream)
{
fputs(m_ppMsgBuffer[nRead], m_pStream);
memset(m_ppMsgBuffer[nRead], 0, LOG_MAX_MSG_LEN);
nWritecount++;
}
}
if (nWritecount)
{
fflush(m_pStream);
}
}
/******************************************************************************
* Function: CRunnigLog.GetMsg
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
char *CRunnigLog::GetMsg()
{
CEasyLogLock lock(m_lcs);
if (m_nMsgCount > 0)
{
int nRead = m_nMsgRead;
m_nMsgRead = ++m_nMsgRead % LOG_MAX_NODES;
m_nMsgCount--;
return m_ppMsgBuffer[nRead];
}
return NULL;
}
/******************************************************************************
* Function: CRunnigLog.ThreadProc
* Purpose: -
* thread loop here
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::ThreadProc()
{
while (m_bRunningThread)
{
WaitForSingleObject(m_hNewMsg, INFINITE);
if (!m_bRunningThread)
{
break;
}
SerialMsg();
}
}
* RunnigLog.h - easy log
*
* Copyright (c) 2007 xxxx (Hangzhou) Software Corp. Ltd.
*
* DESCRIPTION:
* easy log file
* Modification history:
*
* 07 Jan 2009, written by Yanqingwu
* Note: 1.you can use easy log by a macro LOG_LOG(0,0,5)
* 2.if you want specify log path and file use LOG_LOG("C://", "name.log", 5)
******************************************************************************/
/******************************************************************************
* include file here:
* eg. #include <xxx.h>
******************************************************************************/
/******************************************************************************
* define MACRO here:
* eg. DEFINE XXX ()
******************************************************************************/
/******************************************************************************
* define global variable here:
* eg. tpye g_xxx;
******************************************************************************/
/******************************************************************************
* define function/class/.etc here:
* eg. void xxx();
******************************************************************************/
#define _LOG_ON 1
#define LOG_ERROR -1
#define LOG_OK 0
#define LOG_MAX_NODES 50
#define LOG_MAX_MSG_LEN 260
#define LOG_LEVEL_NO 0
#define LOG_LEVEL_INFO 1
#define LOG_LEVEL_WARNING 2
#define LOG_LEVEL_DEBUG 3
#define LOG_LEVEL_ERROR 4
#define LOG_LEVEL_ALL 5
#define THREAD_EXIT_WAIT_TIME 1000
#if _LOG_ON
#define LOG_LOG(path, name, level) do {/
CEasyLog log;/
log.LogInst()->SetPath(path);/
log.LogInst()->SetName(name);/
log.LogInst()->SetLogLevel(level);/
log.LogInst()->DoLog();/
} while (0);
#define INFO_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_INFO, szMsg);/
}while(0);
#define WARNING_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_WARNING, szMsg);/
}while(0);
#define DEBUG_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_DEBUG, szMsg);/
}while(0);
#define ERROR_LOG(x) do{/
CEasyLog log;/
char szMsg[MAX_PATH] = {0};/
sprintf(szMsg, "%s_%d:%s/r/n",__FILE__,__LINE__,x);/
log.LogInst()->PutMsg(LOG_LEVEL_ERROR, szMsg);/
}while(0);
#else
#define LOG_LOG(path, name, level)
#define INFO_LOG(x)
#define WARNING_LOG(x)
#define DEBUG_LOG(x)
#define ERROR_LOG(x)
#endif
typedef struct LogMsgNode
{
unsigned short iNum;
struct LogMsgNode *pNext;
} LOGMSGNODE;
typedef LOGMSGNODE* LOGMSGLIST;
class CLogCriticalSection
{
public:
CLogCriticalSection()
{
::InitializeCriticalSection(&m_cs);
}
~CLogCriticalSection()
{
::DeleteCriticalSection(&m_cs);
}
bool Lock()
{
::EnterCriticalSection(&m_cs);
return true;
}
bool UnLock()
{
::LeaveCriticalSection(&m_cs);
return true;
}
protected:
CRITICAL_SECTION m_cs;
};
class CEasyLogLock
{
public:
CEasyLogLock(CLogCriticalSection &lcs)
:m_lcs(lcs)
{
m_lcs.Lock();
}
~CEasyLogLock()
{
m_lcs.UnLock();
}
protected:
CLogCriticalSection &m_lcs;
};
class CRunnigLog
{
public:
void ReleaseLog();
int SetLogLevel(unsigned short sLevel);
unsigned short GetLogLevel();
int SetPath(char *szPath);
char* GetPath();
int SetName(char *szName);
char* GetName();
bool DoLog();
void PutMsg(unsigned short slevel, char *szMsg);
void SerialMsg();
char *GetMsg();
public:
static CRunnigLog* Instance();
protected:
CRunnigLog();
CRunnigLog(const CRunnigLog &lg);
CRunnigLog &operator=(const CRunnigLog &other);
static int ThreadEntry(void **ppv)
{
(reinterpret_cast <CRunnigLog *> (ppv))->ThreadProc();
return 1;
}
void ThreadProc();
protected:
static CRunnigLog* _instance;
CLogCriticalSection m_lcs;
char m_szLogPath[MAX_PATH];
char m_szLogName[MAX_PATH];
LONG m_lLostMsgCount;
LONG m_lRef;
unsigned short m_sLevel;
HANDLE m_hNewMsg;
bool m_bRunningThread;
HANDLE m_hThread;
FILE* m_pStream;
char m_ppMsgBuffer[LOG_MAX_NODES][LOG_MAX_MSG_LEN];
int m_nMsgCount;
int m_nMsgRead;
int m_nMsgWrite;
};
class CEasyLog
{
public:
CEasyLog()
{
m_log = CRunnigLog::Instance();
}
~CEasyLog()
{
m_log->ReleaseLog();
}
CRunnigLog *LogInst()
{
return m_log;
}
protected:
CRunnigLog* m_log;
};
//
/******************************************************************************
* RunnigLog.cpp - running log module
*
* Copyright (c) 2007 xxxx (Hangzhou) Software Corp. Ltd.
*
* DESCRIPTION:
* easy running log module
* Modification history:
*
* 07 Jan 2009, written by Yanqingwu
* Note: 1.
* 2.
******************************************************************************/
/******************************************************************************
* include file here:
* eg. #include <xxx.h>
******************************************************************************/
/******************************************************************************
* define MACRO here:
* eg. DEFINE XXX ()
******************************************************************************/
/******************************************************************************
* define global variable here:
* eg. tpye g_xxx;
******************************************************************************/
/******************************************************************************
* define function/class/.etc here:
* eg. void xxx();
******************************************************************************/
#include "stdafx.h"
#include "RunnigLog.h"
#include "stdio.h"
#if _LOG_ON
CEasyLog g_EasyLog;
#endif
CRunnigLog* CRunnigLog::_instance = NULL;
/******************************************************************************
* Function: CRunnigLog.Instance
* Purpose: -
* singleton instance
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
CRunnigLog* CRunnigLog::Instance()
{
if (NULL == _instance)
{
_instance = new CRunnigLog;
}
::InterlockedIncrement(&_instance->m_lRef);
return _instance;
}
/******************************************************************************
* Function: CRunnigLog.CRunnigLog
* Purpose: -
* construct running log class
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
CRunnigLog::CRunnigLog()
{
m_sLevel = LOG_LEVEL_NO;
m_lRef = 0;
m_pStream = NULL;
m_hNewMsg = CreateEvent(NULL, FALSE, FALSE, NULL);
memset(m_szLogPath, 0, MAX_PATH);
memset(m_szLogName, 0, MAX_PATH);
strcpy(m_szLogPath, "C://");
SYSTEMTIME t;
::GetLocalTime(&t);
sprintf(m_szLogName,"%04d-%02d-%02d-%02d-%02d-%02d-%04d.txt",t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond,t.wMilliseconds);
m_lLostMsgCount = 0;
m_nMsgCount = 0;
m_nMsgRead = 0;
m_nMsgWrite = 0;
for (int j = 0; j < LOG_MAX_NODES; j++)
{
memset(m_ppMsgBuffer[j], 0, LOG_MAX_MSG_LEN);
}
m_pStream = NULL;
m_bRunningThread = false;
m_hThread = NULL;
}
/******************************************************************************
* Function: CRunnigLog.ReleaseLog
* Purpose: -
* realse running log
* it olny delete log class while reference count less than 0
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::ReleaseLog()
{
::InterlockedDecrement(&m_lRef);
if (m_lRef <= 0)
{
m_bRunningThread = false;
if (m_hThread)
{
SetEvent(m_hNewMsg);
WaitForSingleObject(m_hThread, THREAD_EXIT_WAIT_TIME);
CloseHandle(m_hThread);
}
SerialMsg();
if (m_pStream)
{
fputs("====end log======/r/n", m_pStream);
char szTmp[MAX_PATH] = {0};
sprintf(szTmp, "lost msg cout: %d/r/n", m_lLostMsgCount);
fputs(szTmp, m_pStream);
fclose(m_pStream);
}
delete _instance;
_instance = NULL;
}
}
/******************************************************************************
* Function: CRunnigLog.SetLogLevel
* Purpose: -
* set log level
* Parameter:
* unsigned short sLevel:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
int CRunnigLog::SetLogLevel(unsigned short sLevel)
{
if (NULL == _instance)
{
return LOG_ERROR;
}
if (sLevel < LOG_LEVEL_NO
|| sLevel > LOG_LEVEL_ALL)
{
return LOG_ERROR;
}
m_sLevel = sLevel;
return LOG_OK;
}
/******************************************************************************
* Function: CRunnigLog.GetLogLevel
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
unsigned short CRunnigLog::GetLogLevel()
{
if (NULL == _instance)
{
return LOG_ERROR;
}
return m_sLevel;
}
/******************************************************************************
* Function: CRunnigLog.SetPath
* Purpose: -
*
* Parameter:
* char *szPath:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
int CRunnigLog::SetPath(char *szPath)
{
if (!szPath)
{
return LOG_ERROR;
}
if (strlen(szPath) < MAX_PATH)
{
strcpy(m_szLogPath, szPath);
return LOG_OK;
}
return LOG_ERROR;
}
/******************************************************************************
* Function: CRunnigLog.GetPath
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
char *CRunnigLog::GetPath()
{
return m_szLogPath;
}
/******************************************************************************
* Function: CRunnigLog.SetName
* Purpose: -
*
* Parameter:
* char *szName:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
int CRunnigLog::SetName(char *szName)
{
if (!szName)
{
return LOG_ERROR;
}
if (strlen(szName) < MAX_PATH)
{
strcpy(m_szLogName, szName);
return LOG_OK;
}
return LOG_ERROR;
}
/******************************************************************************
* Function: CRunnigLog.GetName
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
char *CRunnigLog::GetName()
{
return m_szLogName;
}
/******************************************************************************
* Function: CRunnigLog.DoLog
* Purpose: -
* running log thread
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
bool CRunnigLog::DoLog()
{
char szfullpath[MAX_PATH] = {0};
strcpy(szfullpath, m_szLogPath);
if ('//' != szfullpath[strlen(szfullpath)])
{
strcat(szfullpath, "//");
}
strcat(szfullpath, m_szLogName);
m_pStream = fopen(szfullpath, "a+t");
if (m_pStream)
{
fputs("====begin log======/r/n", m_pStream);
}
m_bRunningThread = true;
DWORD dwId;
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadEntry, this, 0, &dwId);
if (m_hThread)
{
return true;
}
else
{
fputs("failed to create log thread!/r/n", m_pStream);
}
return false;
}
/******************************************************************************
* Function: CRunnigLog.PutMsg
* Purpose: -
* buffer a log message
* Parameter:
* unsigned short slevel:
* char *szMsg:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::PutMsg(unsigned short slevel, char *szMsg)
{
if (NULL == szMsg || 0 >= strlen(szMsg))
{
return;
}
if (slevel <= m_sLevel)
{
CEasyLogLock lock(m_lcs);
if (m_nMsgCount >= LOG_MAX_NODES)
{
int nRead;
int nWritecount = 0;
while (m_nMsgCount > 0)
{
nRead = m_nMsgRead;
m_nMsgRead = ++m_nMsgRead % LOG_MAX_NODES;
m_nMsgCount--;
//write to file
if (m_pStream)
{
fputs(m_ppMsgBuffer[nRead], m_pStream);
memset(m_ppMsgBuffer[nRead], 0, LOG_MAX_MSG_LEN);
nWritecount++;
}
}
if (nWritecount)
{
fflush(m_pStream);
}
}
if (m_nMsgCount < LOG_MAX_NODES)
{
int nWrite = m_nMsgWrite;
m_nMsgWrite = ++m_nMsgWrite % LOG_MAX_NODES;
strncpy(m_ppMsgBuffer[nWrite], szMsg, LOG_MAX_MSG_LEN - 1);
m_nMsgCount++;
SetEvent(m_hNewMsg);
}
else
{
m_lLostMsgCount++;
}
}
}
/******************************************************************************
* Function: CRunnigLog.SerialMsg
* Purpose: -
* out put log messages in buffer
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::SerialMsg()
{
int nRead;
int nWritecount = 0;
while (1)
{
CEasyLogLock lock(m_lcs);
if (m_nMsgCount <= 0)
{
break;
}
nRead = m_nMsgRead;
m_nMsgRead = ++m_nMsgRead % LOG_MAX_NODES;
m_nMsgCount--;
//write to file
if (m_pStream)
{
fputs(m_ppMsgBuffer[nRead], m_pStream);
memset(m_ppMsgBuffer[nRead], 0, LOG_MAX_MSG_LEN);
nWritecount++;
}
}
if (nWritecount)
{
fflush(m_pStream);
}
}
/******************************************************************************
* Function: CRunnigLog.GetMsg
* Purpose: -
*
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
char *CRunnigLog::GetMsg()
{
CEasyLogLock lock(m_lcs);
if (m_nMsgCount > 0)
{
int nRead = m_nMsgRead;
m_nMsgRead = ++m_nMsgRead % LOG_MAX_NODES;
m_nMsgCount--;
return m_ppMsgBuffer[nRead];
}
return NULL;
}
/******************************************************************************
* Function: CRunnigLog.ThreadProc
* Purpose: -
* thread loop here
* Parameter:
* Returns:
*
* modification history:
*
* 07 Jan 2009, written by Yanqingwu
*
******************************************************************************/
void CRunnigLog::ThreadProc()
{
while (m_bRunningThread)
{
WaitForSingleObject(m_hNewMsg, INFINITE);
if (!m_bRunningThread)
{
break;
}
SerialMsg();
}
}