C++之log4cpp库的使用

  • log4..简介

    log4..是基于log4j的一系列的c++移植版本,使用了log4j的模式结构,目前主要有以下几个版本: 
    1. log4cxx, 目前是到0.10.0版,Apache下的孵化项目,不能独立编译,依赖于APR,编译比较麻烦,2008年以后就没再更新 
    2. log4cplus,目前最新版本是1.2.0,最近一次更新2016-01-16,不依赖于第三方库,下载位置https://sourceforge.net/projects/log4cplus/files/log4cplus-stable/1.2.0/
    3. log4cpp,目前最新版本1.1.2,最近一次更新2016年-08-02,也不依赖与第三方库,与log4cplus功能类似,但是简化了一些实现,增加了一些功能,下载位置https://sourceforge.net/projects/log4cpp/files/?source=navbar

    因为基本结构大致类似,性能上相比也没有明显差别,下面就选择log4cpp进行介绍

    log4cpp基本结构

    log4cpp从大的结构上分为日志类别(Category),日志追加器(Appender),日志布局(Layout),日志级别(Priority)。除此以外还提供了一些帮助类,简化我们对日志的代码设置。

1、Category,日志输出主体类,提供了输出各种日志级别的方法,并且能够设置类别优先级,低于此优先级的类都不再输出,可以有多个分类,但每个应用程序都有一个root分类,其他分类都是root分类的子分类,有点类似于java的单继承结构,子分类的输出同时会输出到父分类中。

// 根分类root
        log4cpp::Category& root = log4cpp::Category::getRoot();
        // 子分类subCat1
        log4cpp::Category& sub1 = log4cpp::Category::getInstance("sub1");

        root.error("test root error");
        root.warn("test root error");
        root.info("test root error");

        sub1.fatal("test sub1 error");
        sub1.notice("test sub1 error");
        sub1.debug("test sub1 error");

  

2、Appender,主要是用来确定日志输出行为,例如输出到哪儿,如何输出。类Appender是由Category来加载的,一个Category可以加载多个Appender,输出到多个地方,一个Appender也可以被多个Category加载,但是有些Appender类没有设置互斥,日志的多线程支持主要是在Category里做的处理,因此不要使用一个Appender加载到多个Category中。

    // OstreamAppender:输出到输出流中(输出到控制台上)
    // FileAppender:输出到文件中
    // RollingFileAppender:输出到文件中并且能够设置文件最大超过多少时生成新文件
    // DailyRollingFileAppender:每天生成一个新文件
    // NTEventLogAppender:将日志输出到Windows事件日志中去
    // ...
    log4cpp::Appender *appender = new log4cpp::FileAppender("test", "D:/log4cppTest/log4cppTest.log");
    root.addAppender(appender);

  

3、Layout,设置日志输出风格,有BasicLayout、SimpleLayout、PatternLayout,其中BasicLayout,SimpleLayout主要是提供的成型的简单日志风格,实际中基本不会使用,主要是使用PatternLayout对日志做格式输出,Layout是加载到Appender中去的。

   // %% 输出一个%
    // %c 输出Categroy名称
    // %d 输出日期
    // %m 输出消息
    // %n 输出换行
    // %p 输出Priority
    // %d{%Y-%m-%d %H:%M:%S:%l}对输出日期做定制,年月日时分秒毫秒
    // %t 线程ID

    log4cpp::PatternLayout *patternLayout = new log4cpp::PatternLayout();
    patternLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} %t [%p] %m %n");
    appender->setLayout(patternLayout);

  

4、Priority,log4cpp有如下几级日志级别

    typedef enum
    {
        EMERG  = 0,     // emergency
        FATAL  = 0,     // fatal
        ALERT  = 100,   // alert
        CRIT   = 200,   // critical
        ERROR  = 300,   // error
        WARN   = 400,   // wanning
        NOTICE = 500,   // notice
        INFO   = 600,   // infomation
        DEBUG  = 700,   // debug
        NOTSET = 800
    } PriorityLevel;

  

