logcpp4的几种日志的各种写法以及实践。

Log4cpp使

Log4cpp中最重要念有Category种类Appender附加器Layout布局Priorty优先 NDC套的诊上下

CategoryAppenderLayout的关系如图所示

 

 

 

载地址https://sourceforge.net/projects/log4cpp/files/latest/download    载的是 log4cpp-1.1.3.tar.gz

解压

tar zxf log4cpp-1.1.3.tar.gz 编译

cd log4cpp
./configure
make
make check
sudo make install

 

RollingFileAppender.cpp

 

/*
FileAppender和RollingFileAppender是log4cpp中最常用的两个Appender,其功能是将日志写入文件中。
它们之间唯一的区别就是前者会一直在文件中记录日志(直到操作系统承受不了为止),而后者会在文件长度到
达指定值时循环记录日志,文件长度不会超过指定值(默认的指定值是10M byte)。

FileAppender的创建函数如下:
FileAppender(const std::string& name, const std::string& fileName,
                bool append = true, mode_t mode = 00644);


一般仅使用前两个参数,即“名称”和“日志文件名”。第三个参数指示是否在日志文件后继续记入日志,
还是清空原日志文件再记录。第四个参数说明文件的打开方式。

RollingFileAppender的创建函数如下:
RollingFileAppender(const std::string& name, 
                        const std::string& fileName,
                        size_t maxFileSize = 10*1024*1024, 
                        unsigned int maxBackupIndex = 1,
                        bool append = true,
                        mode_t mode = 00644);


它与FileAppender的创建函数很类似,但是多了两个参数:maxFileSize指出了回滚文件的最大值;
maxBackupIndex指出了回滚文件所用的备份文件的最大个数。所谓备份文件,是用来保存回滚文件中
因为空间不足未能记录的日志,备份文件的大小仅比回滚文件的最大值大1kb。所以如果maxBackupIndex取值为3,
则回滚文件(假设其名称是rollwxb.log,大小为100kb)会有三个备份文件,
其名称分别是rollwxb.log.1,rollwxb.log.2和rollwxb.log.3,大小为101kb。
另外要注意:如果maxBackupIndex取值为0或者小于0,则回滚文件功能会失效,其表现如同FileAppender一样,
不会有大小的限制。
*/
#include <iostream>
#include <sys/time.h>

#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/RollingFileAppender.hh>
using namespace std;

static uint64_t get_tick_count()
{
    struct timeval tval;
    uint64_t ret_tick;
    
    gettimeofday(&tval, NULL);
    
    ret_tick = tval.tv_sec * 1000L + tval.tv_usec / 1000L;
    return ret_tick;
}

// g++ -o RollingFileAppender RollingFileAppender.cpp -llog4cpp -lpthread
int main(int argc, char* argv[])
{
    log4cpp::TimeStamp time;
    log4cpp::PatternLayout* pLayout1 = new log4cpp::PatternLayout();
     log4cpp::BasicLayout* pBasicLayout = new log4cpp::BasicLayout();
    //  2020-06-21 17:36:01,946: ERROR  RootName : 0:Root Error Message!
    //  %d: 2020-06-21 17:36:01,946: 
    //  %p ERROR  
    //  %c RootName : 0
    //  %m:Root Error Message!
    // pLayout1->setConversionPattern("%d: %p %c %x: %m%n");
    // 2020-06-21 17:40:34,772: ERROR RootName: 10Root Error Message!
    // pLayout1->setConversionPattern("%d: %p %c: %m%n");
    // 2020-06-21 17:41:41,369: ERROR : 0Root Error Message!
    pLayout1->setConversionPattern("%d: %p %c %x: %m%n");

    log4cpp::PatternLayout* pLayout2 = new log4cpp::PatternLayout();
    pLayout2->setConversionPattern("%d: %p %c %x: %m%n");
    
    log4cpp::Appender* fileAppender = new log4cpp::FileAppender("fileAppender","FileAppender.log",
                        false);
    fileAppender->setLayout(pLayout1);

    log4cpp::RollingFileAppender* rollfileAppender = new log4cpp::RollingFileAppender(
        "rollfileAppender","RollingFileAppender.log",500*1024,5, false);
    rollfileAppender->setLayout(pLayout2);
    
    log4cpp::Category& root = log4cpp::Category::getRoot().getInstance("RootName");
    // root.addAppender(fileAppender);
    root.addAppender(rollfileAppender);
    root.setPriority(log4cpp::Priority::DEBUG);

    uint64_t begin_time = get_tick_count();
    std::cout << "begin_time: " << begin_time << std::endl;
    for (int i = 0; i < 10000; i++)
    {
        string strError;
        ostringstream oss;
        oss<<"NO." << i<<" Root Error Message!";    // 47个字节
        strError = oss.str();
        root.error(strError);
    }
    uint64_t end_time = get_tick_count();
    std::cout << "end_time: " << end_time << std::endl;
    std::cout << "need the time1: " << end_time << " " << begin_time << ", " << end_time - begin_time << "毫秒\n" ;
    log4cpp::Category::shutdown();
    end_time = get_tick_count();
    std::cout << "need the time2: " << end_time - begin_time << "毫秒\n" ;
    return 0;
}

