通用日志类
日志输出格式:类型 时间(毫秒级) 标题 内容
Log.h
#pragma once
#include "sync.h"
#include
extern char* strleft(char *dst,char *src, int n);
enum { CmdOK,CmdTrade,CmdLogin,CmdWarn,CmdErr,CmdAtt };
enum enumLog{ OutOrder, OutError, OutAccount };
class CLog
{
public:
CLog(void);
~CLog(void);
int OutLog(int logtype,char* strlogtitle,char* strlogcontent,...);
private:
bool CreateLogdir(char* szdir);
private:
CSync m_sync;
char m_szLogDir[MAX_PATH];
};
extern CLog ExLog;
sync.h
#pragma once
//+------------------------------------------------------------------+
//| Syncronization |
//+------------------------------------------------------------------+
class CSync
{
private:
CRITICAL_SECTION m_cs;
public:
CSync() { ZeroMemory(&m_cs,sizeof(m_cs)); InitializeCriticalSection(&m_cs); }
~CSync() { DeleteCriticalSection(&m_cs); }
//----
inline void Lock() { EnterCriticalSection(&m_cs); }
inline void Unlock() { LeaveCriticalSection(&m_cs); }
};
//+------------------------------------------------------------------+
Log.cpp
#include "StdAfx.h"
#include "Log.h"
#include
#include
CLog ExLog;
// char* strleft(char *dst,char *src, int n)
// {
// char *p = src;
// char *q = dst;
// int len = strlen(src);
// if(n>len) n = len;
// /*p += (len-n);*/ /*从右边第n个字符开始*/
// while(n--) *(q++) = *(p++);
// *(q++)='\0';
// return dst;
// }
CLog::CLog(void)
{
char szapipath[MAX_PATH];
memset(szapipath,0,MAX_PATH);
GetModuleFileNameA(NULL,szapipath,MAX_PATH);
char szdirpath[MAX_PATH];
memset(szdirpath,0,MAX_PATH);
strleft(szdirpath,szapipath,strlen(szapipath) - strlen("xxxx.exe"));
memset(m_szLogDir,0,MAX_PATH*sizeof(char));
sprintf_s(m_szLogDir,"%sorderlogs",szdirpath);
}
CLog::~CLog(void)
{
}
bool CLog::CreateLogdir(char* szdir)
{
bool bret = false;
if(_access(szdir,0) == 0) //如果目录已存在,直接返回
{
bret = true;
}
else
{
char sztemppath[MAX_PATH];
memset(sztemppath,0,MAX_PATH);
char szsavetemppath[MAX_PATH];
memset(szsavetemppath,0,MAX_PATH);
char *ptoken = strtok(szdir, "\\");
bret = true;
while(ptoken)
{
if(strlen(szsavetemppath) > 0)
{
sprintf_s(sztemppath,"%s\\%s",szsavetemppath,ptoken);
}
else
{
sprintf_s(sztemppath,"%s",ptoken);
}
memcpy_s(szsavetemppath,MAX_PATH,sztemppath,MAX_PATH);
if(_access(szsavetemppath,0) != 0)
{
//创建失败时还应删除已创建的上层目录,此次略
if(!CreateDirectoryA(szsavetemppath,NULL))
{
DWORD dw = GetLastError();
bret = false;
break;
}
}
ptoken = strtok(NULL, "\\");
}
}
return bret;
}
int CLog::OutLog(int logtype,char* strlogtitle,char* strlogcontent,...)
{
int nlen = strlen(strlogcontent) +1024;
char* writebuffer = new char[nlen];
memset(writebuffer,0,nlen);
va_list arg_ptr;
va_start(arg_ptr,strlogcontent);
_vsnprintf(writebuffer,nlen-1,strlogcontent,arg_ptr);
va_end(arg_ptr);
int ncontentlen = strlen(writebuffer);
int nret = 0;
m_sync.Lock();
if(CreateLogdir(m_szLogDir))
{
SYSTEMTIME wtm;
GetLocalTime(&wtm);
char buffer [80];
sprintf_s(buffer, 80, "%02d:%02d:%02d.%03d",wtm.wHour,wtm.wMinute,wtm.wSecond,wtm.wMilliseconds);
int nbufflen = ncontentlen + 100;
char* writebuff = new char[nbufflen];
memset(writebuff,0,nbufflen);
sprintf_s(writebuff,nbufflen,"%d\t%s\t%s\t%s\r\n",logtype,buffer,strlogtitle,writebuffer);
char szLogPath[MAX_PATH];
memset(szLogPath,0,MAX_PATH);
sprintf_s(szLogPath,MAX_PATH,"%s\\%04d%02d%02d.log",m_szLogDir,wtm.wYear,wtm.wMonth,wtm.wDay);
FILE* pfile = NULL;
if( 0 == fopen_s(&pfile,szLogPath,"a+"))
{
fwrite(writebuff,1,strlen(writebuff),pfile);
fclose(pfile);
}
else
{
nret = 2;
}
delete[] writebuff;
}
else
{
nret = 1;
}
m_sync.Unlock();
delete[] writebuffer;
return nret;
}
//Unicode
log.h
#pragma once
extern TCHAR* strleftLog(TCHAR *dst, TCHAR *src, int n);
enum EnErrLogTypes {
CmdOK, // OK
CmdTrade, // trades only
CmdLogin, // logins only
CmdWarn, // warnings
CmdErr, // errors
CmdAtt // attention, important errors
};
class CLog
{
public:
CLog(void);
~CLog(void);
int OutLog(int logtype, TCHAR* strlogtitle, TCHAR* strlogcontent, ...);
bool CreateLogdir(TCHAR* szdir);
std::string GetCfgDir();//获取配置文件目录
tstring GetCfgDirW();//获取配置文件目录
private:
CSync m_sync;
TCHAR m_szLogDir[MAX_PATH];
TCHAR m_szCfgDir[MAX_PATH];//配置文件目录
};
extern CLog ExLog;
log.cpp
#include "../StdAfx.h"
#include "Log.h"
#include
#include
#include
#include
#include
#include
CLog ExLog;
TCHAR* strleftLog(TCHAR *dst, TCHAR *src, int n)
{
TCHAR *p = src;
TCHAR *q = dst;
int len = static_cast(_tcslen(src));
if (n>len) n = len;
/*p += (len-n);*/ /*从右边第n个字符开始*/
while (n--) *(q++) = *(p++);
*(q++) = '\0'; /*有必要吗?很有必要*/
return dst;
}
CLog::CLog(void)
{
TCHAR szapipath[_MAX_PATH];
memset(szapipath, 0, _MAX_PATH);
GetModuleFileName(NULL, szapipath, _MAX_PATH);
TCHAR szdirpath[_MAX_PATH];
memset(szdirpath, 0, _MAX_PATH);
int nAppNamelen = 0;
for (int i = static_cast(_tcslen(szapipath)); i > 1; i--, nAppNamelen++)
{
if (szapipath[i - 1] == '\\')
{
break;
}
}
strleftLog(szdirpath, szapipath, static_cast(_tcslen(szapipath)) - nAppNamelen - 1);
memset(m_szLogDir,0, _MAX_PATH *sizeof(TCHAR));
_stprintf_s(m_szLogDir, _T("%s\\Runlogs"),szdirpath);
memset(m_szCfgDir, 0, _MAX_PATH * sizeof(TCHAR));
_stprintf_s(m_szCfgDir, _T("%s\\config\\config.ini"), szdirpath);
CreateLogdir(m_szLogDir);
}
CLog::~CLog(void)
{
}
bool CLog::CreateLogdir(TCHAR* szdir)
{
bool bret = false;
if (_taccess(szdir, 0) == 0) //如果目录已存在,直接返回
{
bret = true;
}
else
{
TCHAR sztemppath[_MAX_PATH];
memset(sztemppath, 0, _MAX_PATH);
TCHAR szsavetemppath[_MAX_PATH];
memset(szsavetemppath, 0, _MAX_PATH);
TCHAR *szfiledir = NULL;
TCHAR *ptoken = _tcstok_s(szdir, _T("\\"), &szfiledir);
bret = true;
//逐层创建目录
while (ptoken)
{
if (_tcslen(szsavetemppath) > 0)
{
_stprintf_s(sztemppath, _T("%s\\%s"), szsavetemppath, ptoken);
}
else
{
_stprintf_s(sztemppath, _T("%s"), ptoken);
}
memcpy_s(szsavetemppath, _MAX_PATH, sztemppath, _MAX_PATH);
if (_taccess(szsavetemppath, 0) != 0)
{
//创建失败时还应删除已创建的上层目录,此次略
if (!CreateDirectory(szsavetemppath, NULL))
{
DWORD dw = GetLastError();
bret = false;
break;
}
}
ptoken = _tcstok_s(NULL, _T("\\"), &szfiledir);
}
}
return bret;
}
////获取配置文件目录
std::string CLog::GetCfgDir()
{
std::string strRet = CW2A(m_szCfgDir);
return strRet;
}
//获取配置文件目录
tstring CLog::GetCfgDirW()
{
return m_szCfgDir;
}
int CLog::OutLog(int logtype, TCHAR* strlogtitle, TCHAR* strlogcontent, ...)
{
int nlen = static_cast(_tcslen(strlogcontent) + 1024);
TCHAR* writebuffer = new TCHAR[nlen];
memset(writebuffer, 0, nlen);
va_list arg_ptr;
va_start(arg_ptr, strlogcontent);
_vsntprintf_s(writebuffer, nlen - 1, _TRUNCATE, strlogcontent, arg_ptr);
va_end(arg_ptr);
int ncontentlen = static_cast(_tcslen(writebuffer));
int nret = 0;
m_sync.Lock();
if (CreateLogdir(m_szLogDir))
{
SYSTEMTIME wtm;
GetLocalTime(&wtm);
TCHAR buffer[80];
_stprintf_s(buffer, 80, _T("%02d:%02d:%02d.%03d"), wtm.wHour, wtm.wMinute, wtm.wSecond, wtm.wMilliseconds);
int nbufflen = ncontentlen + 100;
TCHAR* writebuff = new TCHAR[nbufflen];
memset(writebuff, 0, nbufflen);
_stprintf_s(writebuff, nbufflen, _T("%d\t%s\t%s\t%s\r\n"), logtype, buffer, strlogtitle, writebuffer);
TCHAR szLogPath[_MAX_PATH];
memset(szLogPath, 0, _MAX_PATH);
_stprintf_s(szLogPath, _MAX_PATH, _T("%s\\%04d%02d%02d.log"), m_szLogDir, wtm.wYear, wtm.wMonth, wtm.wDay);
std::wstring_convert> conv;
std::string narrowStr = conv.to_bytes(writebuff);
std::ofstream ofs(szLogPath, ios::app);
ofs << narrowStr;
ofs.close();
//FILE* pfile = NULL;
//if (0 == _tfopen_s(&pfile, szLogPath, _T("a+")))
//{
// std::string strBuf = CW2A(writebuff);
// fwrite(strBuf.c_str(), 1, strBuf.length(), pfile);
// fclose(pfile);
//}
//else
//{
// nret = 2;
//}
delete[] writebuff;
}
else
{
nret = 1;
}
m_sync.Unlock();
delete[] writebuffer;
return nret;
}