Linux C++,使用log4cpp记录日志示例详解

8 篇文章 0 订阅
1 篇文章 0 订阅

Linux C++,使用log4cpp记录日志示例详解

本文主要说明 log4cpp 使用中的配置及调用方法。过程中,会调用 log4cpp开源代码生成的.so,关于如何调用.so,可参考《Linux环境下,创建.so动态链接库 代码实例》

https://aduandniuniu.blog.csdn.net/article/details/123458447?spm=1001.2014.3001.5502

Linux下,还有其他的日志记录开源工具包,比如:spdlog,使用过程都比较类似。 可根据自身情况,灵活选择即可。关于spdlog的使用方法,可参考:《Ubuntu C++, 使用spdlog记录日志示例详解》

https://aduandniuniu.blog.csdn.net/article/details/125423672

log4cpp 是比较普遍使用的开源日志记录模块。目前有各种平台下的版本,可用于JAVA、C++、C#等各种开发语言。。本文重点详细说明在Linux 下C++开发示例。

  • 1、ini配置文件格式说明
  • 2、封装log4cpp日志接口CLogRecord(.h、.cpp)
  • 3、C++调用代码

1、ini配置文件格式说明

示例中,举例了同时对两个日志对象进行了说明。注意其中的: appender1、appender2,A1、A2的定义之处。

  • fileName: 设置生成的日志文件名称及路径
  • maxFileSize:设置单个日志文件大小
  • maxBackupIndex:设置日志文件备份个数,超过个数,自动循环记录
[log4cpp]
rootCategory=DEBUG,appender1
additivity.rootCategory=false

appender.appender1=RollingFileAppender
appender.appender1.fileName=/home/log/logTrafficControlServer.log
appender.appender1.maxFileSize=10485780
appender.appender1.maxBackupIndex=10
appender.appender1.layout=PatternLayout
appender.appender1.layout.ConversionPattern=$%5p %d{%Y-%m-%d %H:%M:%S.%l}@%m%n
category.A1=DEBUG,appender1
additivity.A1=false


appender.appender2=RollingFileAppender
appender.appender2.fileName=/home/log/logTrafficControlServer_TimerDataTrans.log
appender.appender2.maxFileSize=10485780
appender.appender2.maxBackupIndex=10
appender.appender2.layout=PatternLayout
appender.appender2.layout.ConversionPattern=$%5p %d{%Y-%m-%d %H:%M:%S.%l}@%m%n
category.A2=DEBUG,appender2
additivity.A2=false

2、封装log4cpp日志接口CLogRecord

2.1 CLogRecord.h

/*
 * CLogOper.h
 *
 *  Created on: 2022-02-16
 *      Author:
 */
#ifndef LOGMODULE_LOGRECORD_H
#define LOGMODULE_LOGRECORD_H

class CLogRecord {
public:
    CLogRecord();
	virtual ~CLogRecord();
public:
	void GetLogFileName(const char* pszLogFileDir, const char* pszDeviceCode,
			int iFileNum, char* pszLogFileName);//获得日志的文件名

    /*! \fn bool CLogRecord::SetConfigureFile(const char* pszConfigureFileName, const char* pszInstanceName, const char* pszLogFileName, int iMaxFileSize, int iMaxBackupIndex, const char* pszPriority)
    * \brief 设置日志配置文件
    * \param[in]  	pszConfigureFileName
    * \param[in]  	pszInstanceName
    * \param[in]  	pszLogFileName
    * \param[in]  	iMaxFileSize
    * \param[in]  	iMaxBackupIndex
    * \param[in]  	pszPriority
    * \return		true: 初始化成功;false:初始化失败
    * \author
    * \date 		2022-02-17
    */
	bool SetConfigureFile(const char* pszConfigureFileName,
			const char* pszInstanceName, const char* pszLogFileName,
			int iMaxFileSize = 10485760, int iMaxBackupIndex = 10,
			const char* pszPriority = "DEBUG");//设置日志配置文件

    /*! \fn bool CLogRecord::InitLogInstance(const char* pszConfigureFileName, const char* pszInstanceName)
    * \brief 初始化日志实例
    * \param[in]  	pszConfigureFileName
    * \param[in]  	pszInstanceName
    * \return		true: 初始化成功;false:初始化失败
    * \author
    * \date 		2022-02-17
    */
	bool InitLogInstance(const char* pszConfigureFileName,
			const char* pszInstanceName);//初始化日志实例

	//日志记录:DEBUG等级
	void LogDebug(const char* pszStringLog, ...);

	//日志记录:INFO等级
	void LogInfo(const char* pszStringLog, ...);

	//日志记录:WARN等级
	void LogWarn(const char* pszStringLog, ...);