StringQueueAppender.CPP 

/*
StringQueueAppender的功能是将日志记录到一个字符串队列中,该字符串队列使用了STL中的两个容器,
即字符串容器std::string和队列容器std::queue,具体如下:
std::queue<std::string> _queue;
_queue变量是StringQueueAppender类中用于具体存储日志的内存队列。StringQueueAppender的使用方法
与OstreamAppender类似,其创建函数只接收一个参数“名称”,记录完成后需要程序员自己从队列中取出每条日志
*/
#include <iostream>
#include <sys/time.h>
#include <log4cpp/Category.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/StringQueueAppender.hh>

using namespace std;
static uint64_t get_tick_count()
{
    struct timeval tval;
    uint64_t ret_tick;
    
    gettimeofday(&tval, NULL);
    
    ret_tick = tval.tv_sec * 1000L + tval.tv_usec / 1000L;
    return ret_tick;
}
// g++ -o StringQueueAppender StringQueueAppender.cpp -llog4cpp -lpthread
int main(int argc, char* argv[])
{
     log4cpp::StringQueueAppender* strQAppender = new log4cpp::StringQueueAppender("strQAppender");
    strQAppender->setLayout(new log4cpp::BasicLayout());
    
    log4cpp::Category& root = log4cpp::Category::getRoot();
    root.addAppender(strQAppender);
    root.setPriority(log4cpp::Priority::DEBUG);
    
    root.error("Hello log4cpp in a Error Message!");
    root.warn("Hello log4cpp in a Warning Message!");
    
    cout<<"Get message from Memory Queue!"<<endl;
    cout<<"-------------------------------------------"<<endl;

    uint64_t begin_time = get_tick_count();
    std::cout << "begin_time: " << begin_time << std::endl;
    for (int i = 0; i < 100000; i++)
    {
        string strError;
        ostringstream oss;
        oss<<"NO." << i<<" Root Error Message!";        // 47字节 * 10000 = 470000=470k
        strError = oss.str();
        root.error(strError);
    }
    uint64_t end_time = get_tick_count();
    std::cout << "end_time: " << end_time << std::endl;
    std::cout << "need the time1: " << end_time << " " << begin_time << ", " << end_time - begin_time << "毫秒\n" ;

    queue<string>& myStrQ = strQAppender->getQueue();
    std::string bufString;
    int bufCount = 0;

     begin_time = get_tick_count();
    std::cout << "begin_time: " << begin_time << std::endl;
    FILE *file = fopen("StringQueueAppender.log", "wt");
    while(!myStrQ.empty())
    {
        // cout<<myStrQ.front();
        // std::cout << "append\n";
        bufString.append(myStrQ.front().c_str(), myStrQ.front().size());
        // std::cout << "append2\n";
        if(bufCount++ >= 100000) 
        {
            bufCount = 0;
            // std::cout << myStrQ.front() << std::endl;
            fwrite(bufString.c_str(), bufString.size(), 1, file);
            bufString.clear();
        }
        myStrQ.pop();
    }
    fwrite(bufString.c_str(), bufString.size(), 1, file);
    fclose(file);
    end_time = get_tick_count();
    std::cout << "need the time1: " << end_time << " " << begin_time << ", " << end_time - begin_time << "毫秒\n" ;
    log4cpp::Category::shutdown();    
    return 0;
}
test_log4cpp1.CPP

 

 

// FileName: test_log4cpp1.cpp
#include "log4cpp/Category.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/BasicLayout.hh"

//g++ -o test_log4cpp1 test_log4cpp1.cpp -llog4cpp -lpthread

