You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:14:49