项目因为切换日志库,选型log4cpp,为了使用方便,进行了二次封装
log4cpp.h
#ifndef __LOG_4_CPP__
#define __LOG_4_CPP__
#include
#include //strrchr()函数所需头文件
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef _WIN32
#include
#include
#else
#include
#include
#include
#include
#include
#endif
//日志优先级
enum Priority {
LOG_LEVEL_ERROR = 0,
LOG_LEVEL_WARN = 1,
LOG_LEVEL_INFO = 2,
LOG_LEVEL_DEBUG = 3
};
#define MAX_LOG_RECORD_LEN 1024*4 //每条日志大小
#define MAX_LOGSIZE 1024*1024*10 //日志文件大小,默认10M 1024*1024*10
#define LOGFILE_SIZE 30 //文件日志数量
//用单例模式封装log4cpp
class CCVLog {
public:
static CCVLog& getInstance();
~CCVLog();
// 设置日志输出文件名 [10/16/2019 none]
bool SetLogFileName(const std::string& fileName = "log4cpp.log");
// 设置日志级别 [10/16/2019 none]
void SetPriority(Priority priority);
// 日志打印 [10/16/2019 none]
void Info(const char* pchFormat, ...);
void Debug(const char* pchFormat, ...);
void Error(const char* pchFormat, ...);
void Warn(const char* pchFormat, ...);
//void Warn(const char* szFileName, const int nLineNo, const char* pchFormat, ...);
// 释放 [10/16/2019 none]
void Destory();
private:
//单例模式:构造函数私有化
CCVLog();
//设置终端不显示,只打印日志文件 [10/16/2019 none]
void SetLogOnMonitor(const char* pszCfgFileName);
//读取日志配置文件 [10/16/2019 none]
void SetConfigureFile(const char* pszCfgFileName);
//创建日志文件夹 [10/16/2019 none]
bool CreatLogDir(int nPos, std::string strFileName);
private:
std::string m_strLogFileName;
log4cpp::Category& m_Category_Ref;
static CCVLog* m_pLog;
static char m_szLogBuf[MAX_LOG_RECORD_LEN];
log4cpp::OstreamAppender* m_pOs_Appender;
log4cpp::FileAppender* m_pFile_Appender;
};
#ifdef WIN32
#define FILENAME(x) strrchr(x,'\\')?strrchr(x,'\\')+1:x
#else
#define FILENAME(x) strrchr(x,'/')?strrchr(x,'/')+1:x
#endif
static CCVLog &CVLog = CCVLog::getInstance(); //实例化单例
#define LOG_E(format, ...) CVLog.Error(format, ##__VA_ARGS__)
#define LOG_W(format, ...) CVLog.Warn(format, ##__VA_ARGS__)
#define LOG_I(format, ...) CVLog.Info(format, ##__VA_ARGS__)
#define LOG_D(format, ...) CVLog.Debug(format, ##__VA_ARGS__)
//#define LOG_I(format, ...) CVLog.Info(FILENAME(__FILE__), __LINE__, format, ##__VA_ARGS__)
#endif // !__LOG_4_CPP__
log4cpp.cpp
#include "stdafx.h"
#include "log4cpp.h"
#include
using namespace std;
#ifdef _WIN32
#define ACCESS _access
#define MKDIR(a) _mkdir((a))
int CreatDir(char *pDir)
{
int i = 0;
int iRet = 0;
int iLen;
char* pszDir;
if (NULL == pDir)
{
return 0;
}
pszDir = strdup(pDir);
iLen = strlen(pszDir);
// 创建中间目录
for (i = 0; i < iLen; i++)
{
if (pszDir[i] == '\\' || pszDir[i] == '/')
{
pszDir[i] = '\0';
iRet = ACCESS(pszDir, 0); //如果不存在,创建
if (iRet != 0)
{
iRet = MKDIR(pszDir);
if (iRet != 0)
{
return -1;
}
}
pszDir[i] = '/'; //支持linux,将所有\换成/
}
}
iRet = MKDIR(pszDir);
free(pszDir);
printf("-----%d---\n", iLen);
return iRet;
}
#else
#define ACCESS access
#define MKDIR(a) mkdir((a),0755)
//创建多级目录
int CreatDir(char* sPathName)
{
char szCmd[128] = { 0 }; //system("mkdir -p path");
sprintf(szCmd, "mkdir -p %s", sPathName);
system(szCmd);
return 0;
}
#endif
// 静态成员初始化
char CCVLog::m_szLogBuf[MAX_LOG_RECORD_LEN] = { 0 };
CCVLog* CCVLog::m_pLog = NULL;
//获取log指针
CCVLog& CCVLog::getInstance()
{
if (m_pLog == NULL) {
m_pLog = new CCVLog;
}
return *m_pLog;
}
//销毁
CCVLog::~CCVLog() { }
//销毁
void CCVLog::Destory()
{
if (m_pLog) {
m_pLog->m_Category_Ref.info("log4cpp destroy :%s", m_strLogFileName.c_str());
m_pLog->m_Category_Ref.shutdown();
delete m_pLog;
m_pLog = NULL;
}
}
//构造函数
CCVLog::CCVLog() : m_Category_Ref(log4cpp::Category::getRoot()), m_strLogFileName(std::string("log4cpp.log"))
{
}
void CCVLog::SetLogOnMonitor(const char* pszCfgFileName)
{
}
void CCVLog::SetConfigureFile(const char* pszCfgFileName)
{
}
//创建日志文件夹 [10/16/2019 none]
bool CCVLog::CreatLogDir(int nPos, std::string strFileName)
{
char szpath[128] = { 0 };
memset(szpath, 0, 128);
std::string strPath = strFileName.substr(0, nPos + 1);
sprintf(szpath, "%s", strPath.c_str());
#ifdef _WIN32
if (0 == CreatDir(szpath))
{
printf("创建日志文件夹失败");
return false;
}
#else
CreatDir(szpath);
#endif
return true;
}
// 设置日志级别 [10/16/2019 none]
void CCVLog::SetPriority(Priority priority) {
switch (priority) {
case (LOG_LEVEL_ERROR):
m_Category_Ref.setPriority(log4cpp::Priority::ERROR);
break;
case (LOG_LEVEL_WARN):
m_Category_Ref.setPriority(log4cpp::Priority::WARN);
break;
case (LOG_LEVEL_INFO):
m_Category_Ref.setPriority(log4cpp::Priority::INFO);
break;
default:
m_Category_Ref.setPriority(log4cpp::Priority::DEBUG);
break;
}
}
// 设置日志输出文件名 [10/16/2019 none]
bool CCVLog::SetLogFileName(const std::string& fileName /*= "log4cpp.log"*/)
{
m_strLogFileName = fileName;
#ifdef _WIN32
int nPos = fileName.rfind("\\");
#else
int nPos = fileName.rfind("/");
#endif
if (nPos != string::npos)
{
if (!CreatLogDir(nPos, fileName))
{
return false;
}
}
else
{
nPos = fileName.rfind("//");
if (nPos != string::npos)
{
if (!CreatLogDir(nPos, fileName))
{
return false;
}
}
}
//自定义日志的输出格式 1
/*%c->category, %d->日期, %m->消息,, %n->换行, %p->优先级 %x-->NDC
举例: %d: %p %c %x:%m%n 时间: 优先级 Category NDC: 消息换行
*/
log4cpp::PatternLayout *pattern_one = new log4cpp::PatternLayout;
pattern_one->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p]%c%x %m%n");
//自定义日志的输出格式 2
log4cpp::PatternLayout *pattern_two = new log4cpp::PatternLayout;
pattern_two->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p]%c%x %m%n");
//获取屏幕输出
log4cpp::OstreamAppender *os_appender = new log4cpp::OstreamAppender("osAppender", &std::cout);
os_appender->setLayout(pattern_one);
m_pOs_Appender = os_appender;
//获取文件日志输出 http://blog.csdn.net/wyb19890515/article/details/7187057
log4cpp::FileAppender *file_appender = new log4cpp::RollingFileAppender("RollingFileAppender", m_strLogFileName, MAX_LOGSIZE, LOGFILE_SIZE);
file_appender->setLayout(pattern_two);
m_pFile_Appender = file_appender;
m_Category_Ref.setPriority(log4cpp::Priority::DEBUG); //设置优先级 注意:取值越小,优先级越
m_Category_Ref.addAppender(os_appender);
m_Category_Ref.addAppender(file_appender);
//log4cpp::Appender.TESTAppender.fileName
//log4cpp::Category::getRoot().getInstance("LOG").addAppender(file_appender); //使用滚动的方式记录日志
return true;
}
void CCVLog::Error(const char* pchFormat, ...)
{
memset(m_szLogBuf, 0, MAX_LOG_RECORD_LEN);
int nLen = 0;
//nLen += sprintf(m_szLogBuf + nLen, "[%s:%d] ", FILENAME(__FILE__), __LINE__);
// 日志信息
va_list list;
va_start(list, pchFormat);
nLen += vsprintf(m_szLogBuf + nLen, pchFormat, list);
va_end(list);
m_Category_Ref.error(m_szLogBuf);
}
// 日志打印 [10/16/2019 none]
void CCVLog::Info(const char* pchFormat, ...)
{
//日志格式 2019-10-16 20:25:23.495 [INFO] [VS2015.cpp:12]set log begin
memset(m_szLogBuf, 0, MAX_LOG_RECORD_LEN);
int nLen = 0;
//nLen += sprintf(m_szLogBuf + nLen, "[%s:%d] ", szFileName, nLineNo);
va_list list; // 日志信息
va_start(list, pchFormat); //C 不定参宏
nLen += vsprintf(m_szLogBuf + nLen, pchFormat, list);
va_end(list);
//nLen += sprintf(m_szLogBuf + nLen, " (%s:%d)", szFilename, nLineNo);
m_Category_Ref.info(m_szLogBuf);
}
void CCVLog::Debug(const char* pchFormat, ...)
{
memset(m_szLogBuf, 0, MAX_LOG_RECORD_LEN);
int nLen = 0;
//nLen += sprintf(m_szLogBuf + nLen, "[%s:%d] ", FILENAME(__FILE__), __LINE__);
va_list list; // 日志信息
va_start(list, pchFormat);
nLen += vsprintf(m_szLogBuf + nLen, pchFormat, list);
va_end(list);
m_Category_Ref.debug(m_szLogBuf);
}
void CCVLog::Warn(const char* pchFormat, ...)
{
memset(m_szLogBuf, 0, MAX_LOG_RECORD_LEN);
int nLen = 0;
//nLen += sprintf(m_szLogBuf + nLen, "[%s:%d] ", FILENAME(__FILE__), __LINE__);
va_list list; // 日志信息
va_start(list, pchFormat);
nLen += vsprintf(m_szLogBuf + nLen, pchFormat, list);
va_end(list);
m_Category_Ref.warn(m_szLogBuf);
}
main.cpp
#include "stdafx.h"
#include "log4cpp.h"
#include
using namespace std;
int main()
{
CVLog.SetLogFileName("/opt/logs/test/test.log");
int cnt = 1;
while (true)
{
CVLog.Debug("printf log debug");
CVLog.Error("printf log error");
CVLog.Warn("[%s %d]printf log warn, %d",FILENAME(__FILE__), __LINE__, cnt++);
LOG_I("printf INFO log :%d", FILENAME(__FILE__), __LINE__, cnt++);
LOG_W("printf WARN logn");
LOG_D("printf DEBUG log");
LOG_E("printf ERROR log");
}
CVLog.Destory();
system("pause");
return 0;
}
window或linux调用SetLogFileName,分别设置自定义路径日志目录即可!
如果想通过加载日志配置文件设定日志属性,自行发挥!
-------------------------------------------------------------------------------------------------
这个世界是被精心设计过的!