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

Boost Log升级至1.82后浮点格式无法跨日志条目保留,如何解决?

Boost.Log 1.82 浮点数格式跨条目保留解决方案

从Boost.Log 1.61升级到1.82后,浮点数格式化状态不再跨日志条目保留,这是因为新版本默认每个BOOST_LOG_TRIVIAL生成的临时流对象会在构造时重置格式为std::default,目的是避免不同日志条目间的格式污染。要恢复旧版本的行为,有以下几种可行方案:

方案1:每个日志条目显式指定格式

这种方法直接但繁琐,需要在每个需要特定格式的日志行中显式添加格式操纵符:

BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(6) << "bar = " << bar;
BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(6) << "baz = " << baz;

方案2:全局配置日志格式化器(推荐)

通过Boost.Log的格式化器功能,全局统一设置浮点数的输出格式,无需在每个日志语句中重复添加操纵符。以下是完整的配置示例:

#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/core.hpp>
#include <iomanip>

int main(int, char* [])
{
    // 配置trivial日志的格式化器,全局设置浮点数格式
    boost::log::core::get()->set_formatter(
        boost::log::expressions::stream
            << "[" << boost::log::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
            << "] [" << boost::log::expressions::attr<boost::log::attributes::current_thread_id::value_type>("ThreadID")
            << "] [" << boost::log::expressions::attr<boost::log::trivial::severity_level>("Severity")
            << "]    " << std::fixed << std::setprecision(6) // 全局设置浮点数格式
            << boost::log::expressions::smessage
    );

    double foo(10), bar(123.4567890123), baz(100000000.123456789);

    BOOST_LOG_TRIVIAL(info) << "Tests log & double";
    BOOST_LOG_TRIVIAL(info) << "-------------------------------";
    BOOST_LOG_TRIVIAL(info) << "Raw doubles";
    BOOST_LOG_TRIVIAL(info) << "foo = " << foo;
    BOOST_LOG_TRIVIAL(info) << "bar = " << bar;
    BOOST_LOG_TRIVIAL(info) << "baz = " << baz;
    BOOST_LOG_TRIVIAL(info) << "-------------------------------";
    BOOST_LOG_TRIVIAL(info) << "foo fixed";
    BOOST_LOG_TRIVIAL(info) << "foo = " << foo;
    BOOST_LOG_TRIVIAL(info) << "bar = " << bar;
    BOOST_LOG_TRIVIAL(info) << "baz = " << baz;
    BOOST_LOG_TRIVIAL(info) << "-------------------------------";
    BOOST_LOG_TRIVIAL(info) << "foo fixed & precision = 5";
    // 如果需要临时修改格式,仍可在日志行中添加操纵符,会覆盖全局设置
    BOOST_LOG_TRIVIAL(info) << std::setprecision(5) << "foo = " << foo;
    BOOST_LOG_TRIVIAL(info) << std::setprecision(5) << "bar = " << bar;
    BOOST_LOG_TRIVIAL(info) << std::setprecision(5) << "baz = " << baz;

    return 0;
}

这种方式下,所有浮点数会默认以fixed格式、6位精度输出,和Boost 1.61的行为一致。如果需要临时修改某条日志的格式,仍可在对应行添加操纵符覆盖全局设置。

方案3:自定义带状态的日志记录器

如果需要手动维护跨条目的格式状态,可以创建自定义的日志记录器,而非使用trivial日志。需要注意的是,这种方式要处理线程安全问题,避免多线程下的格式冲突:

#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <iomanip>

boost::log::sources::logger_mt g_logger; // 线程安全的日志记录器

int main(int, char* [])
{
    boost::log::add_common_attributes();

    double foo(10), bar(123.4567890123), baz(100000000.123456789);

    BOOST_LOG(g_logger) << "Tests log & double";
    BOOST_LOG(g_logger) << "-------------------------------";
    BOOST_LOG(g_logger) << "Raw doubles";
    BOOST_LOG(g_logger) << "foo = " << foo;
    BOOST_LOG(g_logger) << "bar = " << bar;
    BOOST_LOG(g_logger) << "baz = " << baz;
    BOOST_LOG(g_logger) << "-------------------------------";
    BOOST_LOG(g_logger) << "foo fixed";
    
    // 获取日志流并设置格式,后续条目会保留该状态
    boost::log::record rec = g_logger.open_record();
    if (rec) {
        boost::log::record_ostream strm(rec);
        strm << std::fixed << "foo = " << foo;
        strm.flush();
        g_logger.push_record(boost::move(rec));
    }

    // 后续日志条目会继承之前的fixed格式
    BOOST_LOG(g_logger) << "bar = " << bar;
    BOOST_LOG(g_logger) << "baz = " << baz;

    return 0;
}

内容的提问来源于stack exchange,提问作者HWP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:24:56