Apache log4cxxC++多进程多线程下的使用
1Apache log4cxx介绍
Apache log4cxxApache Logging Services三个日志记录项目之一,完全开源组件。是著名的日志记录组件log4jc++移植版,用于为C++程序提供日志功能,以便开发者对目标程序进行调试和审计。当前的最新版本为0.10.0
2Apache log4cxx 框架组成
Apache Log4cxx有三个关键组件,它们是loggers, appenderslayouts。执行日志操作Loggerlog4cxx的核心类。looger有层次结构,最顶层为RootLoggerlogger是分七个级别,分别是debuginfowarnerrorfatalalloff,最常用的应该是debug()info();而warn()error()fatal()仅在相应事件发生后才使用。每个logger可以附加多个AppenderAppender代表了日志输出的目标,如输出到文件、控制台,数据库等等。对于每一种appender,都可以通过layout进行格式设置,根据自己需求定制不同日志内容。
使用中用到的类有BasicConfiguratorPropertyConfiguratorDOMConfigurator等,用于对lo
g4cxx进行配置。其中BasicConfigurator提供了一种简单配置,包括使用ConsoleAppder作为root appenderPatternLayout作为缺省布局,
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.1microsoft  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小时内删除。