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;
      }
    
  • 文件打印:再运行看下文件中的打印
    在这里插入图片描述
  • 可以看到,打印的格式就是我们自定义的格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/402304.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot-helloworld

1. helloworld 使用springboot完成一个简单的web应用&#xff0c;当访问/hello时&#xff0c;返回"hello springboot"字符串。 首先&#xff0c;创建一个maven工程&#xff0c;并引入依赖。 <!--使用springboot编写web应用前&#xff0c;需要声明父工程spring-b…

Cent OS 7 无线网连接

环境&#xff1a;小型迷尔工控机 CentOS的镜像版本&#xff1a;CentOS-7-x86_64-DVD-2009.iso 下载地址&#xff1a;https://www.centos.org/download/ 安装CentOS的过程跳过。 成功安装后&#xff1a; 1、通过 ip addr 查看网卡的情况 2、通过nmcli dev status 查看网卡的…

嵌入式学习-qt-Day3

嵌入式学习-qt-Day3 一、思维导图 二、作业 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳…

【Nacos】构建云原生应用的动态服务发现、配置管理和服务管理平台【企业级生产环境集群搭建应用】

基础描述 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和…

快速鲁棒的ICP(一)

一、代码下载以、修改以及使用 链接&#xff1a;OpenGP/sparseicp: Automatically exported from code.google.com/p/sparseicp (github.com) 解压之后&#xff1a; 快速鲁棒的ICP是其他人在这份Sparse ICP代码基础上改写出来的&#xff1a; 我这里已经下载好了&#xff1a;…

【C Primer Plus第六版 学习笔记】 第十七章 高级数据表示

有基础&#xff0c;进阶用&#xff0c;个人查漏补缺 链表&#xff1a;假设要编写一个程序&#xff0c;让用户输入一年内看过的所有电影&#xff0c;要储存每部影片的片名和评级。 #include <stdio.h> #include <stdlib.h> /* 提供malloc()的原型 */ #include <s…

​LeetCode解法汇总106. 从中序与后序遍历序列构造二叉树

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 描述&#xff1a; 给定两个…

jetson是什么?

jetson是NVIDIA推出的一系列嵌入式计算板&#xff0c;用于边缘计算。这些板卡专门设计用于加速机器学习和计算机视觉等人工智能应用&#xff0c;它们是低功耗设备&#xff0c;非常适合在无人机、机器人、智能相机和其他自动化设备中使用。 Jetson板卡包括多种型号&#xff0c;…

前端知识复习

1.symbol类型 Symbol 是 ECMAScript 6 中引入的一种新的基本数据类型&#xff0c;它表示独一无二的值。Symbol 值是通过 Symbol() 函数创建的。 Symbol 值具有以下特点&#xff1a; 独一无二性&#xff08;唯一性&#xff09;&#xff1a;每个通过 Symbol() 函数创建的 Symb…

2024 年,向量数据库的性能卷到什么程度了?

对于数据库&#xff08;尤其是向量数据库&#xff09;而言&#xff0c;“性能”是一个十分关键的指标&#xff0c;其用于衡量数据库是否能够在有限资源内&#xff0c;高效处理大量用户请求。对于向量数据库用户而言&#xff0c;尽管可能在某些情况下对延时的要求不高&#xff0…

模板(类模板)---C++

模板目录 2.类模板2.1 类模板语法2.2 类模板与函数模板区别2.3 类模板中成员函数创建时机2.4 类模板对象做函数参数2.5 类模板与继承2.6 类模板成员函数类外实现2.7 类模板分文件编写2.8 类模板与友元2.9 类模板案例 2.类模板 2.1 类模板语法 类模板作用&#xff1a; 建立一个…

pikachu靶场-XSS

XSS&#xff1a; XSS&#xff08;跨站脚本&#xff09;概述 Cross-Site Scripting 简称为“CSS”&#xff0c;为避免与前端叠成样式表的缩写"CSS"冲突&#xff0c;故又称XSS。一般XSS可以分为如下几种常见类型&#xff1a; 1.反射性XSS; 2.存储型XSS; 3.DOM型XSS; …

猫头虎分享已解决Bug || Spring Error: Request method ‘POST‘ not supported

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

上海交大研究团队成功开发可读大模型指纹 /苹果连续17年蝉联全球最受赞赏公司榜首 |魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; &#x1f525;资讯预览 上海交大研究团队成功开发可读大模型指纹&#xff0c;实现模型血统识别 苹果…

C++从入门到精通 第十七章(终极案例)

写在前面&#xff1a; 本系列专栏主要介绍C的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程&#xff0c;笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C教材&#xff08;比…

SD-WAN如何降低运维成本、简化运维工作?

在当今数字化浪潮中&#xff0c;企业对网络的需求愈发迫切&#xff0c;要求网络在安全性、可靠性和灵活性方面都能够得到保障。然而&#xff0c;随着企业上云和远程办公等需求的不断增加&#xff0c;传统的WAN网络已经难以满足企业的多样化需求&#xff0c;所需的运维成本也越来…

数据结构之链表经典算法QJ题目

目录 单链表经典算法题目1. 单链表相关经典算法OJ题&#xff1a;移除链表元素思路一&#xff1a;思路二&#xff1a; 2. 单链表相关经典算法QI题&#xff1a;链表的中间节点思路一思路二 3. 单链表相关经典算法QJ题&#xff1a;反转链表思路一思路二 4. 单链表相关经典算法QJ题…

微信小程序 ---- 慕尚花坊 项目初始化

目录 项目介绍 01. 项目概述 02. 项目演示 03. 项目技术栈 04. 接口文档 申请开发权限 项目初始化 01. 创建项目与项目初始化 02. 自定义构建 npm 集成Sass 03. 集成项目页面文件 04. VsCode 开发小程序项目 项目介绍 01. 项目概述 [慕尚花坊] 是一款 同城鲜花订购…

文心一言 VS 讯飞星火 VS chatgpt (199)-- 算法导论15.2 1题

一、用go语言&#xff0c;对矩阵规模序列(5&#xff0c;10&#xff0c;3&#xff0c;12&#xff0c;5&#xff0c;50&#xff0c;6)&#xff0c;求矩阵链最优括号化方案。 文心一言&#xff0c;代码正常运行&#xff1a; 在Go语言中&#xff0c;为了找到矩阵链乘法的最优括号…

【鸿蒙 HarmonyOS 4.0】TypeScript开发语言

一、背景 HarmonyOS 应用的主要开发语言是 ArkTS&#xff0c;它由 TypeScript&#xff08;简称TS&#xff09;扩展而来&#xff0c;在继承TypeScript语法的基础上进行了一系列优化&#xff0c;使开发者能够以更简洁、更自然的方式开发应用。值得注意的是&#xff0c;TypeScrip…