超级好用的C++实用库之日志类

💡 需要该C++实用库源码的大佬们,可搜索微信公众号“希望睿智”。添加关注后,输入消息“超级好用的C++实用库”,即可获得源码的下载链接。

概述

        日志类主要用于在程序运行过程中记录信息、错误、警告以及其他需要跟踪的数据,这对于调试、监控应用状态及后期问题分析至关重要。一个高效且灵活的日志类应该满足以下几个核心需求。

        日志级别管理:可定义多个日志级别,比如:DEBUG、INFO、WARN、ERROR、FATAL等,以便根据情况筛选日志的详细程度。同时,还允许运行时动态调整日志输出级别,便于在生产环境中减少不需要的日志输出,或增加更详细的日志输出。

        多线程安全:在多线程的环境下,可确保日志写入操作是线程安全的,避免日志内容混乱或程序崩溃。通常情况下,这可以通过互斥锁、原子操作或线程局部存储等机制来实现。

        灵活的输出点:支持将日志输出到控制台、本地文件、网络套接字、数据库等多种目的地,并可配置输出目标,允许同时或选择性地输出到多个地方。

        自动文件管理:可自动创建和管理日志文件,并按时间、大小滚动日志文件。同时,文件名应包含日期等信息,便于归档和查询。

        日志格式化:支持格式化字符串,允许在日志中内嵌变量、时间戳、进程ID、线程ID等信息。另外,支持自定义日志格式,以满足不同场景下的需求。

        高性能与低延迟:采用缓冲机制减少I/O操作次数,提高日志写入效率。支持异步写入日志,避免阻塞主线程,减少对应用性能的影响。

        可以看到,封装一个高效且灵活的日志类,需要考虑的东西非常多。目前有很多第三方开源日志库,比如:glog、spdlog或EasyLogger等,但这些库用起来相对比较复杂,特别是在底层模块中使用,耦合比较严重。为了简化底层模块中日志类的使用,我们封装了下面的CHP_Logger类。

CHP_Logger类

        CHP_Logger是一个简单、易于集成和使用的日志类,可在各个底层库中使用。应用层可使用glog、spdlog或EasyLogger等第三方日志库,并配合该日志类记录底层库日志。CHP_Logger类的头文件,可参考下面的示例代码。

#pragma once#include <stdarg.h>#include "HP_Types.h"
#include "HP_Mutex.h"enum IHPLoggerLevel
{HPLoggerLevel_None,HPLoggerLevel_Error, HPLoggerLevel_Warn,HPLoggerLevel_Info, HPLoggerLevel_Debug, HPLoggerLevel_Trace, HPLoggerLevel_Count
};typedef void(*CALLBACK_LOGGER_OUTPUT)(IHPLoggerLevel level, const char *pszLog, void *pContext);class CHP_Logger
{
public:static void Open();static CHP_Logger *&Singleton();static void Close();void SetLevel(IHPLoggerLevel level);bool IsLogEnabled(IHPLoggerLevel level);void SetLogOutputListener(CALLBACK_LOGGER_OUTPUT pCbOutput, void *pContext);void SetMaxLogLen(unsigned int uiLen);void Error(const char *pszFormat, ...);void Warn(const char *pszFormat, ...);void Info(const char *pszFormat, ...);void Debug(const char *pszFormat, ...);void Trace(const char *pszFormat, ...);static void Error(CHP_Logger *pLogger, const char *pszFormat, ...);static void Warn(CHP_Logger *pLogger, const char *pszFormat, ...);static void Info(CHP_Logger *pLogger, const char *pszFormat, ...);static void Debug(CHP_Logger *pLogger, const char *pszFormat, ...);static void Trace(CHP_Logger *pLogger, const char *pszFormat, ...);protected:CHP_Logger();~CHP_Logger();private:void Log(const char *pszFormat, va_list &argList, IHPLoggerLevel level);private:static CHP_Logger *m_pThis;IHPLoggerLevel m_level;CALLBACK_LOGGER_OUTPUT m_pCbOutput;void *m_pContext;char *m_pszLog;unsigned int m_uiMaxLogLen;CHP_Mutex m_mutexLog;
};

        在上面的示例代码中,我们声明了一个枚举类型IHPLoggerLevel,用于指定日志输出级别。CHP_Logger类是一个接口类,不需要实例化。因此,我们将构造函数和析构函数声明成了私有的。下面,我们将分别介绍其导出的公共实例接口。

        SetLevel:设置日志输出级别。参数level为日志输出级别,用于控制日志输出的详细程度。

        IsLogEnabled:用于判断指定级别的日志是否使能。参数level为指定的日志级别,返回值为true表示该级别的日志使能,否则不使能。

        SetLogOutputListener:设置日志输出监听器。参数pCbOutput为日志输出的回调函数,参数pContext为回调函数上下文。应用层需要设置日志输出监听器,以对回调函数中的日志进行自定义操作,比如:写本地文件、输出到控制台、传输到网络等。

        SetMaxLogLen:设置单条日志的最大长度。参数uiLen为单条日志的最大长度,单位为字节,传0时,默认为16KB。

        Error:输出错误日志。pszFormat为日志格式字符串,支持可变参数。

        Warn:输出警告日志。pszFormat为日志格式字符串,支持可变参数。

        Info:输出信息日志。pszFormat为日志格式字符串,支持可变参数。

        Debug:输出调试日志。pszFormat为日志格式字符串,支持可变参数。

        Trace:输出详尽日志。pszFormat为日志格式字符串,支持可变参数。

        除了上面的实例接口外,我们还导出了5个同名的静态接口,分别为:Error、Warn、Info、Debug、Trace。这几个静态接口一般用于底层动态链接库中输出日志,这样底层和应用层可以共用一个日志单实例对象。

