C++日志系统:从原理到实战实现

目录

一.日志

二.日志模拟代码

1.filesystem(C++17封装的文件操作函数)

2.获取当前时间:localtime

[三.FILE LINE](#三.FILE LINE)

[1. FILE](#1. FILE)

[2. LINE](#2. LINE)

四.stringstream


一.日志

计算机中的日志是记录系统和软件运行中发生事件的文件,主要作用是监控运行状态、记录异常信息,帮助快速定位问题并支持程序员进行问题修复。它是系统维护、故障排查和安全管理的重要工具。

日志格式以下几个指标是必须得有的

• 时间戳

• 日志等级

• 日志内容

以下几个指标是可选的

• 文件名行号

• 进程,线程相关id信息等

日志有现成的解决方案,如:spdlog、glog、Boost.Log、Log4cxx等等,我们依旧采用自定义日志的方式。

二.日志模拟代码

1.filesystem(C++17封装的文件操作函数)

<filesystem> 是 C++17 引入的标准库,用于跨平台的文件系统操作(目录遍历、文件读写、路径操作等)

操作 函数
路径操作
拼接路径 path / path
获取父路径 p.parent_path()
获取文件名 p.filename()
获取扩展名 p.extension()
目录操作
创建目录 create_directory() / create_directories()
删除目录 remove() / remove_all()
遍历目录 directory_iterator / recursive_directory_iterator
文件操作
复制文件 copy_file()
移动/重命名 rename()
获取大小 file_size()
查询
存在性 exists()
判断类型 is_* 系列函数
最后修改时间 last_write_time()
路径
绝对路径 absolute()
规范化路径 canonical()
当前工作目录 current_path()

注意事项

  1. C++17 要求:确保编译器启用 C++17 标准

  2. 链接选项 :旧版本 GCC/Clang 需要链接 -lstdc++fs-lc++fs

  3. 跨平台性:路径分隔符自动处理,但根名称(Windows 盘符)存在差异

  4. 性能 :频繁调用 exists()/is_directory() 等,建议使用 directory_entry 缓存版本

  5. 异常安全:注意使用 try-catch 或 error_code 版本

  6. 文件系统竞争:多线程操作同一文件系统对象时行为未定义

2.获取当前时间:localtime

在日志中我们难免不了获取当前的时间,下面展示一个简单快速的获取当前可读性高的时间的方法·。

localtime_r 是线程安全的日期时间转换函数,用于将时间戳转换为本地时间的结构化表示

cpp 复制代码
#include <time.h>    // C
#include <ctime>     // C++
cpp 复制代码
struct tm* localtime_r(const time_t* timep, struct tm* result);
参数 类型 说明
timep const time_t* 指向时间戳的指针(通常来自 time() 函数)
result struct tm* 指向存储结果的 tm 结构体的指针
  • 成功 :返回 result 指针(即第二个参数)

  • 失败 :返回 NULL

三.FILE LINE

预定义宏是编译器在编译过程中自动定义的特殊宏,它们在预处理阶段被替换为对应的值。这些宏都以双下划线开头和结尾。

1. __FILE__

类型 : const char*(字符串字面量)

: 当前源文件的文件名(包含路径)

cpp 复制代码
// 文件: /home/user/project/src/main.cpp
#include <iostream>
int main() {
    std::cout << __FILE__ << std::endl;
    // 输出: /home/user/project/src/main.cpp
    return 0;
}

2. __LINE__

类型 : int(整数常量)

: 当前代码所在的行号

cpp 复制代码
#include <iostream>
int main() {
    std::cout << __LINE__ << std::endl;  // 输出: 4
    std::cout << __LINE__ << std::endl;  // 输出: 5
    return 0;
}
  • 行号从 1 开始计数

  • 空行、注释也会占用行号

  • 可以通过 #line 指令修改

四.stringstream

stringstream 是 C++ 标准库中用于字符串流处理的类,定义在 <sstream> 头文件中。它允许你将字符串像输入输出流一样操作。

stringstream 继承自 iostream,因此它支持 <<>> 操作符,可以将各种数据类型转换为字符串或从字符串解析。

cpp 复制代码
#include <sstream>
#include <iostream>
#include <string>

// 1. stringstream - 可读可写
std::stringstream ss;

// 2. istringstream - 只读(输入)
std::istringstream iss("Hello World");

// 3. ostringstream - 只写(输出)
std::ostringstream oss;
cpp 复制代码
std ::stringstream ssbuffer;
                ssbuffer << "[" << _currtime << "] "
                         << "[" << LevaltoString(_leval) << "] "
                         << "[" << _pid << "] "
                         << "[" << _filename << "] "
                         << "[" << _line << "]"
                         << " - ";

                _loginfo = ssbuffer.str();

与snpringf的功能类似。

相关推荐
java修仙传1 小时前
Java 实习日记:一次 Excel 导入校验 Bug 的定位与数据更新逻辑优化
java·数据库·bug·excel·后端开发
小短腿的代码世界1 小时前
传感器暗战:Qt Sensors如何让桌面应用“感知“物理世界?
开发语言·qt
小小编程路1 小时前
增强版 JavaScript 读取 Excel
开发语言·javascript·excel
稽稽稽稽不如人1 小时前
《从零开始的java从入门到入土的学习生活——Java后端篇》Chapter21——Java后端篇学习记录——Redis初步入门
java·学习·生活
吃好睡好便好1 小时前
在Matlab中绘制马鞍函数曲面图
开发语言·人工智能·学习·算法·matlab·信息可视化
测试员周周1 小时前
【Appium 系列】第01节-Appium 是什么 — 移动端自动化的行业标准
开发语言·人工智能·python·功能测试·appium·自动化·测试用例
ID_180079054731 小时前
淘宝店铺所有商品 API 接口:核心能力与数据返回参考
java·服务器·前端
码界筑梦坊1 小时前
117-基于Python的印度犯罪数据可视化分析系统
开发语言·python·mysql·信息可视化·毕业设计·echarts·fastapi
Wy_编程1 小时前
golang 基础语法和函数
开发语言·go