Linux下g3log日志仅程序关闭后输出,Windows10正常的问题求助
g3log在Ubuntu 22/23下日志延迟输出,仅程序关闭后才写入文件
问题描述
开发应用时发现,g3log在Ubuntu 22、23版本下,日志不会实时输出到文件,必须等待程序完全关闭后才会写入;但相同代码在Windows 10系统下运行正常,测试程序可在3台不同Linux设备上稳定复现该问题。
g3log编译步骤
git clone https://github.com/KjellKod/g3log.git cd g3log mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_FATAL_SIGNALHANDLING=OFF -DUSE_DYNAMIC_LOGGING_LEVELS=ON -DG3_SHARED_LIB:BOOL=ON .. make install
测试程序代码
#include <chrono> #include <future> #include <iostream> #include "g3log/g3log.hpp" #include "g3log/logworker.hpp" int main(int argc, char* argv[]) { // initialize g3log auto logger = g3::LogWorker::createLogWorker(); auto handle = logger->addDefaultLogger("test_g3log", "."); g3::initializeLogging(logger.get()); handle->call(&g3::FileSink::overrideLogDetails, &g3::LogMessage::FullLogDetailsToString); std::future<std::string> log_file_name = handle->call(&g3::FileSink::fileName); std::cout << "log file at: [" << log_file_name.get() << "]" << std::endl; for (int j = 0; j < 5; ++j) { std::this_thread::sleep_for(std::chrono::seconds(1)); LOG(INFO) << "test"; } }
编译命令
g++ -o main.exe main.cpp -L/usr/local/lib -lg3log
问题原因
Linux系统下文件IO默认采用全缓冲模式,只有当缓冲区满或程序退出时才会将数据写入磁盘。g3log的默认FileSink在Release模式下依赖系统缓冲策略,不会主动强制刷新缓冲区,导致日志延迟输出。而Windows系统的文件IO缓冲策略更倾向于频繁刷新,因此日志能实时显示。
解决方案
方案1:手动触发单条日志刷新
在每次调用LOG后,主动调用FileSink的flush方法强制刷新缓冲区:
for (int j = 0; j < 5; ++j) { std::this_thread::sleep_for(std::chrono::seconds(1)); LOG(INFO) << "test"; handle->call(&g3::FileSink::flush); // 添加此行 }
方案2:编译g3log时强制全局刷新
编译g3log时添加-DG3LOG_FORCE_FLUSH_ON_EVERY_LOG=ON选项,让每条日志都自动刷新缓冲区:
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_FATAL_SIGNALHANDLING=OFF -DUSE_DYNAMIC_LOGGING_LEVELS=ON -DG3_SHARED_LIB:BOOL=ON -DG3LOG_FORCE_FLUSH_ON_EVERY_LOG=ON .. make install
方案3:自定义FileSink控制缓冲
如果需要更灵活的缓冲策略,可以自定义FileSink实现,例如在日志写入后调用fflush,或者通过setvbuf将文件设置为行缓冲/无缓冲模式:
// 示例:自定义Sink时设置行缓冲 FILE* file = fopen(filename.c_str(), "a"); setvbuf(file, nullptr, _IOLBF, 0); // 设置为行缓冲,每行结束自动刷新
内容的提问来源于stack exchange,提问作者darnell_a
相关产品推荐
相关产品推荐

