一、服务器端日志与客户端日志的区别
在正式讲解之前,我们先来看一个日志类的实现方法,这个日志类也是代表着大多数客户端日志的主流写法:
/**
*@desc: 程序运行log类,log.h
*@author: zhangyl
*@date: 2017.01.17
**/
#ifndef __LOG_H__
#define __LOG_H__
#ifdef _ZYL_LOG_
#define LogInfo(...) Log::GetInstance().AddLog("INFO", __FILE__, __LINE__, __FUNCSIG__, __VA_ARGS__)
#define LogWarning(...) Log::GetInstance().AddLog("WARNING", __FILE__, __LINE__, __FUNCSIG__, __VA_ARGS__)
#define LogError(...) Log::GetInstance().AddLog("ERROR", __FILE__, __LINE__, __FUNCSIG__, __VA_ARGS__)
#else
#define LogInfo(...) (void(0))
#define LogError(...) (void(0))
#endif
class Log
{
public:
static Log& GetInstance();
bool AddLog(const char* pszLevel, const char* pszFile, int lineNo, const char* pszFuncSig, char* pszFmt, ...);
private:
Log();
~Log();
Log(const Log&);
Log& operator=(const Log&);
private:
FILE* m_file;
};
#endif //!__LOG_H__
/**
*@desc: 程序运行log类,log.cpp
*@author: zhangyl
*@date: 2017.01.17
**/
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include "Log.h"
Log& Log::GetInstance()
{
static Log log;
return log;
}
bool Log::AddLog(const char* pszLevel, const char* pszFile, int lineNo, const char* pszFuncSig, char* pszFmt, ...)
{
if (m_file == NULL)
return false;
char tmp[8192*10] = { 0 };
va_list va; //定义一个va_list型的变量,这个变量是指向参数的指针.
va_start(va, pszFmt); //用va_start宏初始化变量,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数
_vsnprintf(tmp, ARRAYSIZE(tmp), pszFmt, va);//注意,不要漏掉前面的_
va_end(va);
time_t now = time(NULL);
struct tm* tmstr = localtime(&now);
char content[8192 * 10 + 256] = {0};
sprintf_s(content, ARRAYSIZE(content), "[%04d-%02d-%02d %02d:%02d:%02d][%s][0x%04x][%s:%d %s]%s\r\n",
tmstr->tm_year + 1900,
tmstr->tm_mon + 1,
tmstr->tm_mday,
tmstr->tm_hour,
tmstr->tm_min,
tmstr->tm_sec,
pszLevel,
GetCurrentThreadId(),
pszFile,
lineNo,
pszFuncSig,

最低0.47元/天 解锁文章
3145

被折叠的 条评论
为什么被折叠?



