讲师中心 微信公众号

工具推荐

视频效率加速
Laper
Laper

剧本策划到成片协作

AniShort
AniShort

AI短剧协同制作平台

剧云
剧云

中文短剧剧本制作平台

Seko
Seko

AI短剧一键生成成片

如何用C++编写一个日志库?C++项目日志系统设计与实现【从零开始】

浅浩吖_3702

浅浩吖_3702

发布时间:2025-12-21 15:21:08

|

870人浏览过

|

来源于php中文网

原创

C++轻量日志库应以线程安全、高性能、易用可扩展为设计核心,采用enum class日志级别、轻量消息结构、延迟格式化、无锁入队+单线程刷盘、LogSink接口抽象及懒加载单例模式。

如何用c++编写一个日志库?c++项目日志系统设计与实现【从零开始】

用C++写一个实用的日志库,核心不是堆功能,而是平衡线程安全、性能、易用性和可扩展性。从零开始不必追求大而全,先实现“能用、不崩、看得懂”,再逐步加特性。

基础结构:日志级别 + 输出目标

日志库最底层要定义几个关键概念:日志级别(DEBUG/INFO/WARNING/ERROR)、日志消息体(时间、线程ID、模块名、内容)、输出方式(控制台、文件、或两者)。不需要一开始就支持网络或数据库——那些是后期插件化的事。

  • 用 enum class 定义级别,配合 constexpr 字符串映射,避免运行时字符串比较
  • 日志消息建议封装为轻量结构体(非类),构造时只存必要字段(如 const char* msg, int level, uint64_t timestamp),延迟格式化(避免锁内做 snprintf)
  • 输出目标抽象为接口(如 class LogSink),默认提供 ConsoleSink 和 FileSink,便于后续替换或组合

线程安全:别锁整个日志函数

高频打日志时,全局互斥锁是性能杀手。更合理的做法是“无锁入队 + 单线程刷盘”:

  • 前端(调用方)用 lock-free queue(如 boost::lockfree::queue 或自己基于原子操作实现的简易环形缓冲区)把日志消息快速入队
  • 后台起一个专用日志线程,循环取队列、格式化、写入目标。这样主线程几乎不阻塞
  • 如果项目不允许额外线程(如嵌入式),改用 per-thread buffer + 定期 flush,或退化为带细粒度锁的 mutex + 小缓冲区

格式化与上下文:少用 std::string,多用 string_view

格式化是日志开销大头之一。避免在每次 log 调用中构造 std::string 或调用 std::format(C++20)——它们可能触发内存分配。

阿拉丁·前端工程工坊|脚手架·组件·规范落地·构建优化·性能与可访问性一体
阿拉丁·前端工程工坊|脚手架·组件·规范落地·构建优化·性能与可访问性一体

阿拉丁·前端工程工坊把「前端只会写页面、规范停在文档里、脚手架手敲、构建靠抄、性能靠猜、可访问性靠忘」从「手动搭项目、抄配置、肉眼查规范」升级成一条本地工具链——多框架脚手架生成(React/Vue3/Svelte + Vite)、可复用组件生成(Props 类型+样式+示例)、规范落地检查(lint-lite:命名/未用变量/console残留/TS any/目录结构)、构建配置生成与产物体积预算、性能审计(依赖体积/重复/懒加载/Lighthouse 清单)、可访问性(a11y)校验(alt/aria

下载

立即学习“C++免费学习笔记(深入)”;

  • 接受 const char* 或 std::string_view 作为消息主体,参数用变参模板(如 template)延迟展开
  • 格式化逻辑尽量放在后台线程里,且优先使用栈上缓冲(如 char buf[512])+ snprintf;超出再 fallback 到 heap 分配
  • 支持简单上下文:比如通过 RAII 类(如 LogScope)自动记录进入/退出,或用宏注入 __FILE__、__LINE__、函数名(__func__)

配置与初始化:静态实例 + 懒加载

日志库应“开箱即用”,但又不能强依赖全局初始化顺序。

  • 提供全局函数(如 LOG_INFO("hello")),背后调用单例 Logger::instance(),首次调用时懒初始化(double-checked locking 或 std::call_once)
  • 初始化接口简洁:Logger::init(FileSink{"app.log"}, Level::INFO);支持运行时动态调级(set_level())和添加 sink(add_sink())
  • 避免静态对象析构期写日志(可能导致 crash),关闭时显式调用 Logger::shutdown(),由用户控制时机

基本上就这些。不复杂但容易忽略的是:日志本身不该成为故障源——它得在内存紧张、线程混乱、甚至部分系统调用失效时仍尽力工作。所以越早做边界检查(如空指针、缓冲区溢出)、越晚做昂贵操作(如堆分配、系统调用),就越稳。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

7579

2023.08.02

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1869

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1231

2024.06.27

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1089

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3540

2023.10.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2478

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1938

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

3204

2023.09.04

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

100

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn