BOOST_LOG_TRIVIAL和boost :: posix_time :: ptime输出格式

时间:2015-09-25 09:15:49

标签: c++ boost

需要为posix_time :: ptime设置使用BOOST_LOG_TRIVIAL打印的自定义构面。比如说,将默认方面更改为“%Y - %m - %d%H:%M:%S”。 我试图用新的语言环境灌输日志接收器,但没有成功。 当应用于std :: cout时,相同的灌输技巧非常有效。 可能是什么问题,是否有办法处理它?<​​/ p>

#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;
}

2 个答案:

答案 0 :(得分:3)

像这样使用sink->set_formatter

sink->set_formatter
    (
        expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y--%m--%d %H:%M:%S")
    );

另外,请务必致电logging::add_common_attributes();

工作示例Coliru

#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 <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/expressions/formatters/date_time.hpp>

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

int 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;

    sink->set_formatter
    (
        expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y--%m--%d %H:%M:%S")
    );
    sink->imbue(sink->getloc());

    logging::add_common_attributes();

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

    return 0;
}

<强>输出:

before 2014-Nov-23 23:59:59.117000
2015--09--25 10:37:42

答案 1 :(得分:1)

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

日志消息字符串由为每条日志消息初始化的流组成,因此您无法使用自定义区域设置为其保留用于多个记录的区域设置。

在使用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;
}

请注意,这会影响应用程序中的所有格式,以用于记录目的而不是。

如果这是不可接受的,您可以尝试不同的方法。首先,您可以编写一个流操纵器,在格式化日期/时间对象之前,将使用区域设置对流进行填充。要自动使用此操纵器,您可以定义自己的记录宏。

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

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