[C++]——同步异步日志系统(3)

同步异步日志系统

  • 一、日志系统框架设计
    • 1.1模块划分
      • 1.1.1 日志等级模块
      • 1.1.2 日志消息模块
      • 1.1.3 日志消息格式化模块
      • 1.1.4 日志落地模块(日志落地的方向是工厂模式)
      • 1.1.5 日志器模块(日志器的生成是建造者模式)
      • 1.1.6 异步线程模块(日志的输出是用宏完成的代理模式)
      • 1.1.7 单例的日志器管理模块(单例模式实现对日志器的管理)
    • 1.2 模块关系图
  • 二、代码设计
    • 2.1 实用类设计

日志系统:
作用:将一条消息,进行格式化为指定格式的字符串后,写入到指定位置

  1. 日志要写入指定位置(标准输出,指定文件, 滚动文件等等是可扩展得)
    日志系统需要支持将日志消息落地到不同的位置—多落地方向
  2. 日志写入指定位置,支持不同的写入方式(同步,异步)
    同步:业务线程自己负责日志的写入(流程简单,但是有可能会因为阻塞导致效率降低) 异步:业务线程将日志放入缓冲区内存,让其他异步线程负责将日志写入指定位置
  3. 日志输出以日志器为单位,支持多日志器(不同的项目组有不同的输出策略)

一、日志系统框架设计

本项⽬实现的是⼀个多⽇志器⽇志系统,主要实现的功能是让程序员能够轻松的将程序运⾏⽇志信息落地到指定的位置,且⽀持同步异步两种⽅式的⽇志落地⽅式。

1.1模块划分

1.1.1 日志等级模块

枚举出日志分为多少个等级—对不同的日志有不同等级标记–以便于控制输出

  • OFF:关闭
  • DEBUG:调试,调试时的关键信息输出。
  • INFO:提示,普通的提⽰型⽇志信息。
  • WARN:警告,不影响运⾏,但是需要注意⼀下的⽇志。
  • ERROR:错误,程序运⾏出现错误的⽇志。
  • FATAL:致命,⼀般是代码异常导致程序⽆法继续推进运⾏的⽇志。

1.1.2 日志消息模块

封装一条日志所需的各种要素(时间,线程ID,文件名,行号,日志等级,消息主体…)

  • 时间:描述本条⽇志的输出时间。
  • 线程ID:描述本条⽇志是哪个线程输出的。
  • ⽇志等级:描述本条⽇志的等级。
  • ⽇志数据:本条⽇志的有效载荷数据。
  • ⽇志⽂件名:描述本条⽇志在哪个源码⽂件中输出的。
  • ⽇志⾏号:描述本条⽇志在源码⽂件的哪⼀⾏输出的。

1.1.3 日志消息格式化模块

按照指定的格式,对于日志消息中关键要素进行组织,最终得到一个指定格式的字符串

系统默认的输出格式: [%d{%H:%M:%S}]%T[%t]%T[%p]%T[%c]%T%f:%l%T%m%n
[12:38:45] [12345678] [FATAL] [root] main.c:178 套接字创建失败…\n

  • %d{%H:%M:%S}:表⽰⽇期时间,花括号中的内容表示日期时间的格式。
  • %T:表⽰制表符缩进。
  • %t:表⽰线程ID。%p:表⽰⽇志级别。
  • %c:表⽰⽇志器名称,不同的开发组可以创建⾃⼰的⽇志器进⾏⽇志输出,⼩组之间互不影响。
  • %f:表⽰⽇志输出时的源代码⽂件名。
  • %l:表⽰⽇志输出时的源代码⾏号。
  • %m:表⽰给与的⽇志有效载荷数据 。
  • %n:表⽰换行。
  • 设计思想:设计不同的⼦类,不同的⼦类从⽇志消息中取出不同的数据进⾏处理。

1.1.4 日志落地模块(日志落地的方向是工厂模式)

决定了⽇志的落地⽅向,以什么方式输出。

  • 标准输出:表⽰将⽇志进⾏标准输出的打印。
  • ⽇志⽂件输出:表⽰将⽇志写⼊指定的⽂件末尾。
  • 滚动⽂件输出:当前以⽂件⼤⼩进⾏控制,当⼀个⽇志⽂件⼤⼩达到指定⼤⼩,则切换下⼀个⽂件进⾏输出 。
  • 后期,也可以扩展远程⽇志输出,创建客⼾端,将⽇志消息发送给远程的⽇志分析服务器。
  • 设计思想:设计不同的⼦类,不同的⼦类控制不同的⽇志落地⽅向。

1.1.5 日志器模块(日志器的生成是建造者模式)

