log4cpp日志库的使用

  • 怎样将第三方库安装路径纳入程序搜索路径

    • /etc/profile.d文件夹
      其下脚本会在用户登录时自动执行,具体而言,/etc/profile文件会遍历profile.d文件夹下的所有脚本并执行。

    • LD_LIBRARY_PATH:程序在加载共享库时需要搜索的路径
      因此,要想自动将第三方库安装路径纳入程序搜索路径,就在/etc/profile.d文件夹下写一个脚本文件来实现:

        1. 获取当前LD_LIBRARY_PATH环境变量值
          $LD_LIBRARY_PATH
        1. 增加新路径/usr/local/lib
          LD_LIBRARY_PATH=:$LD_LIBRARY_PATH:/usr/local/lib
        1. 使用export将环境变量值导出,让它对当前shell及其后启动的子进程生效
          export LD_LIBRARY_PATH

      写成一句命令:LD_LIBRARY_PATH=:$LD_LIBRARY_PATH:/usr/local/lib export LD_LIBRARY_PATH

    • 脚本写好后,还需要为它添加执行权限(a+x表示给所有用户加上该文件执行权限)
      chmod a+x /etc/profile.d/log4cpp.sh

  • 使用流程
    编译时-llog4cpp -lpthread
    不要手动释放Category、Appender和Layout,
    它们都由内存管理类自动管理释放,其会找到category下的appender的layout,
    1个appender不要用于多个category,1个layout不要用于多个appender

    头文件:
    #include “log4cpp/Category.hh”
    #include “log4cpp/FileAppender.hh”
    #include “log4cpp/BasicLayout.hh”
    #include “log4cpp/SimpleLayout.hh”

    1. 创建layout、appender、category

      log4cpp::Layout *layout = new log4cpp::SimpleLayout();
      log4cpp::Appender *appender = new log4cpp::FileAppender("FileAppender", "./log_name.log");
      log4cpp::Category& warn_log = log4cpp::Category::getInstance("mywarn");
      
    2. 将layout、category 、appender进行绑定

      appender->setLayout(layout);
      warn_log.setAppender(appender);
      
    3. 设置category优先级
      warn_log.setPriority(log4cpp::Priority::WARN);

    4. 打印日志:日志优先级 不低于 Category的优先级时 才输出
      优先级:debug < info < notice < warn < error < crit < alert

      //两种方法在打印日志时 指定日志优先级
      warn_log.warn("hh");
      warn_log.log(log4cpp::Priority::WARN, "hh");
      
    5. 关闭日志:可以不手动调用,HierarchyMaintainer会在程序结束时自动调用
      log4cpp::Category::shutdown();

  • 布局:输出的信息格式

    • BasicLayout布局:输出 时间戳 消息优先级 消息内容
    • PatternLayout布局:可以自定义输出的信息和内容
      setConversionPattern (const std::string& conversionPattern)
      其中string内容写如下符号:
      符号含义
      %c记录日志的category对象名称
      %d日期,可以用花括号进一步的设置格式。例如%d{%d %m %Y%H:%M:%S,%l}
      %m要输出的日志消息字符串
      %n换行符,会根据平台的不同而不同,但对于用户透明
      %p优先级,warn,debug,info
      %r自从layout被创建后的毫秒数
      %R1970年至今的秒数
      %u进程开始到目前为止的时钟周期数
      %xNDC
  • appender:日志输出到哪些地方
    在new创建appender对象时,使用不同的函数,则日志输出的地方会不同
    例如:

    • 输出到文件
      new log4cpp::FileAppender(...)一直在文件中顺序记录日志
      new log4cpp::RollingFileAppender(...)会在文件长度到达指定值时循环记录日志
    • 输出到标准控制台
      new log4cpp::OstreamAppender(...)
    • 多线程时不要直接输出到标准控制台,否则会中断当前线程,应当输出到内存队列
      new log4cpp::StringQueueAppender(...)
      需要自己从队列中取出日志:appender对象调用getQueue()获得队列对象
  • category
    log4cpp::Category::getRoot()可以得到根Category
    log4cpp::Category::getInstance("sub1")可以得到子Category

  • NDC
    使用NDC来区分当前是哪个线程输出的日志:
    当前线程执行前先push一个标识,执行完再pop。使用get可以获取到当前标识名字

    #include <iostream>
    #include <log4cpp/NDC.hh>
    #include <log4cpp/Category.hh>
    #include "log4cpp/FileAppender.hh"
    #include "log4cpp/BasicLayout.hh"
    void processRequest1(log4cpp::Category& warn_log) {
      log4cpp::NDC::push("Request 1");
      warn_log.warn("processRequest1");
      log4cpp::NDC::pop();
    }
    void processRequest2(log4cpp::Category& warn_log) {
      log4cpp::NDC::push("Request 2");
      warn_log.warn("processRequest2");
      log4cpp::NDC::pop(); 
    }
    int main() {
        log4cpp::Layout *layout = new log4cpp::BasicLayout();
        log4cpp::Appender *appender = new log4cpp::FileAppender("xxx", "./log_name.log");
        log4cpp::Category& warn_log = log4cpp::Category::getInstance("mywarn");
        //绑定
        appender->setLayout(layout);
        warn_log.setAppender(appender);
        //设置优先级
        warn_log.setPriority(log4cpp::Priority::WARN);
        //执行不同程序时,都会打印日志到同一个日志文件
        processRequest1(warn_log);
        processRequest2(warn_log);
        //关闭日志
        log4cpp::Category::shutdown();
        return 0;
    }
    

    运行结果:
    1694957100 WARN mywarn Request 1: processRequest1
    1694957100 WARN mywarn Request 2: processRequest2

  • 使用配置文件来定制日志

    • 配置文件log4cpp.conf:

      #log4cpp配置文件
      #定义Root category的属性
      log4cpp.rootCategory=DEBUG,RootLog 
      #定义RootLog属性:如果使用时获取的category名字这里没定义过,就使用这个默认配置
      log4cpp.appender.RootLog=ConsoleAppender
      log4cpp.appender.RootLog.layout=PatternLayout
      log4cpp.appender.RootLog.layout.ConversionPattern=%d [%p] -%m%n
      
      #定义sample category的属性
      log4cpp.category.sample=DEBUG,sample
      #定义sample属性
      log4cpp.appender.sample=FileAppender#定义一个名为sample的FileAppender
      log4cpp.appender.sample.fileName=sample.log#输出到文件sample.log
      log4cpp.appender.sample.layout=PatternLayout#布局
      log4cpp.appender.sample.layout.ConversionPattern=%d [%p] -%m%n#输出格式
      
      #定义sample.soncategory的属性
      log4cpp.category.sample.son=DEBUG, son
      #定义son的属性
      log4cpp.appender.son=FileAppender
      log4cpp.appender.son.fileName=son.log
      log4cpp.appender.son.layout=PatternLayout
      log4cpp.appender.son.layout.ConversionPattern=%d[%p] - %m%n
      
    • 使用

      #include<iostream>
      #include<log4cpp/Category.hh>
      #include<log4cpp/PropertyConfigurator.hh>
      using namespace log4cpp;
      using namespace std;
      int main(int argc, char *argv[])
      {
          //读取解析配置文件
          log4cpp::PropertyConfigurator::configure("./log4cpp.conf");
          //使用:如果写的是一个配置文件中没有的名字,那么会使用rootCategory默认的配置
          log4cpp::Category & log1 = log4cpp::Category::getInstance(std::string("sample.son"));
          log1.debug("test debug log of son");
          log1.info("test info log of son");
          //关闭
          log4cpp::Category::shutdown();
          return 0;
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值