如何在自定义格式化函数中使用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.

实现该目标的方法