可变参数模板——log4cpp

实现log4cpp的封装,使其可以像printf一样使用,测试用例如下:

void test()

       {

              int number = 100;

              const char *pstr = "hello, log4cpp";

              LogInfo("This is an info message. number = %d, str = %s\n", number, pstr);

       }

------------ Mylogger.h------------
#ifndef __MYLOGGER__H__
#define __MYLOGGER__H__
#include <log4cpp/Category.hh>

#define LOGFILENAME "test.log"

using namespace log4cpp;//导入全部log4cpp的全部实体

class Mylogger
{
public:
    static Mylogger *getInstance();
    static void destroy();

    void warn(const char * msg);
    void error(const char * msg);
    void debug(const char * msg);
    void info(const char * msg);
    
    template <class... Args>
    //不能把函数的实现写在Mylogger.cc中
    //和inline一样,函数的实现和声明不能分开,否则会链接失败
    void warn(const char * msg, Args... args)
    {
        _root.warn(msg, args...);
    }

    template <class... Args>
    void error(const char * msg, Args... args)
    {
        _root.error(msg, args...);

    }

    template <class... Args>
    void info(const char * msg, Args... args)
    {
        _root.info(msg, args...);

    }


    template <class... Args>
    void debug(const char * msg, Args... args)
    {
        _root.debug(msg, args...);

    }


private:
    Mylogger();
    ~Mylogger();
private:
    static Mylogger *_pInstance;
    Category &_root; //引用成员必须在构造函数的初始化列表进行初始化,否则会报错

};

//文件名、行号、函数名相关,这里没用到不用管
#define prefic(msg) string(__FILE__).append(" ").append(__FUNCTION__) \
            .append(" ").append(std::to_string(__LINE__))\
                    .append(":").append(msg).c_str()

//##__VA_ARGS__接收可变数目的参数,当宏的调用展开时,实际的参数就传递给函数了
#define logError(msg,...) Mylogger::getInstance()->error(msg,##__VA_ARGS__) 
#define logInfo(msg,...) Mylogger::getInstance()->info(msg,##__VA_ARGS__)
#define logDebug(msg,...) Mylogger::getInstance()->debug(msg,##__VA_ARGS__)
#define logWarn(msg,...) Mylogger::getInstance()->warn(msg,##__VA_ARGS__)
//##的用处:当只有msg参数时,忽略后面的,号

#endif

------------ Mylogger.cc------------
#include "Mylogger.h"
#include <stdlib.h>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>

using std::cout;
using std::endl;

Mylogger * Mylogger::_pInstance=Mylogger::getInstance(); //必须在实现文件中初始化,在头文件中初始化易出现重复定义

Mylogger::Mylogger()
:_root(Category::getRoot().getInstance("Mycat"))  //获得日志记录器,记录器名为Mycat
{
    //设置日志的格式
    //文件格式
    PatternLayout *ppl1 = new PatternLayout();   
    ppl1->setConversionPattern("%d %c [%p] %m %n");

    //终端格式
    PatternLayout *ppl2 = new PatternLayout();
    ppl2->setConversionPattern("%d %c [%p] %m %n");

    //设置日志输出的地点
    //输出到文件
    FileAppender *pfa = new FileAppender("FileAppender123", LOGFILENAME);
    pfa->setLayout(ppl1);

    //输出到输出流对象
    OstreamAppender *poa = new OstreamAppender("OstreamAppender1", &cout);
    poa->setLayout(ppl2);

    //绑定到记录器
    _root.addAppender(poa);
    _root.addAppender(pfa);
    _root.setPriority(Priority::DEBUG);
    
    cout<<"Mylogger()"<<endl;
}

void Mylogger::destroy()//销毁单例对象
{
    if(_pInstance!=nullptr)
    {
        delete _pInstance;
        _pInstance=nullptr;
    }
}
Mylogger *Mylogger::getInstance()//创建单例对象
{
    if(_pInstance==nullptr)
    {
        _pInstance=new Mylogger();
        atexit(destroy);//单例模式自动释放:注册函数,进程结束时自动调用
    }
    return _pInstance;
}

Mylogger::~Mylogger()
{
    cout<<"~Mylogger()"<<endl;
    Category::shutdown();//回收日志资源
}

void Mylogger::info(const char *msg)
{
    _root.info(msg);
}

void Mylogger::error(const char *msg)
{
    _root.error(msg);
}

void Mylogger::warn(const char *msg)
{
    _root.warn(msg);
}

void Mylogger::debug(const char *msg)
{
    _root.debug(msg);
}

------------ test.cc-----------
#include "Mylogger.h"

void test() 
{
    int number = 100;
    const char *pstr = "hello";
    logInfo("This is an info message. number = %d, str = %s\n", number, pstr);
    logWarn("this is a warn message!\n");
    logError("this is a error message! str=%s\n",pstr);
    logDebug("this is a debug message!,number=%d\n",number);
}


int main(int argc,char *argv[])
{
    test();
    return 0;
}

 

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值