C++日志库plog使用指南

前言

  • 之前介绍过一个C语言日志库 轻量级c语言开源日志库log.c介绍,源代码只有不到200行,使用非常方便。
  • 但是也存在很多缺点,比如日志时间只支持打印到秒,没有作多线程处理,不支持日志回滚。在小型项目或者测试demo中使用还可以,在大型项目中,就无法满足需求了。
  • 于是又找到了一个C++日志库plog,虽然代码量较多,但使用也非常简单,并且功能非常强大,可以满足在大型项目中的使用需求。

plog简介

  • plog 是一个轻量级、跨平台的C++日志库,它设计简洁且易于使用。有以下特点
    • 简单易用: plog 提供了直观的API,允许开发者以简洁的方式在代码中添加日志记录功能。例如,通过LOGD, LOGI, LOGW, LOGE等宏定义来分别表示不同级别的日志输出(如debug、info、warning和error)。
    • 多线程支持: plog 设计为线程安全的,可以安全地在多线程环境下使用,确保各个线程的日志记录不会相互干扰。
    • 多种日志级别: 支持多种日志级别,可以根据需要调整输出的日志详细程度,只显示重要信息或者包括所有调试细节。
    • 文件回滚与滚动日志: plog 允许配置日志文件的大小限制和循环策略,当达到一定大小时会自动创建新的日志文件,以实现日志的滚动存储。
    • 异步/同步日志写入: 可以根据需求选择同步或异步的方式来写入日志,提高程序性能,尤其是在大量日志产生时。
    • 可扩展性: plog 提供了自定义appender的能力,用户可以创建自己的日志接收器,将日志输出到各种不同的目标,如文件、数据库、网络等。
    • 跨平台兼容: plog 能够在多个操作系统和编译器下运行,如Windows、Linux、macOS等,并且兼容多种C++标准。
    • 体积小巧: plog 的源代码量小,占用资源少,适合嵌入式系统或其他对体积敏感的应用场景

使用步骤

  • 下载源代码后,将根目录下include目录下的所有文件拷贝到我们自己的工程下,然后在工程中包含对应的头文件即可。

使用示例

基本功能

  • 通过一个示例演示下基本功能。
  • 测试代码 : main.cpp
  •   #include <plog/Log.h> // Step1: include the header.
      #include <plog/Initializers/RollingFileInitializer.h>
      #include <plog/Appenders/ColorConsoleAppender.h>
      #include <string.h>
      #include <iostream>
      #include <iomanip>
      
      
      void polgFunc(){
      	PLOG_DEBUG << "DEBUG join polgFunc func";
      	PLOG_INFO << "DEBUG join polgFunc func";
      	PLOG_ERROR << "DEBUG join polgFunc func";
      }
      
      int main()
      {
          // 日志初始化
          // 参数1 - 日志级别, 参数2 - 日志文件名, 参数3 - 单个日志大小, 参数4 - 日志回滚数
          // 如果不想实现日志回滚,参数3和参数4可以不填或者填0
          plog::init(plog::info, "plog.log", 1024, 5);
      
          // 同时打印到控制台
          plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender;
          plog::get()->addAppender(&consoleAppender); // Also add logging to the console.
      
      
          int iData = 10020;
          double fData = 3.141592654; 
          std::string sData = "hello plog";
      
          PLOG_DEBUG << "debug hello log!"; 
          LOG_INFO << "info hello log!";
          PLOG_WARNING << "warning hello log!";
          PLOG_ERROR << "error hello log!";
      
          PLOG_INFO << "int data : " << iData;
          PLOG_INFO << "int hex data : " << std::hex << iData;
          
          PLOG_INFO << "float data : " << fData;
          PLOG_INFO << "float data : " << std::fixed << std::setprecision(2) << fData;
      
          PLOG_INFO << "string data : " << fData;
      
          polgFunc();
      
          system("pause");
          return 0;
      }
    
  • 控制台打印
    在这里插入图片描述
  • 文件打印:在当前目录下会生成一个 plog.log 文件
    在这里插入图片描述
  • 日志回滚 : 文件超出我们设置的大小后,可以自动回滚
    在这里插入图片描述