其中每个Category都有一个level,低于此高于此level的日志将不会输出,比如Category设置priority为ERROR则,使用此Category输出的WARN,NOTICE等级别的日志都不会输出, 当Category的Priority设置为NOTSET时,该Categroy继承父Category的Priority;每个Appender也可以设置其threshold,当输出日志的Priority的值大于threshold时,此Appender将不会输出此条日志

    // 代码设置
    root.setPriority(log4cpp::Priority::DEBUG);
    appender->setThreshold()

  

1、帮助类, log4cpp主要提供如下几个类来简化代码设置:SimpleConfigurator,BasicConfigurator,PropertyConfigurator,其中SimpleConfigurator和BasicConfigurator,主要是使用代码的方式,进行了一些简单的默认配置,而PropertyConfigurator,是通过配置文件的方式对日志进行配置,也是最常用的,下面就是配置文件的格式:

    #文件名为logTest.Property

    #配置root Category的Priority为DEBUG, Appender为rootAppender
    log4cpp.rootCategory=DEBUG, rootAppender
    #配置子Category sub1的Priority为DEBUG, Appender为A1
    log4cpp.category.sub1=DEBUG, A1 

    #配置rootAppender为FileAppender
    log4cpp.appender.rootAppender=FileAppender
    #配置日志文件名为test1.log,存放在D盘根目录下
    log4cpp.appender.rootAppender.fileName=D:/test1.log
    #配置layout为PatternLayout
    log4cpp.appender.rootAppender.layout=PatternLayout
    #设置日志输出风格
    log4cpp.appender.rootAppender.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S.%l} %t [%p] %m %n

    #配置A1为RollingFileAppender
    log4cpp.appender.A1=RollingFileAppender
    #配置日志文件名为test2.log,存放在D盘根目录下
    log4cpp.appender.A1.fileName=D:/test2.log
    #配置日志文件最大不能超过1M
    log4cpp.appender.A1.maxFileSize=1024 * 1024
    #日志文件最多存储3个文件,超过就会删除旧的
    log4cpp.appender.A1.maxBackupIndex=2
    #设置日志风格
    log4cpp.appender.A1.layout=PatternLayout
    log4cpp.appender.A1.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S.%l} %t [%p] %m %n

    // 代码设置配置文件
    log4cpp::PropertyConfigurator::configure(logTest.Property);

  

代码使用

windows环境下

获取到源代码后,找到源码目录中的msvc10目录,使用VS2010打开msvc10.sln解决方案文件,编译源码获得log4cpp.DLL和log4cpp.lib;在源码目录中有include文件夹,将include整个拷贝到我们的工程目录下,将include添加到工程属性中的附加包含目录中(QT工程则添加到INCLUDEPATH中去),这时就能够正常使用了。

linux环境下

1.下载log4cpp-1.1.1.tar.gz

2. 安装:先将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

3. 使用:
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 //更新库文件的缓存信息

测试用例 

#include <stdio.h>
#include <time.h>
#include <iostream>
#include <boost/circular_buffer.hpp>
#include <thread>
#include <mutex>
#include <vector>

#include <stdio.h>
#include <log4cpp/Category.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/SimpleLayout.hh>
#include "log4cpp/PropertyConfigurator.hh"

using namespace std;
std::mutex g_mutex;  // protects g_i
// 1. circular_buffer 在多线程下是否需要加锁
//    ---- thread1 write
//    ---- thread2 read
//    ---- thread3 write

boost::circular_buffer<int> cb(3);

void thread1_foo()
{
    int i = 0;
    while(i++ < 1000)
    {
        cb.push_back(i);
        {
            lock_guard<std::mutex> lock(g_mutex);
            cout << "thread1 write: " << i << endl;
        }
    }
}