总结

        日志类是编程中用于生成、管理、保存应用程序运行时信息的核心组件,对于故障排查、系统监控、性能分析、合规审计至关重要。日志类更是开发、运维团队的重要工具,能帮助我们快速定位问题,优化系统性能,保障系统稳定运行。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

std::ref和std::cref的使用和原理分析

目录 1.用法 2.std::reference_wrapper介绍 3.std::ref原理分析 4.std::cref原理分析 5.总结 1.用法 它的定义如下&#xff1a; std::ref&#xff1a;用于包装按引用传递的值。 std::cref&#xff1a;用户包装按const引用传递的值。 C本身就有引用&#xff08;&&#…

学习中的小疑问|头结点是什么?

头结点 在数据结构中&#xff0c;单链表是一种常见的线性数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含两个部分&#xff1a;存储数据的数据域和指向下一个节点的指针域。单链表的头结点是指链表的第一个节点&#xff0c;它通常用于标识链表的开始位置。 …

面试题:调整数字顺序,使奇数位于偶数前面

题目&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序 使得所有奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分 算法1&#xff1a; 利用快速排序的一次划分思想&#xff0c;从2端往中间遍历 时间复杂度&#x…

C++ | Leetcode C++题解之第88题合并两个有序数组

题目&#xff1a; 题解&#xff1a; class Solution { public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {int p1 m - 1, p2 n - 1;int tail m n - 1;int cur;while (p1 > 0 || p2 > 0) {if (p1 -1) {cur nums2[p2-…

Alist + RaiDrive-Nas挂载云盘(Quark)

Alist RaiDrive-Nas挂载云盘(Quark) Alist download Alist document RaiDriver download — https://www.raidrive.com/ nssm download nssm document nssm specification 配置 Alist 下载适合的Alist版本后&#xff0c;启动服务&#xff1b; 需使用命令符。 在完成解…

数字水印 | Python 基于离散小波变换 DWT 的图像水印嵌入(上)

&#x1f34d;原文&#xff1a; 基于 dwt (离散小波变换) 实现彩色图像水印嵌入部分_1.0 &#x1f34d;写在前面&#xff1a; 本文在原文的基础上进行了代码补全。 正文 本文的内容主要为&#xff1a;水印图像经过 A r n o l d \mathsf{Arnold} Arnold 置乱算法后&#xff0…

vue+springboot用户注销功能

vue文件前端 <el-button type"warning" plain click"handleDeletion">注 销</el-button> // 注销 const handleDeletion (userName) > {ElMessageBox.confirm(注销该用户所有信息后无法恢复&#xff0c;您确认注销吗?, 注销确认, { type…

基于halcon的锯齿检测