对上边几个模块的整合,⽤⼾通过⽇志器进⾏⽇志的输出,有效降低⽤⼾的使⽤ 难度。
⽇志消息落地模块对象,⽇志消息格式化模块对象,⽇志输出等级

  • 同步日志器模块—完成日志的同步输出功能。
  • 异步日志器模块—完成日志的异步输出功能(将日志消息发送到日志缓冲器内存)

1.1.6 异步线程模块(日志的输出是用宏完成的代理模式)

负责异步日志的实际落地输出功能

  • 实现对⽇志的异步输出功能,⽤⼾只需要将输出⽇志任务放⼊任务池,异步线程负责⽇志的落地输出功能,提供了更加⾼效的⾮阻塞的⽇志输出。

1.1.7 单例的日志器管理模块(单例模式实现对日志器的管理)

为了方便管理,可以在程序的任意位置使用日志器,我设置一个单例对象。对日志进行全局的管理,以便于能够在项目的任何位置获取指定的日志器进行日志输出。

  • 为了降低项⽬开发的⽇志耦合,不同的项⽬组可以有⾃⼰的⽇志器来控制输出格式以及落地⽅向,因此本项⽬是⼀个多⽇志器的⽇志系统。
  • 管理模块就是对创建的所有⽇志器进⾏统⼀管理。并提供⼀个默认⽇志器,提供标准输出的⽇志输出。

1.2 模块关系图

在这里插入图片描述
通过模块关系图,能够简单快速的了解模块之间的关系。

二、代码设计

2.1 实用类设计

提前完成一些功能和接口。

  1. 首先需要把架子搭起来,功能先声明好。
