0

0

C++如何实现简单日志系统_C++封装带时间戳的Log输出类【工具】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-13 14:24:00

|

633人浏览过

|

来源于php中文网

原创

推荐用 std::chrono::system_clock::now() 获取高精度时间,结合 localtime_s(windows)或 localtime_r(linux)转本地时区,毫秒通过 time_since_epoch().count() % 1000000 计算;日志接口采用可变模板参数封装,避免 va_list,优先用 std::ostringstream 或 c++20 std::format。

c++如何实现简单日志系统_c++封装带时间戳的log输出类【工具】

直接用 std::chrono + std::ostringstream 就能做出线程安全、带毫秒级时间戳、可重定向输出的轻量日志类,不用第三方库,也不必依赖 strftime 这类 C 风格函数。

如何生成高精度本地时间戳(含毫秒)

Windows 和 Linux 下都推荐用 std::chrono::system_clock 获取当前时间,再转为本地时区并格式化。别用 std::time(nullptr),它只到秒级,且不处理时区。

  • std::chrono::system_clock::now() 取时间点,转成 std::time_t 得到秒数,再用 std::localtime 转本地结构体
  • 毫秒部分要单独算:time_point.time_since_epoch().count() % 1000(单位是纳秒时除 1000000)
  • 注意:std::localtime 在多线程下非线程安全,应改用 std::localtime_r(Linux)或 localtime_s(MSVC)

如何封装可变参数的日志接口(类似 printf)

C++11 起用可变模板参数比宏更安全,也支持类型检查。不要用 va_list 手动解析,容易出错且无法自动推导类型。

  • 定义模板函数 log(const char* fmt, Args&&... args),内部用 std::sprintfstd::format(C++20)拼接
  • 若不用 C++20,推荐用 std::ostringstream + 流式拼接,避免格式符错误(比如传 <code>std::string 却写 %s
  • 宏包装(如 LOG_INFO)仍可保留,但只做 __FILE____LINE__ 和级别注入,实际输出走模板函数

如何保证多线程下日志不乱序、不崩溃

最简单的办法是每个日志调用都加 std::mutex 锁,但性能差;更合理的是把日志暂存到线程局部缓冲,再由单个日志线程统一刷盘。

NoCode
NoCode

美团推出的零代码应用生成平台

下载

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

  • 轻量场景:在 log() 入口加 static std::mutex mtx,锁住整个格式化+输出流程
  • 注意:锁的范围不能只包 std::cout,必须包含时间戳生成和字符串拼接,否则时间/内容可能错位
  • 若用 std::ofstream 写文件,记得调用 flush(),否则缓冲区内容可能滞留
  • 避免在析构函数里写日志——对象销毁顺序不确定,std::ofstream 可能已关闭

如何支持日志级别和运行时开关

用一个全局 enum class LogLevel 和静态变量控制最低输出级别,比预处理器宏更灵活,支持运行时调整。

  • 定义 enum class LogLevel { DEBUG, INFO, WARNING, ERROR },成员值对应整数便于比较
  • 设静态变量 static LogLevel g_min_level = LogLevel::INFO,每次 log 前先判断 level >= g_min_level
  • 级别字符串建议用 constexpr std::array 查表,而不是一堆 if-else,避免分支预测失败
  • 如果需要动态修改,提供 set_log_level(LogLevel) 接口,无需重启程序

真正难的不是打日志,而是确保时间戳和消息严格对应、多线程下不丢日志、以及关闭日志时不意外触发析构顺序问题——这些细节不显眼,但线上出问题时最难排查。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2023.11.20

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

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

865

2023.07.31

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

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

445

2024.06.27

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

76

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

295

2023.11.28

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

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

543

2023.09.20

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

322

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

198

2025.07.04

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

8

2026.02.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 5万人学习

Pandas 教程
Pandas 教程

共15课时 | 1.1万人学习

ASP 教程
ASP 教程

共34课时 | 4.9万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号