锯齿检测是机器视觉中的一项任务&#xff0c;它涉及到检测图像中类似锯齿的边缘或模式。在 Halcon 中&#xff0c;这通常涉及到图像处理和分析技术&#xff0c;如边缘检测、阈值处理、形态学操作和轮廓分析。以下是一个基于 Halcon 的锯齿检测的概述&#xff0c;以及一个简单的…

Spring生命周期深度解析

Spring生命周期深度解析 介绍 Spring是一个开源的Java框架&#xff0c;用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式&#xff0c;使得开发者可以更加专注于业务逻辑的实现&#xff0c;而不必过多关注底层的技术细节。 在使用Spring框架开发应用程序时…

数据之舞:Processing中的数据可视化艺术

前言: 🌐在前几篇文章中,我们已经探索了静态图形、动态动画以及交互设计的世界。今天,我们将踏入一个全新的领域——数据可视化。在这个信息爆炸的时代,如何将复杂的数据转化为直观、美观的视觉呈现,是每一位设计师和艺术家都需要掌握的技能。Processing提供了一系列强…

实现日期类

日期类的实现主要是去学习使用operator的 日期类就是计算日期之间的天数&#xff0c;日期与&#xff08;日期&#xff0c;天数&#xff09;的相加减 比如日常生活中我们可以计算日期加天数&#xff0c;日期减天数&#xff0c;日期减日期&#xff0c; 但没有日期加日期的说法 日…

M-有效算法

在赛场上&#xff0c;脑子就两个字“二分”&#xff0c;一点思路都没&#xff0c;完全不知道二分谁&#xff0c;怎么二分&#xff0c;从哪入手。隐隐约约也知道要变换公式&#xff0c;可惜没坚持这个想法。脑子里全是把k分离出来&#xff0c;赛后看了题解才知道&#xff0c;应该…

LeetCode 力扣题目:买卖股票的最佳时机 IV

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

MQTT学习(二)

订阅主题和订阅确认 SUBSCRIBE——订阅主题 之前的CONNECT报文&#xff0c;分为 固定报头&#xff1a;必须存在&#xff0c;用于描述报文信息。里面有指出什么类型的报文&#xff0c;报文的等级。可变报头&#xff1a;不一定存在。主要看什么样子类型的报文。有效载荷部分&a…

LoRA Land: 310个经微调的大语言模型可媲美GPT-4

摘要 低秩自适应 (LoRA) 已成为大语言模型 (LLM) 参数有效微调 (PEFT) 中最广泛采用的方法之一。LoRA 减少了可训练参数的数量和内存使用,同时达到了与全面微调相当的性能。该研究旨在评估在实际应用中训练和服务使用 LoRA 微调的 LLM 的可行性。首先,该研究测量了在 10 个基础…

js基础-数组-事件对象-日期-本地存储

一、大纲 一、获取元素位置 在JavaScript中&#xff0c;获取一个元素在页面上的位置可以通过多种方法实现。以下是一些常见的方法&#xff1a; getBoundingClientRect() getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。它提供了元素的left、top、right和bo…

Vue的学习 —— <vue响应式基础>

目录 前言 正文 单文件组件 什么是单文件组件 单文件组件使用方法 数据绑定 什么是数据绑定 数据绑定的使用方法 响应式数据绑定 响应式数据绑定的使用方法 ref() 函数 reactive()函数 toRef()函数 toRefs()函数 案例练习 前言 Vue.js 以其高效的数据绑定和视图…

探索大语言模型代理(Agent):研究背景、通用框架与未来展望

引言 近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;在智能代理&#xff08;Agent&#xff09;领域中的应用已成为研究的热点。这些代理不仅能够模拟人类的认知过程&#xff0c;还能在复杂的社会环…

CNN/TCN/LSTM/BiGRU-Attention到底哪个模型效果最好?注意力机制全家桶来啦!

​ 声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 数据介绍 效果展示 原理简介 代…

数字人解决方案——AniTalker声音驱动肖像生成生动多样的头部说话视频算法解析

1.概述 AniTalker是一款先进的AI驱动的动画生成工具&#xff0c;它超越了简单的嘴唇同步技术&#xff0c;能够精准捕捉并再现人物的面部表情、头部动作以及其他非言语的微妙动态。这不仅意味着AniTalker能够生成嘴型精准同步的视频&#xff0c;更重要的是&#xff0c;它还能够…