	//日志记录:ERROR等级
	void LogError(const char* pszStringLog, ...);

	//日志记录:FATAL等级
	void LogFatal(const char* pszStringLog, ...);

protected:
	void* m_hCategory; //生成实例的句柄
};

#endif /* LOGMODULE_LOGRECORD_H */

CLogRecord.cpp

/*
 * CLogOper.cpp
 *
 *  Created on: 2022-02-16
 *      Author:
*/


#include "log4cpp/Category.hh"
#include "log4cpp/PropertyConfigurator.hh"
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/RollingFileAppender.hh"
#include "log4cpp/Priority.hh"

#include "CLogRecord.h"

#define LOG_OPER_MAX_SIZE 204800

CLogRecord::CLogRecord() {
	// TODO Auto-generated constructor stub
	m_hCategory = NULL;

}

CLogRecord::~CLogRecord() {
	// TODO Auto-generated destructor stub
}

//获得日志的文件名
void CLogRecord::GetLogFileName(const char* pszLogFileDir,
		const char* pszDeviceCode, int iFileNum, char* pszLogFileName) {
	// TODO Auto-generated destructor stub
}


/*! \fn bool CLogRecord::SetConfigureFile(const char* pszConfigureFileName, const char* pszInstanceName, const char* pszLogFileName, int iMaxFileSize, int iMaxBackupIndex, const char* pszPriority)
 * \brief 设置日志配置文件
 * \param[in]  	pszConfigureFileName
 * \param[in]  	pszInstanceName
 * \param[in]  	pszLogFileName
 * \param[in]  	iMaxFileSize
 * \param[in]  	iMaxBackupIndex
 * \param[in]  	pszPriority
 * \return		true: 初始化成功;false:初始化失败
 * \author
 * \date 		2022-02-17
 */
bool CLogRecord::SetConfigureFile(const char* pszConfigureFileName, const char* pszInstanceName,
                                  const char* pszLogFileName, int iMaxFileSize, int iMaxBackupIndex, const char* pszPriority)
{
	if(m_hCategory)
	{
		delete (log4cpp::Category*)m_hCategory;
		m_hCategory = NULL;
	}
	bool bCfgExists = true;
	// 1 读取解析配置文件
	// 读取出错, 完全可以忽略,可以定义一个缺省策略或者使用系统缺省策略
	// BasicLayout输出所有优先级日志到ConsoleAppender
	try {
		log4cpp::PropertyConfigurator::configure(pszConfigureFileName);
	} catch (log4cpp::ConfigureFailure& f) {
		std::cout << "Configure Problem " << f.what() << std::endl;
		bCfgExists = false;
	}

	bool bCreateNewCategory = false;
	if (bCfgExists) {
		m_hCategory = log4cpp::Category::exists(std::string(pszInstanceName));

		if (m_hCategory == NULL) {
			bCreateNewCategory = true;
		}
	} else {
		bCreateNewCategory = true;
	}

	if (bCreateNewCategory) {
		log4cpp::PatternLayout* pLayout1 = new log4cpp::PatternLayout();
		pLayout1->setConversionPattern("$%5p %d{%Y-%m-%d %H:%M:%S.%l}@%m%n");

		log4cpp::RollingFileAppender* rollfileAppender =
				new log4cpp::RollingFileAppender("RollingFileAppender",
						pszLogFileName, iMaxFileSize, iMaxBackupIndex);
		rollfileAppender->setLayout(pLayout1);

		m_hCategory = &(log4cpp::Category::getInstance(std::string(
				pszInstanceName)));
		((log4cpp::Category*) m_hCategory)->addAppender(rollfileAppender);
		((log4cpp::Category*) m_hCategory)->setAdditivity(false);
		try {
			log4cpp::Priority::Value valPriority = log4cpp::Priority::getPriorityValue(pszPriority);
			((log4cpp::Category*) m_hCategory)->setPriority(valPriority);
		} catch (...) {
			std::cout << "Unknown Priority \" " << pszPriority << "\""
					<< std::endl;
		}

	}

	//m_hCategory = log4cpp::Category::exists(std::string(pszInstanceName));

	if (m_hCategory == NULL)
		return false;
	return true;
}


/*! \fn bool CLogRecord::InitLogInstance(const char* pszConfigureFileName, const char* pszInstanceName)
 * \brief 初始化日志实例
 * \param[in]  	pszConfigureFileName
 * \param[in]  	pszInstanceName
 * \return		true: 初始化成功;false:初始化失败
 * \author
 * \date 		2022-02-17
 */