进阶功能 - 自定义日志打印格式

  • 对测试代码进行修改 main.cpp
  •   #include <plog/Log.h> // Step1: include the header.
      #include <plog/Initializers/RollingFileInitializer.h>
      #include <plog/Appenders/ColorConsoleAppender.h>
      #include <string.h>
      #include <iostream>
      #include <iomanip>
      
      // 自定义日志格式器
      namespace plog
      {
          class MyFormatter
          {
          public:
              static util::nstring header() // This method returns a header for a new file. In our case it is empty.
              {
                  return util::nstring();
              }
      
              static util::nstring format(const Record& record) // This method returns a string from a record.
              {
                  util::nostringstream ss;
                  util::Time t;
                  t.time = record.getTime().time;
                  struct tm *ltime = localtime(&t.time);
                  t.millitm = record.getTime().millitm;
                  // 在这里设置日志打印的格式
                  ss << "[plog] ["<<ltime->tm_year + 1900 <<"/"<< std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_mon + 1 <<"/"<< std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_mday << "_";
                  ss << std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_hour << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_min << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_sec << ".";
                  ss << std::setfill(PLOG_NSTR('0')) << std::setw(3) <<t.millitm << "] ";
                  ss << std::setw(5) << std::left << std::setfill(PLOG_NSTR(' ')) <<severityToString(record.getSeverity()) <<" [" << record.getTid()<< "]"<<" [" << record.getFunc() << ":" << record.getLine() << "] " << record.getMessage() << "\n";
                  return ss.str();
              }
          };
      }
      
      
      void polgFunc(){
      	PLOG_DEBUG << "DEBUG join polgFunc func";
      	PLOG_INFO << "DEBUG join polgFunc func";
      	PLOG_ERROR << "DEBUG join polgFunc func";
      }
      
      int main()
      {
          // 日志初始化
          // 参数1 - 日志级别, 参数2 - 日志文件名, 参数3 - 单个日志大小, 参数4 - 日志回滚数
          // 如果不想实现日志回滚,参数3和参数4可以不填或者填0
          // plog::init(plog::info, "plog.log", 1024, 5);
          plog::init<plog::MyFormatter>(plog::info, "plogformat.log", 1024, 5); 
      
          // 同时打印到控制台
          plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender;
          plog::get()->addAppender(&consoleAppender); // Also add logging to the console.
      
      
          int iData = 10020;
          double fData = 3.141592654; 
          std::string sData = "hello plog";
      
          PLOG_DEBUG << "debug hello log!"; 
          LOG_INFO << "info hello log!";
          PLOG_WARNING << "warning hello log!";
          PLOG_ERROR << "error hello log!";
      
          PLOG_INFO << "int data : " << iData;
          PLOG_INFO << "int hex data : " << std::hex << iData;
          
          PLOG_INFO << "float data : " << fData;
          PLOG_INFO << "float data : " << std::fixed << std::setprecision(2) << fData;
      
          PLOG_INFO << "string data : " << fData;
      
          polgFunc();
      
          system("pause");
          return 0;
      }
    
  • 文件打印:再运行看下文件中的打印
    在这里插入图片描述
  • 可以看到,打印的格式就是我们自定义的格式。

在线程中打印

  • 可以在线程中打印

  • main.cpp

  •   #include <plog/Log.h> 
      #include <plog/Initializers/RollingFileInitializer.h>
      #include <string.h>
      #include <iostream>
      #include <windows.h>
      #include <process.h>
      
      unsigned int __stdcall ThreadFun(PVOID lpParam) {
      	PLOG_DEBUG << "debug ThreadFun!";
      	LOG_INFO << "info ThreadFun!";
      	PLOG_WARNING << "warning ThreadFun!";
      	PLOG_ERROR << "error ThreadFun!";
      
      	return 0;
      }
      
      int main()
      {
      	plog::init(plog::info, "plog.log", 1024, 5);
      
      	HANDLE handle1 = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);
      	HANDLE handle2 = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);
      	HANDLE handle3 = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);
      
      	system("pause");
      	return 0;
      }
    
    
  • 打印结果
    在这里插入图片描述

  • 可以看到不同线程中的线程id

在多个文件中打印

  • 多个文件中如何打印呢?只需要通过 plog::init 在程序入口处初始化,然后在其他文件中包含 #include <plog/Log.h> 头文件直接通过 PLOG_INFO 打印即可,不需要传任何参数,使用非常方便。这里就不演示了。
  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值