C++开发的transit应用如何实现单文件1KB大小的运行时日志保存
C++ 单文件1KB限制的运行时日志实现方案
核心实现逻辑
- 采用日志滚动切割机制:每次写入日志前校验当前活跃日志文件的大小,超过1KB阈值后自动创建新的日志文件,命名可按序号或时间戳区分,例如
transit_run.log.0、transit_run.log.1 - 兼顾性能与崩溃可追溯性:每次写入日志后立即刷入磁盘,避免程序崩溃时缓冲区内的日志丢失;加锁保证多线程场景下的日志写入安全
- 自带上下文信息:日志自动拼接时间戳,也可扩展添加行号、线程ID等字段,方便故障定位
参考代码实现
#include <fstream> #include <string> #include <mutex> #include <filesystem> #include <chrono> #include <format> // 配置常量 constexpr size_t MAX_LOG_FILE_SIZE = 1024; // 单文件最大1KB constexpr const char* LOG_BASE_NAME = "transit_app.log"; std::mutex log_mutex; std::ofstream current_log_file; int log_file_index = 0; // 日志初始化,应用启动时优先调用 void init_log() { current_log_file.open(LOG_BASE_NAME, std::ios::app | std::ios::out); if (std::filesystem::exists(LOG_BASE_NAME) && std::filesystem::file_size(LOG_BASE_NAME) >= MAX_LOG_FILE_SIZE) { rotate_log(); } } // 日志滚动切割逻辑 void rotate_log() { current_log_file.close(); std::string old_name = LOG_BASE_NAME; std::string new_name = std::format("{}.{}", LOG_BASE_NAME, log_file_index++); std::filesystem::rename(old_name, new_name); current_log_file.open(old_name, std::ios::app | std::ios::out); } // 对外日志写入接口 void write_log(const std::string& content) { std::lock_guard<std::mutex> lock(log_mutex); // 写入前判断是否需要滚动 if (std::filesystem::file_size(LOG_BASE_NAME) >= MAX_LOG_FILE_SIZE) { rotate_log(); } // 拼接时间戳写入 auto now = std::chrono::system_clock::now(); auto time_str = std::format("{:%Y-%m-%d %H:%M:%S}", now); current_log_file << "[" << time_str << "] " << content << std::endl; current_log_file.flush(); } // 可选:封装带代码位置的日志宏,方便定位崩溃 #define LOG_INFO(msg) write_log(std::format("[INFO] {}:{} {}", __FILE__, __LINE__, msg)) #define LOG_ERROR(msg) write_log(std::format("[ERROR] {}:{} {}", __FILE__, __LINE__, msg))
适配说明
- 如果使用C++17以下版本,可将
std::filesystem替换为操作系统原生文件操作接口,std::format替换为sprintf或第三方轻量格式化库 - 可自行添加日志保留数量限制,比如最多留存10个历史日志文件,避免占用过多磁盘空间
内容的提问来源于stack exchange,提问作者M tech expert Gmoepgihal
相关产品推荐
相关产品推荐

