logger.h
#pragma once
#define FILE_NAME_SIZE 256 //文件名称大小
#define MAX_FILE_SIZE (4*1024) //最大的文件大小(4M)
class CHLog
{
public:
CHLog(void);
~CHLog(void);
private:
wchar_t m_FileName[FILE_NAME_SIZE]; //文件名称
int m_nFileSize; //文件大小(KB)
FILE *m_fpFile; //文件指针
public:
//初始化log,生成默认文件名(时间.LOG)
bool InitLogFile();
//初始化log,设置文件名(文件路径),打开文件
bool InitLogFile(const wchar_t *szFileName);
//停止log,关闭文件
void CloseLog();
//输出数据到文件,目前支持%s、%S(宽字符串)、%c、%d、%f、%02X、%lld
void WriteLogTofile(const char *format, ...);
//加时间戳,输出数据到文件(【时间】 + 信息),目前支持%s、%S(宽字符串)、%c、%d、%f、%02X、%lld
void WriteLogTofile(const bool &bHaveTime, const char *format, ...);
//protected:
//获得系统时间字符串
bool GetSystemTime(wchar_t *timebuff, int bufferlen, const wchar_t &cSplit = L'\0');
public:
};
logger.cpp
#include "stdafx.h"
#include "logger.h"
#include
CHLog::CHLog(void)
:m_nFileSize(0), m_fpFile(NULL)
{
memset(m_FileName, 0, sizeof(wchar_t)*FILE_NAME_SIZE);
}
CHLog::~CHLog(void)
{
}
//初始化log,生成默认文件名(时间.LOG)
bool CHLog::InitLogFile()
{
//获得时间戳
if ( GetSystemTime(m_FileName, FILE_NAME_SIZE) )
{
//加上.LOG
wcscat_s(m_FileName, L".log");
wchar_t m_FileName0[] = L"Trace.log";
if (NULL != m_FileName)
{
_wfopen_s(&m_fpFile, m_FileName0, L"a+");
}
}
return false;
}
//设置文件名(文件路径)
bool CHLog::InitLogFile(const wchar_t *szFileName)
{
//校验
if ( (NULL == szFileName) ||
(1 > wcslen(szFileName)) ||
(FILE_NAME_SIZE < wcslen(szFileName)) )
{
return false;
}
//赋值
wcscat_s(m_FileName, FILE_NAME_SIZE, szFileName);
//打开嗯我那件
if (NULL != m_FileName)
{
_wfopen_s(&m_fpFile, m_FileName, L"a+");
}
return true;
}
//停止log,关闭文件
void CHLog::CloseLog()
{
fclose(m_fpFile);
}
//获得系统时间字符串【格式:2018 + 分割符 + 0523 + 分隔符 + 150353】
bool CHLog::GetSystemTime(wchar_t *timebuff, int bufferlen, const wchar_t &cSplit)
{
// 校验入参
if ( (NULL == timebuff) )
{
return false;
}
// 获取系统当前时间戳
time_t tt = time(NULL);
struct tm t;
errno_t err = localtime_s(&t, &tt);
SYSTEMTIME localTime = { 0 };
GetLocalTime( &localTime );
//校验
if (0 != err)
return false;
//获得字符串
if (L'\0' == cSplit)
{
swprintf_s( timebuff,
bufferlen,
L"%d-%02d-%02d %02d:%02d:%02d: %02d",
t.tm_year + 1900,
t.tm_mon + 1,
t.tm_mday,
t.tm_hour,
t.tm_min,
t.tm_sec,
localTime.wMilliseconds
);
}
else
{
swprintf_s( timebuff,
bufferlen,
L"%d%c%02d%02d%c %02d:%02d:%02d: %02d\n",
t.tm_year + 1900,
cSplit,
t.tm_mon + 1,
t.tm_mday,
cSplit,
t.tm_hour,
t.tm_min,
t.tm_sec,
localTime.wMilliseconds
);
}
return true;
}
//输出数据到文件,目前支持%s、%S(宽字符串)、%c、%d、%f、%02X、%lld
void CHLog::WriteLogTofile(const char *format, ...)
{
//校验
if (NULL == m_fpFile)
return;
//变量定义
va_list ap = NULL;
va_start(ap, format);
char *eos = (char *)format; //结束标志
//开始写入
while (*eos)
{
if('%' == *eos)
{
//获得下一个字符
eos++;
switch(*eos)
{
case 's': //字符串
{
char *sTmp = va_arg(ap, char*);
while(*sTmp)
{
fprintf(m_fpFile, "%c", *sTmp);
sTmp++;
}
break;
}
case 'S': //宽字符串
{
wchar_t *wsTmp = va_arg(ap, wchar_t*);
while(*wsTmp)
{
fprintf(m_fpFile, "%c", *wsTmp);
wsTmp++;
}
break;
}
case 'c': //字符
{
char cTmp = va_arg(ap, char);
fprintf(m_fpFile, "%c", cTmp);
break;
}
case 'd': //十进制
{
int dTmp = va_arg(ap, int);
fprintf(m_fpFile, "%d", dTmp);
break;
}
case '0': //二进制02X
{
char *cNext = eos;
if (('2' == *(++eos)) && ('X' == *(++eos)))
{
int dTmp = va_arg(ap, int);
fprintf(m_fpFile, "%02X", dTmp);
}
break;
}
case 'f': //浮点型
{
float fTmp = (float)va_arg(ap, double);
fprintf(m_fpFile, "%f", fTmp);
break;
}
case 'l': //LONGLONG型
{
char *cNext = eos;
if (('l' == *(++eos)) && ('d' == *(++eos)))
{
LONGLONG lTmp = (LONGLONG)va_arg(ap, LONGLONG);
fprintf(m_fpFile, "%lld", lTmp);
}
break;
}
default :
break;
}
}
else
{
fprintf(m_fpFile, "%c", *eos);
}
eos++;
}
//最后写入换行符
fprintf(m_fpFile, "\n");
}
//加时间戳,输出数据到文件(【时间】 + 信息),目前支持%s、%S(宽字符串)、%c、%d、%f、%02X、%lld
void CHLog::WriteLogTofile(const bool &bHaveTime, const char *format, ...)
{
//校验
if (NULL == m_fpFile)
return;
//写入时间戳
if (bHaveTime)
{
wchar_t szTime[FILE_NAME_SIZE];
GetSystemTime(szTime, FILE_NAME_SIZE);
fprintf(m_fpFile, "【%S】", szTime);
}
//变量定义
va_list ap = NULL;
va_start(ap, format);
char *eos = (char *)format; //结束标志
//开始写入
while (*eos)
{
if('%' == *eos)
{
//获得下一个字符
eos++;
switch(*eos)
{
case 's': //字符串
{
char *sTmp = va_arg(ap, char*);
while(*sTmp)
{
fprintf(m_fpFile, "%c", *sTmp);
sTmp++;
}
break;
}
case 'S': //宽字符串
{
wchar_t *wsTmp = va_arg(ap, wchar_t*);
while(*wsTmp)
{
fprintf(m_fpFile, "%c", *wsTmp);
wsTmp++;
}
break;
}
case 'c': //字符
{
char cTmp = va_arg(ap, char);
fprintf(m_fpFile, "%c", cTmp);
break;
}
case 'd': //十进制
{
int dTmp = va_arg(ap, int);
fprintf(m_fpFile, "%d", dTmp);
break;
}
case '0': //二进制02X
{
char *cNext = eos;
if (('2' == *(++eos)) && ('X' == *(++eos)))
{
int dTmp = va_arg(ap, int);
fprintf(m_fpFile, "%02X", dTmp);
}
break;
}
case 'f': //浮点型
{
float fTmp = (float)va_arg(ap, double);
fprintf(m_fpFile, "%f", fTmp);
break;
}
case 'l': //LONGLONG型
{
char *cNext = eos;
if (('l' == *(++eos)) && ('d' == *(++eos)))
{
LONGLONG lTmp = (LONGLONG)va_arg(ap, LONGLONG);
fprintf(m_fpFile, "%lld", lTmp);
}
break;
}
default :
break;
}
}
else
{
fprintf(m_fpFile, "%c", *eos);
}
eos++;
}
//最后写入换行符
//fprintf(m_fpFile, "\n");
}
实现
void main()
{
//打印宽字节一定要用大写的S%,打印字符用小写的s%,打印整形用d%,打印浮点型用f%,long用l%
//默认打印在应用程序路径下
std::wstring sql = L"测试程序";
CHLog hlog;
hlog.InitLogFile();
hlog.WriteLogTofile(true, "sql:%S \n",sql.c_str());
hlog.CloseLog();
}