我正在尝试使用Boost.Log自定义格式化程序。我知道如何做到这一点的方法是调用汇给它一个本地函数的地址set_formatter
方法,其中本地函数的签名必须是:如何在自定义格式化函数中使用Boost.Log格式表达式
void my_formatter(boost::log::record_view const& rec, boost::log::formatting_ostream& strm)
在my_formatter
我可以使用Boost .Log抽取API以获取我需要的属性值。一旦我得到的值,我可以输出他们到strm
。我想这样做,这样我可以轻松地格式化存储在记录中的一些自定义属性。但对于其他更传统的Boost.Log属性,我想继续使用简单的格式化表达式,这些表达式被记录为set_formatter
方法的关键字参数。有没有办法在my_formatter
自定义函数中使用关键字表达式?
例如:
void my_formatter(boost::log::record_view const& rec, boost::log::formatting_ostream& strm)
{
// here I can get the timestamp attribute and format its ticks value to the stream
boost::log::value_ref<boost::posix_time::ptime> tstamp_ref =
boost::log::extract<boost::posix_time::ptime>("TimeStamp", rec);
const boost::posix_time::ptime& timestamp = tstamp_ref.get();
strm << timestamp.time_of_day().ticks();
}
然后给一个接收器,我可以打电话给
sink->set_formatter(&my_formatter)
但Boost.Log给我一个优雅的(几乎是不可思议的)的表达,我可以用它来设置格式:
boost::log::formatter formatter =
expr::stream
<< expr::format_date_time<boost::posix_time::ptime>(
"TimeStamp", "%Y/%m/%d, %H:%M:%S.%f, ");
sink->set_formatter(formatter)
我的问题是:有没有办法在我的自定义中使用formatter表达式my_formatter
功能?
谢谢!
谢谢!这是一个很长的答案,所以我将不得不稍稍研究一下,但这似乎也是一个很好的方法。在使用格式化表达式时,您可以多讨论一下性能下降吗?您在文档中提到,代码中的格式化表达式的执行速度要比从配置文件创建的快。我的观察是我的非表达式格式化程序比基于表达式的表达式执行得更快。 (在我的临时基准测试中,唯一正在做的工作就是日志记录,所以我对速度变慢了,但有时性能确实很重要。) – Phil
必须检查代码和生成的程序集才能发现绩效回归的原因。格式化表达式(无论如何涉及'expr :: stream')比解析格式化器更有效率,因为编译器有更多优化方法。特别是它可以更积极地内联函数。手写格式化程序可能会胜过格式化表达式,因为它可以更加专业化。它通常是一个扁平函数,所以它不依赖内联,而编译器可能由于某种原因无法优化模板表达式。 –
另外,如果你的格式化程序涉及日期/时间,那么确保你使用'expr :: format_date_time'而不是Boost.DateTime中的'operator <<',因为后者被认为比较慢。 –