Apache log4cxx在C++多进程多线程下的使用
1、Apache log4cxx介绍
Apache log4cxx是Apache Logging Services三个日志记录项目之一,完全开源组件。是著名的日志记录组件log4j的c++移植版,用于为C++程序提供日志功能,以便开发者对目标程序进行调试和审计。当前的最新版本为0.10.0。
2、Apache log4cxx 框架组成
Apache Log4cxx有三个关键组件,它们是loggers, appenders和layouts。执行日志操作Logger是log4cxx的核心类。looger有层次结构,最顶层为RootLogger;logger是分七个级别,分别是debug、info、warn、error、fatal、all、off,最常用的应该是debug()和info();而warn()、error()、fatal()仅在相应事件发生后才使用。每个logger可以附加多个Appender。Appender代表了日志输出的目标,如输出到文件、控制台,数据库等等。对于每一种appender,都可以通过layout进行格式设置,根据自己需求定制不同日志内容。
使用中用到的类有BasicConfigurator、PropertyConfigurator、DOMConfigurator等,用于对lo
g4cxx进行配置。其中BasicConfigurator提供了一种简单配置,包括使用ConsoleAppder作为root appender和PatternLayout作为缺省布局,
PropertyConfigurator使用properties文件作为配置方式,
DOMConfigurator则使用properties文件作为配置方式,具体配置文档信息请查阅相关资料。
3、多进程多线程使用设计
Apache Log4cxx 提供的常用供日志调用方法,logger->info(),logger->debug(),logger->warn(),logger->error(),与上述方法类似的还有相应的宏调用LOG4CXX_DEBUG()、LOG4CXX_INFO()、LOG4CXX_WARN()、LOG4CXX_ERROR()。每个方法与宏的参数要求是全字符串类型,对于不同的日志信息相应调用不同的日志记录方法,即可得到不同级别、不同类型的日志信息。
配置文件的设置Apache Log4cxx提供
static void configure(helpers::Properties& properties)函数,参数中传入配置文件的绝对路径或是相对路径、文件名, 日志文件名称 Apache Log4cxx提供
static LoggerPtr getLogger(const std::wstring& name);
参数中传入日志文件名,用日志文件名称实例化LoggerPtr对象
LoggerPtr logger(Logger::getLogger(trace)),即可用通过logger对象调用相应类型日志方法,宏调用也在实例化日志对象后才能对设置信息有作用
大家看到了,方法参数要求是一个字符串类型,不便于C++记录日志,也不习惯于C++程序员使用。配置文件与日志文件名设备,都用到了静态方法,多线程共用一个日志对象,每个线程一个日志文件,上述静态方法是不能满足这个需求的,多个进程里面不用的线程调用此方法,每个线程一个日志文件,就更不能满足需求,所以我们必须自己设计一种结构来封装Apache Log4cxx提供的方法,满足多进程多线程下,一个线程一个日志文件的需求。设计一种方便的参数传入模式,使C++程序员能方便使用日志组件提供方法。
我的设计模型如下,用动态库封装日志方法,不同进程、不同线程实例化一个动态库对象,便能解决多进程,多线程生成不同文件问题,用类似sprintf()格式化参数,封装日志方法参数,当然也可以用特定格式来规定日志输出,便能解决方便操作问题,实例化封装类对象,
为了不再引入Apache Log4cxx头文件信息,我提供两个额外的创建实例,销毁实例方法,这样一个完美的日志服务组件就做成了,下面我们来实现这个设想。
4、多进程多线程使用实现
4.1在microsoft Visual C++ 6.0 IDE 上新建一个Win32 Dynamic-Link Library 工程,命名为Trace,选择A simple Dll project,点击Finish一个简单的动态连接库工程就建好了。
4.2 在StdAfx.h文件中包函调用Apache Log4cxx的头文件
#include "logger.h"
#include "PropertyConfigurator.h"
using namespace std;
using namespace log4cxx;
相应的头文件,动态连接库,静态连接库,部分参考文档,请到Apache Log4cxx官方网址ht
tp:/// 下载,官方网址只提供工程文件,相应的动态连接库,静态连接库,需求自己编译得到,具体的编译方法请查阅相关文档。
4.3在工程Trace中新增加一个基础类,命名为CBase用于实现Apache Log4cxx的配置信息,格式化日志文件的输出信息等作用。
Base .h:
#define LOGNAMELNET 100\
class CBase
{
public:
CBase(char * PropertyPath,char * TraceName);
~CBase();
public:
//格式化日志三角输出框
void f_foursquare_sign(char * arg,char *dst);
//格式化日志四角输出框
void f_triangle_sign(char * arg,char *dst);
public:
//日志对象
LoggerPtr m_log;
//日志文件名
char f_c_logname[LOGNAMELNET];
};
Base .cpp:
CBase::CBase(char * PropertyPath,char * TraceName)
{
log4cxx::PropertyConfigurator::configure(PropertyPath); //configure file
this->m_log = Logger::getLogger(TraceName); //appender
//保存日志名称
memset(this->f_c_logname,0,sizeof(this->f_c_logname));
strcpy(this->f_c_logname,TraceName);
}
CBase::~CBase()
{
}
void CBase::f_triangle_sign(char * arg,char *dst)
{
char c_str[100*2];
memset(c_str,0,sizeof(c_str));
strcat(c_str,"<");
strcat(c_str,arg);
strcat(c_str,">-");
strcat(dst,c_str);
}
void CBase::f_foursquare_sign(char * arg,char *dst)
{
char c_str[100*2];
memset(c_str,0,sizeof(c_str));
strcat(c_str,"[");
strcat(c_str,arg);
strcat(c_str,"]-");
strcat(dst,c_str);
}
log4j2不打印日志4.4 增加一个接口类CTraceImpl,向调用者提供接口,这个类只声明接口虚函数,可以直接在项目头文件中实现,额外的创建对象,销毁对象方法也在此声明,实现直接放在项目文件中。
Trace.h:
#ifndef __TRACEIMPL__
#define __TRACEIMPL__
//动态库输出调用约定
#define TRACEFUN __declspec(dllexport)
class TRACEFUN CTraceImpl
{
public:
//重设日志文件名称
virtual void ResetTraceName(char * TraceName) = 0;
public:
//输出Debug日志
virtual void DebugLog(char * CallName,int LogSign,char * StrMsg,...) = 0;
//输出Info日志
virtual void InfoLog (char * EventName,int LogSign,char * StrMsg,...) = 0;
… …
};
//创建实例
TRACEFUN CTraceImpl * CreateTrace(char * PropertyPath = "./log4cxx.properties",char * TraceName = "defilename");
//销毁实例
TRACEFUN void DestroyTrace(CTraceImpl * pCTrace);
#endif // #ifndef __TRACEIMPL__
Trace.cpp:
//创建实例
TRACEFUN CTraceImpl * CreateTrace(char * PropertyPath ,char * TraceName )
{
//创建新对象
return ( new CTrace(PropertyPath,TraceName) );
}
//销毁实例
TRACEFUN void DestroyTrace(CTraceImpl * pCTrace)
{
if (pCTrace)
{
//销毁对象
CTraceImpl* fp = (CTraceImpl *)pCTrace;
delete fp;
}
}
4.5 新增一个实现类CTrace,从CBase, CTraceImpl继承,实现日志方法的封装,参数的格式化:
_Trace.h:
class CTrace:public CBase,public CTraceImpl
{
public:
//默认配置文件名、日志文件名
CTrace(char * PropertyPath ,char * TraceName );
~CTrace();
public:
//重设日志文件名称
virtual void ResetTraceName(char * TraceName);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论