How to use Boost.Log formatting expressions in custom formatting function

时间:2016-07-28 20:28:18

标签: c++ boost-log

I am trying to use a custom formatter with Boost.Log. The way I know how to do this is to call the set_formatter method of a sink giving it the address of a local function where the signature of the local function needs to be:

void my_formatter(boost::log::record_view const& rec, boost::log::formatting_ostream& strm)

In my_formatter I can use the Boost.Log extraction api to get the attribute values that I need. Once I get the values, I can output them to the strm. I want to do this so I can easily format some custom attributes stored in the record. But for other, more conventional Boost.Log attributes, I would like to continue to use the simple formatting expressions that are documented as keyword arguments to the set_formatter method. Is there a way to also use the keyword expressions in my_formatter custom function?

For example:

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();
}

Then given a sink, I can call

sink->set_formatter(&my_formatter)

But Boost.Log gives me an elegant (almost magical) expression that I can use to set the formatter:

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 question is: is there a way to use the formatter expression in my custom my_formatter function?

Thanks!

2 个答案:

答案 0 :(得分:2)

您可能想要做的是将格式化程序的自定义部分注入使用Boost.Log创建的格式表达式,而不是相反。 This回答描述了使用phoenix::bind实现这一目标的方法。

答案 1 :(得分:1)

经过一番工作,我发现了一些Boost.Log测试代码form_date_time.cpp,它显示了如何执行此操作。下面是如何在自定义格式函数中以编程方式使用表达式formatter。

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),此方法允许人们在自定义格式化函数中利用表达式格式化程序。