Boost.Log日志写入后进程未终止时无法读取文件内容的测试问题
Boost.Log日志写入后进程未终止时无法读取文件内容的测试问题
我完全明白你遇到的困扰——Boost.Log为了性能考虑,默认会对日志输出做内存缓冲,日志消息不会立刻写入磁盘,而是要等到缓冲区满、手动触发刷新,或者进程退出时才会把内容刷到文件里。这就导致你在测试用例里刚写完日志就去读文件,自然拿不到内容。下面咱们一步步解决这个问题:
先修正代码里的基础错误
在动手解决刷新问题前,先把代码里的几个笔误修正,不然测试根本跑不起来:
- 你的实现文件
my_boost_log.cpp里,add_file_log的file_name参数用了未定义的logFileName,要改成函数参数fileLog - 测试用例里用了
LOG_INFO宏,但你定义的是MY_LOG_DEBUG,要对应上 main函数里调用的log::init应该是你接口里的init_library函数
核心解决方案:让日志立刻写入磁盘
有两种常用的方式可以实现进程未终止时读取到日志内容:
方式一:开启自动刷新(全局配置)
在init_library函数的add_file_log配置里,新增auto_flush = true参数,这样每条日志写入后都会立刻刷新到磁盘:
void init_library(std::string fileLog) { boost::log::add_file_log( boost::log::keywords::file_name = fileLog, // 修正为参数fileLog boost::log::keywords::rotation_size = 10 * 1024 * 1024, boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0), boost::log::keywords::format = "%TimeStamp% [%Severity%] : %Message%", boost::log::keywords::auto_flush = true); // 开启自动刷新 auto core = boost::log::core::get(); core->add_global_attribute("TimeStamp", boost::log::attributes::local_clock()); core->add_global_attribute("Process", boost::log::attributes::current_process_name()); core->add_global_attribute("ProcessID", boost::log::attributes::current_process_id()); core->add_global_attribute("ThreadID", boost::log::attributes::current_thread_id()); core->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace); }
方式二:手动触发刷新(按需调用)
如果不想全局开启自动刷新(担心影响性能),可以在测试用例里写完日志后,手动调用日志核心的flush方法,强制把缓冲区内容刷到磁盘:
TEST_F(MyLogTest, TestLogRecord) { std::string logMess{"Test debug log"}; MY_LOG_DEBUG(logMess); // 手动刷新日志核心 boost::log::core::get()->flush(); std::ifstream logFile("test_file.log"); if (logFile.is_open()) { std::string fileLine; bool messageFound = false; while (std::getline(logFile, fileLine)) { std::cout << "文件内容行: " << fileLine << std::endl; // 提取日志消息部分:你的格式是「时间戳 [级别] : 消息」,所以找": "的位置 size_t msgStartPos = fileLine.find(": "); if (msgStartPos != std::string::npos) { std::string extractedMsg = fileLine.substr(msgStartPos + 2); if (extractedMsg == logMess) { messageFound = true; break; } } } logFile.close(); // 断言消息是否找到 ASSERT_TRUE(messageFound) << "测试日志消息未在文件中找到"; } else { FAIL() << "无法打开测试日志文件"; } }
修正后的main函数
别忘了把main里的初始化函数改成正确的init_library:
int main(int argc, char** argv) { init_library("test_file.log"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
额外注意事项
- 测试完成后,可以考虑删除测试用的日志文件,避免残留文件影响下一次测试
- 如果你的日志宏里给消息加了换行,记得在测试时调整
logMess的内容(比如去掉多余的换行,或者匹配日志里的格式) - 确保Boost.Log的链接和编译配置正确,避免因为库依赖问题导致日志无法正常写入
备注:内容来源于stack exchange,提问作者n_90040
相关产品推荐
相关产品推荐

