需要设置BOOST_LOG_TRIVIAL打印的posix_time::ptime的自定义构面。说,将默认构面更改为“%Y-%m-%d%H:%M:%S”。
我试图使日志接收器具有新的语言环境,但没有成功。
将相同的注入(inject)技巧应用于std::cout时,效果很好。
可能是什么问题,有没有办法解决?

#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <locale>

namespace logging  = boost::log;
namespace pt       = boost::posix_time;

void main(void)
{
    // console sink
    auto sink = logging::add_console_log(std::cout);

    // standart output
    boost::posix_time::ptime t1(boost::posix_time::time_from_string("2014-11-23 23:59:59.117"));
    BOOST_LOG_TRIVIAL(info) << "before " << t1;

    // adding custom facet...
    pt::time_facet *facet = new boost::posix_time::time_facet("%Y--%m--%d %H:%M:%S");
    sink->imbue(std::locale(sink->getloc(), facet));

    // ... but output doesn't change
    BOOST_LOG_TRIVIAL(info) << "after  " << t1;
}

最佳答案

问题是接收器中的语言环境未用于日志消息字符串格式化。无法使用它,因为可能有多个接收器,并且选择不明确。该语言环境用于日志记录格式设置,该格式针对每个接收器单独执行。

日志消息字符串由为每个日志消息初始化的流组成,因此您不能以使区域设置用于多个记录的方式为它添加自定义区域设置。

您可以做的是在使用Boost.Log之前,将自定义语言环境设置为应用程序初始化代码中某个位置的全局语言环境。

void main(void)
{
    pt::time_facet *facet = new boost::posix_time::time_facet("%Y--%m--%d %H:%M:%S");
    std::locale::global(std::locale(std::locale(), facet));

    // console sink
    auto sink = logging::add_console_log(std::cout);

    // ...

    BOOST_LOG_TRIVIAL(info) << "after  " << t1;
}

请注意,这将影响应用程序中的所有格式,而不会影响日志记录。

如果不能接受,则可以尝试其他方法。首先,您可以编写一个流操纵器,在格式化日期/时间对象之前,该操纵器将在语言环境中注入(inject)流。要自动使用此操纵器,您可以定义自己的日志记录宏。
struct locale_manip {};

std::ostream& operator<< (std::ostream& strm, locale_manip)
{
    pt::time_facet *facet = new boost::posix_time::time_facet("%Y--%m--%d %H:%M:%S");
    strm.imbue(std::locale(std::locale(), facet));
    return strm;
}

#define MY_LOG(sev) BOOST_LOG_TRIVIAL(sev) << locale_manip()

void main(void)
{
    // ...

    MY_LOG(info) << "after  " << t1;
}

另一种解决方案是转换日志记录语句,以便将日期/时间对象作为属性添加到日志记录中。然后,您可以使用格式化程序和特定于接收器的语言环境来自定义输出。

10-08 07:52
查看更多