Linux之线程池(一)

日志

日志与策略模式

一、什么是设计模式

软件开发里,很多场景都是重复遇到的经典问题。前辈工程师针对这些高频场景,总结出一套通用、成熟、可复用的解决方案 ,这套方案就叫做设计模式

简单理解:写代码的 "模板套路",目的是让代码更好扩展、更容易维护、可读性更强,团队协作时大家也能看懂彼此的代码。

二、日志认识

日志是用来记录程序、系统运行过程中发生事件的文件。 核心用途:

  1. 监控程序运行状态
  2. 保存报错、异常信息
  3. 线上故障排查、定位 BUG
  4. 运维安全审计

日志是排查线上问题最重要的工具,程序出问题无法调试时,只能依靠日志回溯现场。

规范日志必备字段(标准日志组成)

  • 时间戳:事件发生的精确时间,用来定位先后顺序
  • 日志等级(DEBUG/INFO/WARN/ERROR/FATAL)
  • 进程 / 线程 ID
  • 报错文件、行号
  • 具体描述信息(业务内容、异常堆栈)

了解日志相关的函数

cpp 复制代码
[可读性很好的时间] [日志等级] [进程 pid] [打印对应日志的文件名][行号] - 消息内容,支持可变参数
2 [2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [16] - hello world
3 [2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [17] - hello world
4 [2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [18] - hello world
5 [2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [20] - hello world
6 [2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [21] - hello world
7 [2024-08-04 12:27:03] [WARNING] [202938] [main.cc] [23] - hello world

先思考,这个日志模块需要哪些东西?

先梳理依赖元素:

  1. 日志有不同等级:DEBUG / WARNING / ERROR / INFO → 用 enum 枚举
  2. 核心打印函数:接收【等级、文件名字符串、行号、格式化字符串、可变参数】→ 函数声明
  3. 多线程安全:打印的时候不能多个线程穿插输出 → 需要互斥锁
  4. 对外简易接口宏:自动填充 __FILE__ __LINE__,使用者不用手动传文件、行号
  5. 需要用到的头文件:<cstdarg>可变参数、<ctime>时间、<pthread.h>互斥锁、<string>字符串处理

代码

gettimeofday()

作用:获取系统当前时间,得到秒 + 微秒高精度时间

参数:

  1. tv:传出参数,传入 struct timeval 指针,函数把当前时间填进 tv->tv_sec(秒)、tv->tv_usec(微秒)
  2. tzstruct timezone*时区参数已经废弃,直接传 nullptr / NULL

返回值:

  • 0:成功
  • -1:失败,设置 errno

localtime_r

_r 系列函数:把输出缓冲区由库内部全局,改成调用者自己提供内存

参数:

  1. timep:输入,time_t 指针(Unix 纪元秒)
  2. result调用者自己定义的 struct tm 变量地址 ,函数把解析出来的年月日时分秒,填到你给的这块内存。 返回值:成功返回 result 指针;失败返回 NULL
我们先进行策略的制定

由于有多种策略,我们这里实现向显示器和文件写入,

这里就可以使用基类和子类的方法进行

向显示器打印

向文件写入

我们需要文件名,文件路径

设计一个类调用

我们想要外部包含头文件就可以使用

测试

设计日志生成

这里我们采用内部类的实现

stringstream 详解

头文件:#include <sstream>

stringstream 是 C++ 字符串流,把字符串当成内存里的流设备 ,和 cin/cout 用法几乎一样。

  • cout:把数据输出到屏幕
  • cin:从键盘读取数据
  • stringstream:把数据输出 / 读取到内存字符串,不操作文件、不操作终端。

分为三类:

  1. ostringstream:只输出(把变量转字符串)
  2. istringstream:只输入(把字符串解析成变量)
  3. stringstream:既可以读,也可以写。
1. 核心用途
  1. 任意类型转字符串(int、double、bool 转 std::string)
  2. 字符串切割解析,按空格分割字符串
  3. 拼接多类型字符串 ,不用反复 += 处理数字转字符串
  4. 把任意类型日志内容转成字符串,拼到日志缓冲区。

构造函数

我们还需要往里面写入内容,也就是说我们需要重载<<

功能作用

  1. 模板 template<typename T> :支持任意类型(字符串、int、double 等)日志内容输入,不用写多个重载版本。
  2. 参数接收待写入日志的数据info
  3. 局部stringstream ss:把任意类型 T 的数据,统一转为字符串。
  4. _loginfo += ss.str():把转换后的字符串,追加到类私有成员_loginfo(日志消息缓冲区),累积整条日志内容。
  5. return *this返回对象引用 :支持链式调用,实现 obj << "a" << 123 << 3.14连续拼接日志。
相关推荐
IT毕设实战小研1 小时前
基于大数据的二手车数据分析与预测
java·大数据·后端·爬虫·python·算法·课程设计
吠品1 小时前
OkHttp 多文件上传的一个实现
java·服务器·前端
牛油果子哥q1 小时前
C++序列式容器深度精讲:vector/list/deque底层实现、扩容原理、迭代器失效、性能对比、工程选型避坑
开发语言·c++·list
lingguangbuzhi1 小时前
【JAVA教程】java课程java学习编程
java·学习·教程
渡我白衣1 小时前
Acceptor模块的设计与实现
java·linux·服务器·开发语言·网络·c++·人工智能
沫璃染墨2 小时前
《从零入门Linux系统篇(二十八):文件篇·一——Linux为什么“万物皆文件”:从C语言文件流到系统调用》
linux·运维·服务器·开发语言·c++·文件
luteres3 小时前
Mybatis+SSM整合笔记
java·开发语言·mybatis
郝学胜-神的一滴3 小时前
《C++11 工程级应用01:告别冗长类型,开启简洁高效编码新时代》深度解读
开发语言·c++·算法·软件开发·系统设计
其实防守也摸鱼3 小时前
推荐一个自动化教育SRC漏洞挖掘系统--AutoHunter
运维·开发语言·人工智能·学习·安全·web安全·自动化