void log_test()
{

    try
    {
        log4cpp::PropertyConfigurator::configure("./log4cpp.conf");
    }
    catch (log4cpp::ConfigureFailure& f)
    {
        std::cout << "Configure Problem " << f.what() << std::endl;

    }

    log4cpp::Category& root = log4cpp::Category::getRoot();
    log4cpp::Category& sub3 = log4cpp::Category::getInstance(std::string("sub3"));

    for(int i = 0; i < 100; i++)
    {
        sub3.fatal("some test");
    }

}

void thread2_foo()
{
    int i = 0;
    while(i++ < 2000)
    {
        if(cb.empty())
        {
            continue;
        }

        int a = cb[0];
        cb.pop_front();

        {

            lock_guard<std::mutex> lock(g_mutex);
            cout<< "thread2 read : "<< a << endl;
        }
    }
}

#define LOGFILE "./test.log"

int main() {
    /*Setting up Appender, layout and Category*/
//    log4cpp::Appender *appender = new log4cpp::FileAppender("FileAppender",LOGFILE);//第一个参数是appender的名字,第二个是log文件的名字
//    log4cpp::Layout *layout = new log4cpp::SimpleLayout();
//    //log4cpp::Layout *layout = new log4cpp::BasicLayout();
//    log4cpp::Category& category = log4cpp::Category::getInstance("abc");
//
//    appender->setLayout(layout);
//    category.setAppender(appender);
//    category.setPriority(log4cpp::Priority::INFO);
//
//    /*The actual logging*/
//    category.info("This is for tracing the flow");
//    category.notice("This is to notify certain events");
//    category.warn("This is to generate certain warnings");
    log_test();
    return 0;
}

  

g++ -std=c++11 -I/usr/local/include  -I/users/jiangxf/3rdParty/boost  -o log_test log_test.cpp liblog4cpp.a
# 定义了3个category sub1, sub2, sub3
# 其中sub2和sub3设置了additivity属性为false;sub1的additivity属性默认为true
rootCategory=DEBUG, rootAppender

category.sub1=,A1

category.sub2=INFO, A2
additivity.sub2=false

category.sub3=ERROR, A3
additivity.sub3=false

# 定义rootAppender类型和layout属性,这里使用了BasicLayout
appender.rootAppender=org.apache.log4cpp.ConsoleAppender
appender.rootAppender.layout=org.apache.log4cpp.BasicLayout

#定义A1的属性,  这里使用了  SimpleLayout
appender.A1=org.apache.log4cpp.FileAppender
appender.A1.fileName=./log/A1.log
appender.A1.layout=org.apache.log4cpp.SimpleLayout

#定义A2的属性,这里使用了  PatternLayout
appender.A2=org.apache.log4cpp.ConsoleAppender
appender.A2.layout=org.apache.log4cpp.PatternLayout
appender.A2.layout.ConversionPattern=The message ‘%m‘ at time %d%n

#定义A3的属性
#appender.A3=org.apache.log4cpp.RollingFileAppender
appender.A3=org.apache.log4cpp.ConsoleAppender
appender.A3.fileName=./log/A3.log
appender.A3.maxFileSize=50
appender.A3.maxBackupIndex=3
appender.A3.backupPattern=%Y-%m-%d
appender.A3.layout=org.apache.log4cpp.PatternLayout
#appender.A3.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} [%p]: [%c] %m%n
appender.A3.layout.ConversionPattern=%d,%p,%m%n
#%c sub3
#%p fatal
#%m 日志内容
#%n 回车换行

  

log4cpp学习
http://blog.csdn.net/liuhong135541/article/category/1496383

原文地址:https://www.cnblogs.com/cthon/p/9192787.html

时间: 2024-10-17 00:19:41

C++之log4cpp库的使用的相关文章

log4cpp 日志库