//  通⽤功能类,与业务⽆关的功能实现
//  1. 获取系统时间
//  2. 判断文件是否存在
//  3. 获取⽂件所在⽬录的路径
//  4. 创建⽬录
//静态接口可以直接使用,不需要实例化对象
#include <iostream>
namespace logsLearn {namespace util{//日期类class Data{public://获取系统时间static time_t now();};//文件类class File{public://判断文件是否存在static bool exists(const std::string &pathname);//获取⽂件所在⽬录的路径static std::string path(const std::string &pathname);//创建⽬录static void createDirectory(const std::string &pathname);};} 
}
  1. 其次在实现各个功能。
// 条件编译,防止头文件重复包含
#ifndef __M_UTIL_H__
#define __M_UTIL_H__
//  通⽤功能类,与业务⽆关的功能实现
//  1. 获取系统时间
//  2. 判断文件是否存在
//  3. 获取⽂件所在⽬录的路径
//  4. 创建⽬录
#include <iostream>
#include <ctime>
#include <sys/stat.h>
#include <sys/types.h>
namespace logsLearn
{namespace util{// 日期类class Data{public:// 获取系统时间static time_t now(){// 返回当前系统时间return time(nullptr);}};// 文件类class File{public:// 判断文件是否存在static bool exists(const std::string &pathname){ // 定义了一个stat的结构体变量struct stat st;// 获取文件信息不成功,进入条件if (stat(pathname.c_str(), &st) < 0){return false;}return true;}// 获取⽂件所在⽬录的路径static std::string path(const std::string &pathname){ if (pathname.empty()) return ".";// pos是当前查找的最后“/\\”的位置size_t pos = pathname.find_last_of("/\\");// 没有找到"/\\"if (pos == std::string::npos)return ".";// 找到了,返回路径,左闭右开原则,要想包括pos位置,需要加1return pathname.substr(0, pos + 1);}// 创建⽬录static void createDirectory(const std::string &pathname){ // pos找到的位置,idx是存的位置size_t pos = 0, idx = 0;while (idx < pathname.size()){// 遍历路径每找到最后一个"/\\"创建文件夹size_t pos = pathname.find_first_of("/\\", idx);if (pos == std::string::npos){ // 创建文件夹,pathname.c_str()表示路径名,0777表示权限mkdir(pathname.c_str(), 0777);}// 前面的路径std::string parent_dir = pathname.substr(0, pos + 1);// 文件是否存在if (exists(parent_dir) == true){idx = pos + 1;continue;}// 文件不存在,创建文件mkdir(parent_dir.c_str(), 0777);idx = pos + 1;}}};}
}
#endif
  1. 我们每次编写完一个模块后,要对其进行单元测试,确保程序的准确性。
//测试代码
#include "util.hpp"
int main()
{//工具类测试std::cout<<logsLearn::util::Data::now()<<std::endl;std::string pathname="./abc/bcd/a.txt";std::cout<<pathname;logsLearn::util::File::createDirectory(logsLearn::util::File::path(pathname));return 0;
}
  1. 界面展示
    make运行之前
    在这里插入图片描述
    make运行之后
    在这里插入图片描述
    补充:
    1.stat函数
    stat函数是用于获取文件信息,比如文件权限,文件类型信息等等。
    函数的声明:
    int stat(const char *pathname, struct stat *buf);
    参数说明:
    pathname:表示文件路径名
    buf:用于保存获取到的文件属性信息(这是一个传出参数)
    返回值说明:成功返回0,失败返回-1并设置errno
    2.mkdir函数
    mkdir函数用于创建一个新的目录。如果指定的目录已经存在,并且没有设置相应的标志来允许覆盖或忽略已存在的目录,则函数会失败;它允许用户为新创建的目录设置权限,这些权限决定了谁可以访问该目录。
    函数声明:
    int mkdir(const char * pathname , mode_t mode);
    参数说明:
    pathname(const char * ):指向以null结尾的字符串的指针,该字符串指定了要创建的目录的路径。路径可以是相对路径或绝对路径。
    mode(mode_t):指定新目录的权限。这些权限位使用八进制数表示(例如,0755),并且会受进程的文件模式创建掩码(umask)的影响。最终权限是请求权限与umask的补码的逻辑与结果。通常,mode参数包括文件所有者(user)、组(group)和其他人(other)的读(r)、写(w)和执行(x)权限的组合。
    返回值说明:成功时,返回0;失败时,返回-1,并设置全局变量errno以指示错误类型(如EACCES表示权限不足,EEXIST表示目录已存在等)。

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

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

相关文章

强化学习总结(有具体代码实现)

文章目录 第一部分 强化学习基础第1章 强化学习概述1.1 强化学习概念1.2 强化学习的环境1.3 强化学习的目标1.4 强化学习的数据 第2章 多臂老虎机问题&#xff08;MAB问题&#xff09;2.1 问题描述2.1.1 问题定义2.1.2 形式化描述2.1.3 累积懊悔2.1.4 估计期望奖励 2.2 解决方法…

【机器学习】必会数学知识:一文掌握数据科学核心数学知识点(上),值得收藏~

核心数学知识点 1、引言2、数据科学必会数学知识2.1 线性代数2.2 微积分2.3 概率论2.4 数理统计2.5 随机过程2.6 数据分布2.7 贝叶斯统计2.8 线性回归2.9 逻辑回归2.10 矩阵分解2.11 主成分分析&#xff08;PCA&#xff09;2.12 奇异值分解&#xff08;SVD&#xff09; 3、总结…

【人工智能大语言模型技术发展研究报告 2024】

文末‍有福利&#xff01; 人工智能作为引领新一轮科技产业革命的战略性技术和新质生产力重要驱动力&#xff0c;正在引发经济、社会、文化等领域的变革和重塑&#xff0c;2023 年以来&#xff0c;以 ChatGPT、GPT-4 为代表的大模型技术的出台&#xff0c;因其强大的内容生成及…

提升教师健康,聚焦智慧校园人事系统的职工体检功能

智慧校园人事管理系统内置的职工体检管理&#xff0c;是专为教职员工设计的一项健康管理创新实践&#xff0c;巧妙融合先进信息技术&#xff0c;致力于为教职工提供更加便捷、易懂且持续性的健康检查与管理支持。该服务从多个维度出发&#xff0c;全面呵护教职工的身心健康。 该…

给你的博客加上评论区

一个网站如果有评论功能&#xff0c;可以更好的和读者互动。VuePress 也有很多评论插件&#xff0c;这里简单介绍下&#xff0c;最后介绍本站所使用的 Twikoo。 大部分评论插件都是使用的 Github 或 Gitee 的 issue 功能&#xff0c;也就是用 issue 去存储评论&#xff1b;而 …

脚本实现保留文本中特定字符之后的字符串

#目的背景 原始txt文本如下图 目的是为了去除序号&#xff0c;每行只单独呈现域名 手工删除漫长又麻烦&#xff0c;使用脚本快捷些 代码实现逻辑&#xff1a; 1.使用open函数打开文本&#xff0c;之后用变量lines存储文本的所有行&#xff0c;使用for循环&#xff0c;让变量te…

暑假学习计划怎么做 用待办计划软件安排更科学

暑期来临&#xff0c;无论是学生还是老师&#xff0c;做好暑期计划都至关重要。记得去年暑假&#xff0c;我给自己定下了阅读十本书的目标&#xff0c;却因为缺乏明确的计划&#xff0c;最后只草草读完了两本。而今年&#xff0c;我决定尝试一种新的方式——使用待办计划软件来…

谷粒商城实战笔记-24-分布式组件-SpringCloud Alibaba-Nacos配置中心-命名空间与配置分组

文章目录 一&#xff0c;命名空间1&#xff0c;简介1.1&#xff0c;命名空间的主要功能和特点1.2&#xff0c;使用场景1.3&#xff0c;如何指定命名空间 2&#xff0c;命名空间实战2.1&#xff0c;环境隔离2.2&#xff0c;服务隔离 二&#xff0c;配置集三&#xff0c;配置集ID…

js原型和类---prototype,__proto__,new,class

原型和原型链 在js中&#xff0c;所有的变量都有原型&#xff0c;原型也可以有原型&#xff0c;原型最终都指向Object 什么是原型 在js中&#xff0c;一个变量被创建出来&#xff0c;它就会被绑定一个原型&#xff1b;比如说&#xff0c;任何一个变量都可以使用console.log打…

PostgreSQL 中如何实现数据的增量更新和全量更新的平衡?

文章目录 一、增量更新与全量更新的概念增量更新全量更新 二、考虑的因素1. 数据量2. 数据更改的频率和规模3. 数据一致性要求4. 系统性能和资源利用5. 业务逻辑和流程 三、解决方案&#xff08;一&#xff09;混合使用增量更新和全量更新&#xff08;二&#xff09;使用临时表…

暑期旅游季必备,用这款客服神器应对爆棚的客流咨询

解决暑期旅游客流高峰问题 暑期是旅游高峰季节&#xff0c;客流量剧增&#xff0c;客户咨询纷至沓来。在这个时候&#xff0c;如何高效处理客户的咨询成为每家旅游机构和景点不可忽视的挑战。 聊天宝快捷回复助手是一款强大的工具&#xff0c;可帮助企业在客流高峰期快速回复客…

MemFire Cloud: 一种全新定义后端即服务的解决方案

在这个快节奏的互联网时代&#xff0c;开发者们最希望的就是能够省时省力地完成项目&#xff0c;快速上线。然而&#xff0c;搭建服务、开发接口API、处理各种后端问题&#xff0c;往往让人头疼不已。别担心&#xff0c;现在有了MemFire Cloud&#xff0c;一款为懒人开发者量身…

制作电子名片的小程序系统源码 快速生成电子名片

在当今数字化时代&#xff0c;传统的纸质名片已逐渐被智能电子名片所取代。电子名片小程序作为一种基于微信生态的创新名片交换方式&#xff0c;凭借其便捷性、高效性和环保性&#xff0c;成为了众多商务人士的首选。小编分享一个制作电子名片的小程序系统源码&#xff0c;无忧…

malloc实现原理【Liunx】

malloc实现原理 malloc是什么&#xff1f;malloc,calloc, realloc的区别malloc的实现原理malloc的两种实现方式为什么使用brk&#xff1f;为什么使用mmap&#xff1f; malloc怎么定界的malloc分配的是虚拟内存上的空间吗&#xff1f; malloc是什么&#xff1f; 通过malloc&…

LinK3D: Linear Keypoints Representation for 3D LiDAR Point Cloud【翻译与解读】

LinK3D: Linear Keypoints Representation for 3D LiDAR Point Cloud 摘要 特征提取和匹配是许多机器人视觉任务的基本组成部分&#xff0c;如 2D 或 3D 目标检测、识别和配准。2D 特征提取和匹配已取得巨大成功。然而&#xff0c;在 3D 领域&#xff0c;当前方法由于描述性差…

2024前端面试题之Vue3

2024前端面试题之Vue3 在面试具有五年经验的前端工程师时&#xff0c;对于 Vue 3 的掌握程度是一个重要的考核点。本文将提供一系列针对这一级别工程师的 Vue 3 面试题&#xff0c;并附上详细的解析&#xff0c;帮助面试官全面评估候选人的技术实力和项目经验。 一、Vue 3 基础…

vscode-server安装和部分配置

文章目录 前言code-server安装rpm包安装tar.gz安装 vscode部分配置vscode配置函数跳转安装插件 vscode的structurevscode的hierarchy更改颜色主题 前言 vscode确实彳亍&#xff0c;虽然我觉得Clion(c/c语言版的IDEA)更方便&#xff0c;但是毕竟我没钱买license 这里记录一下网…

11410-00SF 同轴连接器

型号简介 11410-00SF是Southwest Microwave的连接器。该连接器的外壳采用优质不锈钢&#xff0c;材质为 CRES ALLOY UNS-S303500&#xff0c;符合 ASTM-A582 标准。首先&#xff0c;不锈钢材料经过锻造加工&#xff0c;形成转接器的基本形状。然后&#xff0c;外壳进行精密的 C…

CentOS7忘记root密码无法登陆解决方法

重启服务器&#xff0c;等到如图下所示界面的时候&#xff0c;快速按下键盘的↑或者↓按键&#xff0c;等固定住画面&#xff0c;然后按下e按键 然后按键盘上的↓按键&#xff0c;找到图下所示的linux16开头的那段&#xff0c;然后把光标挪到ro这里 按照图下所示&#xff0c;把…

提供跨平台的视觉安防解决方案,满足不同场景的需求的智慧交通开源了。

智慧交通视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。用户只需在界面上…