以下是一个比较完整的log实现方式
#ifndef LOGFILE_H
#define LOGFILE_H
//#include "stdafx.h"
//#include <stdio.h>
//#include <string.h>
//#include <algorithm>
//
//#include <ctime>
//#include <sstream>
#include <windows.h>
const int LOG_INFO_HIT = 0; //提示.
const int LOG_INFO_WARN = 1; //警告.
const int LOG_INFO_ERROR = 2; //错误.
const int LOG_INFO_FATAL_ERROR = 3;//严重错误.
const int LOG_FILE_MAX_CHAR_NUM = 128*1024; //一次写日志最大的缓存去。
const int LOG_FILE_MAX_PATH = 512; //日志文件最大的路径;
#define LOG_FILE_PATH ".\\log\\" //日志目录
//临界区封装类
class CLogCriticalSection
{
private:
protected:
public:
CLogCriticalSection();
virtual ~CLogCriticalSection();
public:
operator CRITICAL_SECTION*();
CRITICAL_SECTION m_sect;
bool m_bLock;
bool Unlock();
bool Lock();
bool Lock(DWORD dwTimeout);
};
//自动锁对象。
class CLogAutoLock
{
public:
CLogAutoLock::CLogAutoLock(CLogCriticalSection& SyncLock)
:m_SyncLock(SyncLock)
{
m_SyncLock.Lock();
};
CLogAutoLock::~CLogAutoLock(void)
{
m_SyncLock.Unlock();
}
protected:
CLogCriticalSection& m_SyncLock;
};
//
//C++类的LOG实现。
//
class CLogFile
{
public:
CLogFile(void);
virtual ~CLogFile(void);
public:
static CLogFile *Instance( )
{
static CLogFile FileLog;
return &FileLog;
}
//
//创建LOG文件。
//
void LOG_Start(char* pszFilename);
//
//写LOG.
//使用LOG的句柄,错误级别,格式化字符串.
//
void LOG_Write(int nErrorLevel,const char* pFormatStr, ...);
//
//输出一行,带回车的。
//
void LOG_WriteLine(int nErrorLevel,const char* pFormatStr,...);
//关闭LOG的句柄。
void LOG_Close(void);
//创建LOG目录。
bool LOG_CreateDir(char* pszLogDir);
//在Win32利用OutputDebugString输出一行`在这里插入代码片`
void LOG_DebugString(int nErrorLevel,const char* pFormatStr,...);
protected:
//每天创建一个文件。
void LOG_CreateFile(char* pszFileName);
char * m_buf;
//文件名称。
char m_chFile[LOG_FILE_MAX_PATH];
char m_chPreFile[LOG_FILE_MAX_PATH];
//保存LOG句柄.
HANDLE m_hLog;
CLogCriticalSection m_csLock;
};
#endif
以下是实现方式
#include "stdafx.h"
#include "logfile.h"
#include <string>
#pragma warning( disable : 4996 )
//
//
//
CLogFile::CLogFile(void)
{
m_hLog = NULL;
memset(m_chFile, 0, LOG_FILE_MAX_PATH);
memset(m_chPreFile, 0, LOG_FILE_MAX_PATH);
}
//
//
//
CLogFile::~CLogFile(void)
{
}
//
//创建LOG文件。
//
void CLogFile::LOG_Start(char* pszFilename)
{
if (strlen(pszFilename) <= 0)
{
//TRACE0("LOG filename is empty error!\n");
return;
}
CLogAutoLock autoLock(m_csLock);
//
strcpy(m_chPreFile,pszFilename);
//
LOG_CreateDir(pszFilename);
LOG_CreateFile(m_chPreFile);
}
//
//写LOG.
//使用LOG的句柄,错误级别,格式化字符串.
//
void CLogFile::LOG_Write(int nErrorLevel,const char* pFormatStr, ...)
{
// return;
const int nBufSize = LOG_FILE_MAX_CHAR_NUM;
char Buf[nBufSize]={0};
CLogAutoLock autoLock(m_csLock);
//
LOG_CreateFile(m_chPreFile);
if (m_hLog == NULL)
{
//TRACE0("LOG_Write ERROR!\n");
return;
}
std::string strValue;
char Level[32];
if (nErrorLevel == LOG_INFO_HIT)
{
strcpy(Level,"提示");
}
else if (nErrorLevel == LOG_INFO_WARN)
{
strcpy(Level,"警告");
}
else if (nErrorLevel == LOG_INFO_ERROR)
{
strcpy(Level,"错误");
}
else if (nErrorLevel == LOG_INFO_FATAL_ERROR)
{
strcpy(Level,"致命");
}
else
{
strcpy(Level,"未明");
}
//输出时间.
SYSTEMTIME stToday;
GetLocalTime(&stToday);
//[2005-03-25 11:29:16]
sprintf_s(Buf,nBufSize,"[%04d-%02d-%02d %02d:%02d:%02d LEVEL=%s] ",
stToday.wYear,stToday.wMonth,stToday.wDay,
stToday.wHour,stToday.wMinute,stToday.wSecond,
Level);
//写到LOG文件.
fwrite(Buf,strlen(Buf),1,(FILE*)m_hLog);
//
memset(Buf,0,nBufSize);
//分析输入可变参数.
va_list list;
va_start(list, pFormatStr);
vsprintf_s(Buf, pFormatStr, list);
va_end(list);
//写到LOG文件.
fwrite(Buf,strlen(Buf),1,(FILE*)m_hLog);
//缓冲区写到文件.
fflush((FILE*)m_hLog);
}
//
//输出一行,带回车的。
//
void CLogFile::LOG_WriteLine(int nErrorLevel,const char* pFormatStr,...)
{
CLogAutoLock autoLock(m_csLock);
//
LOG_CreateFile(m_chPreFile);
if (m_hLog == NULL)
{
//TRACE0("LOG_WriteLine ERROR!\n");
return;
}
const int nBufSize = LOG_FILE_MAX_CHAR_NUM;
char Buf[nBufSize];
char Level[32];
if (nErrorLevel == LOG_INFO_HIT)
{
strcpy(Level,"提示");
}
else if (nErrorLevel == LOG_INFO_WARN)
{
strcpy(Level,"警告");
}
else if (nErrorLevel == LOG_INFO_ERROR)
{
strcpy(Level,"错误");
}
else if (nErrorLevel == LOG_INFO_FATAL_ERROR)
{
strcpy(Level,"致命");
}
else
{
strcpy(Level,"未明");
}
//输出时间.
SYSTEMTIME stToday;
GetLocalTime(&stToday);
//[2005-03-25 11:29:16]
sprintf_s(Buf,nBufSize,"[%04d-%02d-%02d %02d:%02d:%02d LEVEL=%s] ",
stToday.wYear,stToday.wMonth,stToday.wDay,
stToday.wHour,stToday.wMinute,stToday.wSecond,
Level);
//写到LOG文件.
fwrite(Buf,strlen(Buf),1,(FILE*)m_hLog);
//
memset(Buf,0,nBufSize);
//分析输入可变参数.
va_list list;
va_start(list, pFormatStr);
vsprintf_s(Buf, pFormatStr, list);
va_end(list);
//写到LOG文件.
int nCount = fwrite(Buf,strlen(Buf),1,(FILE*)m_hLog);
FILE * pfile = (FILE*)m_hLog;
//写回车行。
memcpy(Buf,"\r\n",2);
fwrite(Buf,2,1,(FILE*)m_hLog);
//缓冲区写到文件.
fflush((FILE*)m_hLog);
}
//
//关闭LOG的句柄。
//
void CLogFile::LOG_Close(void)
{
CLogAutoLock autoLock(m_csLock);
if (m_hLog)
{
fclose((FILE*)m_hLog);
}
}
//
//每天创建一个文件。
//
void CLogFile::LOG_CreateFile(char* pszFileName)
{
//输出时间.
SYSTEMTIME stToday;
GetLocalTime(&stToday);
//生成日志文件名称
char chBuf[LOG_FILE_MAX_PATH];
sprintf_s(chBuf,LOG_FILE_MAX_PATH,"%s%04d%02d%02d%s",
pszFileName,stToday.wYear,stToday.wMonth,stToday.wDay,".log");
//
if (memcmp(m_chFile,chBuf,strlen(chBuf)) != 0)
{
if (m_hLog)
{
LOG_Close();
}
//
memcpy(m_chFile,chBuf,strlen(chBuf));
m_hLog = fopen(m_chFile, "a");
//m_hLog = fopen(m_chFile, "w+");
LOG_WriteLine(LOG_INFO_HIT, "--------------------- anzer_center server B2017.4.25 -----------------------");
}
}
void CLogFile::LOG_DebugString(int nErrorLevel, const char* pFormatStr,...)
{
#if defined(_WIN32)
CLogAutoLock autoLock(m_csLock);
const int nBufSize = LOG_FILE_MAX_CHAR_NUM;
char Buf[nBufSize] = {0};
char Str[nBufSize] = {0};
char Level[32];
if (nErrorLevel == LOG_INFO_HIT)
{
strcpy(Level,"提示");
}
else if (nErrorLevel == LOG_INFO_WARN)
{
strcpy(Level,"警告");
}
else if (nErrorLevel == LOG_INFO_ERROR)
{
strcpy(Level,"错误");
}
else if (nErrorLevel == LOG_INFO_FATAL_ERROR)
{
strcpy(Level,"致命");
}
else
{
strcpy(Level,"未明");
}
//输出时间.
SYSTEMTIME stToday;
GetLocalTime(&stToday);
//分析输入可变参数.
va_list list;
va_start(list, pFormatStr);
vsprintf_s(Str, pFormatStr, list);
va_end(list);
sprintf_s(Buf,nBufSize,"[%04d-%02d-%02d %02d:%02d:%02d LEVEL=%s] %s",
stToday.wYear,stToday.wMonth,stToday.wDay,
stToday.wHour,stToday.wMinute,stToday.wSecond,
Level, Str);
OutputDebugStringA(Buf);
#endif
}
//
//创建LOG目录。
//
bool CLogFile::LOG_CreateDir(char* pszLogDir)
{
if (!CreateDirectoryA(pszLogDir,NULL))
{
DWORD dwRet = GetLastError();
if (dwRet != ERROR_ALREADY_EXISTS)
{
return false;
}
}
return true;
}
//创建临界区.
CLogCriticalSection::CLogCriticalSection()
{
::InitializeCriticalSection(&m_sect);
m_bLock = false;
}
//指针操作.
CLogCriticalSection::operator CRITICAL_SECTION*()
{
return (CRITICAL_SECTION*) &m_sect;
}
//删除临界区.
CLogCriticalSection::~CLogCriticalSection()
{
::DeleteCriticalSection(&m_sect);
m_bLock = false;
}
//锁住.
bool CLogCriticalSection::Lock()
{
::EnterCriticalSection(&m_sect);
m_bLock = true;
return true;
}
//锁住
bool CLogCriticalSection::Lock(DWORD /* dwTimeout */)
{
return Lock();
}
//解锁.
bool CLogCriticalSection::Unlock()
{
::LeaveCriticalSection(&m_sect);
m_bLock = false;
return true;
}
int main()
{
//CLogFile::Instance()->LOG_Start("D:\\Log\\ServerIO.txt");
CLogFile::Instance()->LOG_Write(1,"InitServer() udpsock:%d\n",Sock);
}