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
相关产品推荐
相关产品推荐

