C++学习笔记05

今天主要讲了C++的log4cpp库

概述

Log4cpp是个基于LGPL的开源项目,移植自Java的日志处理跟踪项目log4j,并保持了API上的一致。其类似的支持库还包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等。(摘自百度百科)
简言之,log4cpp可以理解为一个日志管理系统。

主要部件

  • 记录器 Category
  • 过滤器 日志优先级,详情见下文
  • 格式化器 Layout
  • 输出器 Appender:OstreamAppender,FileAppender,RollingAppender

Priority

结构体定义如下,其中数值越小,表示优先级越高,当日志信息的优先级高于设定的优先级时,该条信息才会被处理,否则丢弃

 typedef enum {EMERG  = 0, 
          FATAL  = 0,
          ALERT  = 100,
          CRIT   = 200,
          ERROR  = 300, 
          WARN   = 400,
          NOTICE = 500,
          INFO   = 600,
          DEBUG  = 700,
          NOTSET = 800
} PriorityLevel;

Category

可使用Category::getRoot()得到根Category,一般情况下,一个程序只需一个根Category,负责向日志中写入信息

Appender

负责制定日志的目的地,以下代码分别把日志信息写入到标准输出cout和文件tmp_log.txt中

OstreamAppender *ostreamAppender = new OstreamAppender("ostreamAppender", &cout);
FileAppender *fileAppender = new FileAppender("fileAppender", "tmp_log.txt");

PatternLayout

创建一个PatternLayout后,可以使用setConversionPattern方法来设置日志的输出格式,以下摘录自官方手册 log4cpp Documentation

Format characters are as follows:
%%%% - a single percent sign
%c - the category
%d - the date
Date format: The date format character may be followed by a date format specifier enclosed between braces. For example, %d{%H:%M:%S,%l} or %d{%d %m %Y %H:%M:%S,%l}. If no date format specifier is given then the following format is used: "Wed Jan 02 02:03:55 1980". The date format specifier admits the same syntax as the ANSI C function strftime, with 1 addition. The addition is the specifier %l for milliseconds, padded with zeros to make 3 digits.
%m - the message
%n - the platform specific line separator
%p - the priority
%r - milliseconds since this layout was created.
%R - seconds since Jan 1, 1970
%u - clock ticks since process start
%x - the NDC

下述代码即可设置日志输出格式为:日期 category [优先级] 消息 换行符

PatternLayout *p1 = new PatternLayout();
p1->setConversionPattern("%d %c [%p] %m%n");

运行

log->error("this is a error");

结果

2019-07-27 23:13:33,412  [ERROR] this is a error

shutdown()

使用完毕后最好使用Category::shutdown()进行内存清理,但即使不手动调用,程序结束时也会自动调用Category的析构函数进行清理。

自己封装的log4cpp类

#include <log4cpp/Category.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/Appender.hh>

#include <iostream>
#include <string>
using namespace std;
using namespace log4cpp;

/*  • __LINE__:在源代码中插入当前源代码行号
    • __FILE__:在源文件中插入当前源文件名
    • __FUNCTION__:函数名
    • __DATE__:在源文件中插入当前的编译日期
    • __TIME__:在源文件中插入当前编译时间    */

//定义一个宏,以输出日志信息所在的文件名,函数名和所在行
#define getinfo(msg) (string(msg).append(" [").append(__FILE__).append(" ").\
        append(__FUNCTION__).append(":").append(to_string(__LINE__)).append("]")).c_str()

class Mylogger
{
public:
    static Mylogger *getstance()
    {
        if (_pinstance == nullptr)
            _pinstance = new Mylogger();
        return _pinstance;
    }
    void destory()
    {
        if (_pinstance)
            delete _pinstance;
        _pinstance = nullptr;
    }
    void warn(const char *msg);
    void error(const char *msg);
    void debug(const char *msg);
    void info(const char *msg);

private:
    Mylogger();
    ~Mylogger();
    PatternLayout *_p1;
    PatternLayout *_p2;
    OstreamAppender *_ostreamAppender;
    FileAppender *_fileAppender;
    Category &_root;
    static Mylogger *_pinstance;
};

Mylogger* Mylogger::_pinstance = nullptr;

Mylogger::Mylogger()
    : _p1(new PatternLayout())
    , _p2(new PatternLayout())
    , _ostreamAppender(new OstreamAppender("ostreamAppender", &cout))
    , _fileAppender(new FileAppender("fileAppender", "log.txt"))
    , _root(Category::getRoot())
{
    _p1->setConversionPattern("%d %c [%p] %m%n");
    _p2->setConversionPattern("%d %c [%p] %m%n");
    _ostreamAppender->setLayout(_p1);
    _fileAppender->setLayout(_p2);
    cout << "nihao" << endl;
    _root.setPriority(Priority::DEBUG);
    _root.addAppender(_ostreamAppender);
    _root.addAppender(_fileAppender);
    //Category::shutdown();
}

Mylogger::~Mylogger()
{
    Category::shutdown();
    cout << "析构函数" << endl;
}

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

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

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

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

int main(int argc, char *argv[])
{
    Mylogger *p = Mylogger::getstance();
    p->warn(getinfo("warn"));
    p->error(getinfo("error"));
    p->debug(getinfo("debug"));
    p->info(getinfo("info"));
    p->destory();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值