如何在自定义格式化函数中使用Boost.Log格式化表达式
How to use Boost.Log formatting expressions in custom formatting function
我正在尝试将自定义格式化程序与 Boost.Log 一起使用。我知道如何做到这一点的方法是调用接收器的 set_formatter
方法,给它一个本地函数的地址,其中本地函数的签名需要是:
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,我可以调用
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)
我的问题是:有没有办法在我的自定义 my_formatter
函数中使用格式化程序表达式?
谢谢!
经过一些工作,我找到了一些 Boost.Log 测试代码,form_date_time.cpp,显示了如何执行此操作。下面是如何在自定义格式函数中以编程方式使用表达式格式化程序。
void my_formatter(boost::log::record_view const& rec,
boost::log::formatting_ostream& strm)
{
typedef boost::log::formatter formatter;
formatter f = expr::stream << expr::format_date_time<boost::posix_time::ptime>(
"TimeStamp", "%Y/%m/%d, %H:%M:%S.%f, ");
f(rec, strm);
}
虽然我给出了答案,但还是要谨慎使用。在我的基准测试中,正确实现的自定义格式化程序函数将胜过表达式格式化程序。但是对于您不想为其编写代码的复杂表达式(例如,专门的 Named scope formatter),这种方法允许在自定义格式化程序函数中利用表达式格式化程序。
您可能想要做的是将格式化程序的自定义部分注入到使用 Boost.Log 创建的格式化表达式中,而不是相反。 答案描述了一种使用 phoenix::bind
.
实现该目标的方法
我正在尝试将自定义格式化程序与 Boost.Log 一起使用。我知道如何做到这一点的方法是调用接收器的 set_formatter
方法,给它一个本地函数的地址,其中本地函数的签名需要是:
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,我可以调用
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)
我的问题是:有没有办法在我的自定义 my_formatter
函数中使用格式化程序表达式?
谢谢!
经过一些工作,我找到了一些 Boost.Log 测试代码,form_date_time.cpp,显示了如何执行此操作。下面是如何在自定义格式函数中以编程方式使用表达式格式化程序。
void my_formatter(boost::log::record_view const& rec,
boost::log::formatting_ostream& strm)
{
typedef boost::log::formatter formatter;
formatter f = expr::stream << expr::format_date_time<boost::posix_time::ptime>(
"TimeStamp", "%Y/%m/%d, %H:%M:%S.%f, ");
f(rec, strm);
}
虽然我给出了答案,但还是要谨慎使用。在我的基准测试中,正确实现的自定义格式化程序函数将胜过表达式格式化程序。但是对于您不想为其编写代码的复杂表达式(例如,专门的 Named scope formatter),这种方法允许在自定义格式化程序函数中利用表达式格式化程序。
您可能想要做的是将格式化程序的自定义部分注入到使用 Boost.Log 创建的格式化表达式中,而不是相反。 phoenix::bind
.