【log4cpp】

提示:在使用中可以将log4cpp再度封装,减少重复代码

文章目录

  • 前言
  • 一、log4cpp是什么?
  • 二、安装步骤
  • 三、遇到问题的一些解决办法
    • 一、编译时找不到库
    • 二、运行时找不到库
  • 四、log4cpp码源阅读
  • 五、使用步骤
    • 1.引入库
    • 2.
    • 该做法存在问题
      • 测试效果:
    • 在这里插入图片描述 还有一个坑:对于有引用的成员初始化必须放进初始化列表里
  • 总结


前言

日志系统在整个系统架构中的重要性可以称得上基础的基础,但是这一点,都容易被大多数人所忽视。因为日志在很多人看来只是printf。在系统运行期间,是很难step by step的,所以只能根据系统的运行轨迹来推断错误出现的位置,这往往也是唯一的资料,特别是在高可靠性的情况下。从更大方面的范围来说,日志系统是运营维护的范畴。但小的方面来说,这是必须的调试的手段。从多年的开发经验来看,日志系统是必须被我们重视的。
提示:大概框架
log4cpp的设计:
日志来源 --> Category
日志布局 --> Layout
日志优先级 --> Priority
日志目的地 --> Appender(终端、文件)

1个Category可以对应多个Appender
1个Appender要对应1个Layout

OstreamAppender
FileAppender

RollingFileAppender 回卷文件
BasicLayout
PatternLayout

包含:第三方库log4cpp的使用和一些bug及思考


提示:以下是本篇文章正文内容,下面案例可供参考

一、log4cpp是什么?

Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能。从Log4j中演变而来,4是for的读音,为C++设计。

二、安装步骤

1.下载log4cpp-1.1.1.tar.gz

  1. 安装:先将log4cpp-1.1.1.tar.gz拖入用户主目录(~),
    然后再执行以下步骤:

    $ tar zxvf log4cpp-1.1.1.tar.gz

    $ cd ~/log4cpp/
    $ ./configure
    $ make
    $ make check
    $ sudo make install

      这里已经安装成功.
    

    默认lib库路径是 : /usr/local/lib/

    默认头文件的位置: /usr/local/include/log4cpp

  2. 使用:
    3.1 编译使用log4cpp库的CPP文件时,要加上库文件,才能顺利的编译通过,如下示例

    $ g++ log4test.cpp -llog4cpp -lpthread

    3.2 运行时,如若提示缺少log4cpp库文件,表示找不到log4cpp的动态库,需要进行以下设置
    以管理员身份登录终端,然后执行以下操作:

    a. $ sudo vim /etc/ld.so.conf

    b. 在打开的文件末尾另起一行添加动态库log4cpp的路径(这里是/usr/local/lib),然后保存退出;
    执行命令ldconfig使设置生效即可。
    c. $ sudo ldconfig //更新库文件的缓存信息

  3. log4cpp学习参考
    [http://blog.csdn.net/liuhong135541/article/category/1496383]

三、遇到问题的一些解决办法

一、编译时找不到库

错误产生的原因:1.没有相关的库 2.库名写错了

二、运行时找不到库

找不到动态库
在运行时,找不到动态库。这里涉及到动态库的使用方式:
解决方案:

  1. 先在ld.so.conf文件中添加库所在的路径
  2. 执行以下命令
    $ sudo ldconfig
    这条命令的作用:是将ld.so.conf配置文件
    中的所有路径下的动态库路径一次性全部
    缓存到ld.so.cache文件中
  3. 程序运行时,需要加载动态库路径时,
    会在ld.so.cache文件中加载路径

四、log4cpp码源阅读

源码阅读工具

  1. SlickEdit 跨平台 Windows/Linux/Mac
  2. SourceInsight 公司里用这个 只能在Windows上使用

五、使用步骤

1.引入库

代码如下(示例):

#include 

#include
#include
#include
#include
#include
#include

2.

代码如下(示例):
单例模式,即只能存在一个对象

#define LEN 1024
//

using std::cout;
using std::endl;
using namespace log4cpp;

class Mylogger
{
public:
    static Mylogger *getInstance()
    {
        if (nullptr == _pInstance)
        {
            _pInstance = new Mylogger();
        }
        return _pInstance;
    }
    static void destroy()
    {
        if (_pInstance)
        {
            delete _pInstance;
        }
    }
    void warn(const char *msg){
       module1.warn(msg);
    }
	void error(const char *msg){
        module1.error(msg);
    }
	void debug(const char *msg){
        module1.debug(msg);
    }
	void info(const char *msg){
        module1.info(msg);
    }

private:
    Mylogger()
    :root(Category::getRoot())//对于有引用的必须放进初始化列表里
    ,module1(root.getInstance("register"))
    {
        ptnLayout = new PatternLayout();
        ptnLayout->setConversionPattern("%d [%c] [%p] %m%n");
        
        posAp = new OstreamAppender("console", &cout);
        posAp->setLayout(ptnLayout);

        
        root.setPriority(Priority::DEBUG);
        root.setAppender(posAp);
    }
    ~Mylogger(){
        Category::shutdown();
        }
    static Mylogger *_pInstance;
    PatternLayout *ptnLayout;
    OstreamAppender * posAp;

    Category & root;
    Category & module1;
};

Mylogger *Mylogger::_pInstance=nullptr;
Mylogger *log = Mylogger::getInstance();

inline //建议
void logwarn(const char *msg){
    char packege[LEN]={0};
    sprintf(packege,"%d %s %s %s",__LINE__,__FILE__,__FUNCTION__,msg);
    log->warn(packege);
}
inline
void logerror(const char *msg){
    char packege[LEN]={0};
    sprintf(packege,"%d %s %s %s",__LINE__,__FILE__,__FUNCTION__,msg);
    log->error(msg);
}
inline
void logdebug(const char *msg){
    char packege[LEN]={0};
    sprintf(packege,"%d %s %s %s",__LINE__,__FILE__,__FUNCTION__,msg);
    log->debug(msg);
}
inline
void loginfo(const char *msg){
    char packege[LEN]={0};
    sprintf(packege,"%d %s %s %s",__LINE__,__FILE__,__FUNCTION__,msg);
    log->info(msg);
}
int main(void)
{
    logwarn("The log is warn message");
    logerror("The log is error message");
    logdebug("The log is debug message");
    loginfo("The log is info message");

}

//输出的日志信息中最好能有文件的名字,函数的名字及其所在的行号(这个在C/C++里面有对应的宏,可以查一下)

该做法存在问题

测试效果:

在这里插入图片描述
//这里只出现了一次,所以要将函数定义放进宏里称为宏函数,则可以避免__line__等只能用一次的问题

【log4cpp】_第1张图片
还有一个坑:对于有引用的成员初始化必须放进初始化列表里

总结

提示:这里对文章进行总结:
例如:以上就是今天记录的一些内容,本文仅仅简单介绍了log4cpp的一部分使用.

你可能感兴趣的:(Log4cpp,c++)