int main(int argc, char *argv[])
{
    // 1实例化一个layout 对象
    log4cpp::Layout *layout = new log4cpp::BasicLayout();   // 有不同的layout
    // 2. 初始化一个appender 对象
    log4cpp::Appender *appender = new log4cpp::FileAppender("FileAppender",
     "./test_log4cpp1.log");
    log4cpp::Appender *osappender = new log4cpp::OstreamAppender("OstreamAppender",
        &std::cout);
    // 3. 把layout对象附着在appender对象上
    appender->setLayout(layout);
    // appender->addLayout 没有addLayout,一个layout格式样式对应一个appender
    // 4. 实例化一个category对象
    log4cpp::Category &warn_log =
        log4cpp::Category::getInstance("darren");   // 是一个单例工厂
    // 5. 设置additivity为false,替换已有的appender
    warn_log.setAdditivity(false);
    // 5. 把appender对象附到category上
    warn_log.setAppender(appender);
    warn_log.addAppender(osappender);
    // 6. 设置category的优先级,低于此优先级的日志不被记录
    warn_log.setPriority(log4cpp::Priority::INFO);
    // 记录一些日志
    warn_log.info("Program info which cannot be wirten, darren = %d", 100);
    warn_log.debug("This debug message will fail to write");
    warn_log.alert("Alert info");
    // 其他记录日志方式
    warn_log.log(log4cpp::Priority::WARN, "This will be a logged warning, darren = %d", 100);


    log4cpp::Priority::PriorityLevel priority;
    bool this_is_critical = true;
    if (this_is_critical)
        priority = log4cpp::Priority::CRIT;
    else
        priority = log4cpp::Priority::DEBUG;
    warn_log.log(priority, "Importance depends on context");

    warn_log.critStream() << "This will show up << as "
                          << 1 << " critical message";
    // clean up and flush all appenders
    log4cpp::Category::shutdown();
    return 0;
}

才配置文件形式来写日志文件

test_log4cpp2.conf

# 文件名: test_log4cpp2.conf
# a simple test config
#定义了3个category sub1, sub2, sub1.sub2
log4j.rootCategory=DEBUG, rootAppender
log4j.category.sub1=,A1
log4j.category.sub2=INFO
#log4j.category.sub1.sub2=ERROR, A2
log4j.category.sub1.sub2=, A2
# 设置sub1.sub2 的additivity属性
log4j.additivity.sub1.sub2=true
#定义rootAppender类型和layout属性
log4j.appender.rootAppender=org.apache.log4j.ConsoleAppender
log4j.appender.rootAppender.layout=org.apache.log4j.BasicLayout
#定义A1的属性
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.fileName=A1.log
log4j.appender.A1.layout=org.apache.log4j.SimpleLayout
#定义A2的属性
log4j.appender.A2=org.apache.log4j.ConsoleAppender
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
#log4j.appender.A2.layout.ConversionPattern=The message '%m' at time %d%n
log4j.appender.A2.layout.ConversionPattern=%d %m %n
test_log4cpp2.cpp

 

// FileName: test_log4cpp2.cpp
// Test log4cpp by config file.
#include "log4cpp/Category.hh"
#include "log4cpp/PropertyConfigurator.hh"

//g++ -o test_log4cpp2 test_log4cpp2.cpp -llog4cpp -lpthread
int main(int argc, char* argv[])
{
    // 1 读取解析配置文件
    // 读取出错, 完全可以忽略,可以定义一个缺省策略或者使用系统缺省策略
    // BasicLayout输出所有优先级日志到ConsoleAppender
    try { 
        log4cpp::PropertyConfigurator::configure("./test_log4cpp2.conf");
    } catch(log4cpp::ConfigureFailure& f) {
        std::cout << "Configure Problem " << f.what() << std::endl;
        return -1;
    }
     
    // 2 实例化category对象
    // 这些对象即使配置文件没有定义也可以使用,不过其属性继承其父category
    // 通常使用引用可能不太方便,可以使用指针,以后做指针使用
    // log4cpp::Category* root = &log4cpp::Category::getRoot();
    log4cpp::Category& root = log4cpp::Category::getRoot();
     
    log4cpp::Category& sub1 = 
        log4cpp::Category::getInstance(std::string("sub1"));
    log4cpp::Category& sub3 = 
        log4cpp::Category::getInstance(std::string("sub1.sub2"));
    // 3 正常使用这些category对象进行日志处理。
    // sub1 has appender A1 and rootappender.
    sub1.info("This is some info");
    sub1.alert("A warning");
     
    // sub3 only have A2 appender.
    sub3.debug("This debug message will fail to write");
    sub3.alert("All hands abandon ship");
    sub3.critStream() << "This will show up << as " << 1 << " critical message";
    sub3 << log4cpp::Priority::ERROR 
              << "And this will be an error";
    sub3.log(log4cpp::Priority::WARN, "This will be a logged warning");
     // clean up and flush all appenders
    log4cpp::Category::shutdown();
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值