bool CLogRecord::InitLogInstance(const char* pszConfigureFileName, const char* pszInstanceName)
{
	if (m_hCategory == NULL)
    {
		// 1 读取解析配置文件
		// 读取出错, 完全可以忽略,可以定义一个缺省策略或者使用系统缺省策略
		// BasicLayout输出所有优先级日志到ConsoleAppender
		try {
			log4cpp::PropertyConfigurator::configure(pszConfigureFileName);
		} catch (log4cpp::ConfigureFailure& f) {
			//std::cout << "Configure Problem " << f.what() << std::endl;
			return false;
		}

		m_hCategory = log4cpp::Category::exists(std::string(pszInstanceName));

		if (m_hCategory == NULL)
			return false;
	}
	return true;
}

void CLogRecord::LogDebug(const char* pszStringLog, ...) {
	if (m_hCategory) {
		char szTmpBuf[LOG_OPER_MAX_SIZE] = { 0 };
		int offset = 0;
		va_list va;
		va_start(va,pszStringLog);
		vsprintf(szTmpBuf + offset, pszStringLog, va);
		va_end(va);

		((log4cpp::Category*) m_hCategory)->debug(szTmpBuf);
	}
}

void CLogRecord::LogInfo(const char* pszStringLog, ...) {
	if (m_hCategory) {
		char szTmpBuf[LOG_OPER_MAX_SIZE] = { 0 };
		int offset = 0;
		va_list va;
		va_start(va,pszStringLog);
		vsprintf(szTmpBuf + offset, pszStringLog, va);
		va_end(va);

		((log4cpp::Category*) m_hCategory)->info(szTmpBuf);
	}
}

void CLogRecord::LogWarn(const char* pszStringLog, ...) {
	if (m_hCategory) {
		char szTmpBuf[LOG_OPER_MAX_SIZE] = { 0 };
		int offset = 0;
		va_list va;
		va_start(va,pszStringLog);
		vsprintf(szTmpBuf + offset, pszStringLog, va);
		va_end(va);

		((log4cpp::Category*) m_hCategory)->warn(szTmpBuf);
	}
}

void CLogRecord::LogError(const char* pszStringLog, ...) {
	if (m_hCategory) {
		char szTmpBuf[LOG_OPER_MAX_SIZE] = { 0 };
		int offset = 0;
		va_list va;
		va_start(va,pszStringLog);
		vsprintf(szTmpBuf + offset, pszStringLog, va);
		va_end(va);

		((log4cpp::Category*) m_hCategory)->error(szTmpBuf);
	}
}

void CLogRecord::LogFatal(const char* pszStringLog, ...) {
	if (m_hCategory) {
		char szTmpBuf[LOG_OPER_MAX_SIZE] = { 0 };
		int offset = 0;
		va_list va;
		va_start(va,pszStringLog);
		vsprintf(szTmpBuf + offset, pszStringLog, va);
		va_end(va);

		((log4cpp::Category*) m_hCategory)->fatal(szTmpBuf);
	}
}


3、C++调用代码

CLogRecord log_record;
CLogRecord log_record_timer_datatrans;

bool InitLog()
{
  std::string log_config_file_name = "/home/testuser/log/LogSetting.ini"; //can ignore
  std::string log_file_name = "/home/testuser/log/logServer.log";
  std::string log_instance_name = "A1";
  if(!log_record.InitLogInstance(log_config_file_name.c_str(), log_instance_name.c_str()))
  {
    printf("[%s][%s][%d]Log Init Failed", __FILE__, __FUNCTION__ ,__LINE__);
    log_record.SetConfigureFile(log_config_file_name.c_str(), log_instance_name.c_str(), log_file_name.c_str(),10485780,5,"DEBUG");
  }
  log_record.LogDebug("[%s][%s][%d]This is the Log module use example1.", __CLASS__, __FUNCTION__ ,__LINE__);

  log_config_file_name = "/home/testuser/log/LogSetting.ini"; //can ignore
  log_file_name = "/usr/local/Projects/HDMap/HDMAP_database/log/logTimerDataTrans.log";
  log_instance_name = "A2";
  if(!log_record_timer_datatrans.InitLogInstance(log_config_file_name.c_str(), log_instance_name.c_str()))
  {
    printf("[%s][%s][%d]Log Init Failed", __FILE__, __FUNCTION__ ,__LINE__);
    log_record_timer_datatrans.SetConfigureFile(log_config_file_name.c_str(), log_instance_name.c_str(), log_file_name.c_str(),10485780,5,"DEBUG");
  }
  log_record_timer_datatrans.LogDebug("[%s][%s][%d]This is the Log module use example1.", __CLASS__, __FUNCTION__ ,__LINE__);

  return true;
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Adunn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值