说明 log4cpp编译安装的路径是/opt/log4cpp 问题:如何正确引入动态库 1.修改/etc/ld.so.conf文件,将/opt/log4cpp/lib添加到文件末尾,该文件主要被ldconfig指令用来搜索可共享的动态链接库 2.执行ldconfig,根据修改的文件内容,创建出动态装入程序所需的连接和缓存文件,提供给系统动态库调用 手动: g++ test.cpp -I/opt/log4cpp/include -L/opt/log4cpp/lib/ -llog4cpp -lpth

Log4cpp介绍及使用

Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能.使用log4cpp,能够非常便利地将日志或者跟踪调试信息写入字符流.内存字符串队列.文件.回滚文件.调试器.Windows日志.本地syslog和远程syslogserver中. 1.Log4cpp简单介绍 Log4cpp是个基于LGPL的开源项目,移植自Java的日志处理跟踪项目log4j,并保持了API上的一致.其类似的支持库还包含Java(log4j),C++(log4cpp.log4cplus),C(l

log4cpp 用法

1 windows环境 1.1创建一个日志模板 staticbool bFirst = true; Logger_logger = Logger::getInstance(LOG4CPLUS_TEXT("thriftserver")); if(bFirst) { SharedAppenderPtr_append(new RollingFileAppender(LOG4CPLUS_TEXT("thriftserver.log"),300 * 1024, 20)); a

CMake快速入门教程-实战

http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/details/6314073 http://www.cnblogs.com/coderfenghc/archive/2013/01/20/2846621.html http://blog.sina.com.cn/s/blog_4aa4593d0100q3bt.html http://hahack.com/c

CMake快速入门教程:实战

转自http://blog.csdn.net/ljt20061908/article/details/11736713 0. 前言    一个多月前,由于工程项目的需要,匆匆的学习了一下cmake的使用方法,现在有时间拿出来整理一下.本文假设你已经学会了cmake的使用方法,如果你还不会使用cmake,请参考相关资料之后再继续向下看.    本文中介绍的是生成可执行程序的方法和步骤,生成动态库和静态库的方法与此有所不同,随后会介绍动态库和静态库项目中cmake的编写方法.    本文参考<CMa

C++开源跨平台类库集

在如下的库支持下,开发的系统可以很方便移植到当前大部分平台上运行而无需改动,只需在对应的平台下 用你喜欢的编译器 重新编译即可 经典的C++库   STLport-------SGI STL库的跨平台可移植版本,在以前有些编译器离符合         标准比较远的情况下 那时还是有用的,当然目前vc71已经比较接近标准了,         故目前不怎么用它了.   Boost---------准标准库, 功能强大 涉及能想的到的大部分非特别领域的算法,         有一个大的C++社区支持 

转:CMake快速入门教程-实战

CMake快速入门教程:实战 收藏人:londonKu     2012-05-07 | 阅:10128  转:34    |   来源   |  分享      0. 前言一个多月前,由于工程项目的需要,匆匆的学习了一下cmake的使用方法,现在有时间拿出来整理一下.本文假设你已经学会了cmake的使用方法,如果你还不会使用cmake,请参考相关资料之后再继续向下看.本文中介绍的是生成可执行程序的方法和步骤,生成动态库和静态库的方法与此有所不同,随后会介绍动态库和静态库项目中cmake的编写方

C/C++框架和库 (真的很强大) 转

http://blog.csdn.net/xiaoxiaoyeyaya/article/details/42541419 值得学习的C语言开源项目 - 1. Webbench Webbench是一个在Linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力.Webbench使用C语言编写, 代码实在太简洁,源码加起来不到600行. 下载链接:http://home.tiscali

值得推荐的C/C++框架和库(深度好文)

[本文系外部转贴,原文地址:http://www.cppblog.com/merlinfang/archive/2014/12/26/209311.html http://coolshell.info/c/c++/2014/12/13/c-open-project.htm]留作存档 公交车上看到的好文,忍不住转发!下次造轮子前先看看现有的轮子吧-- 值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客