2015-09-25 126 views
2

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

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

回答

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

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

+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 
+0

真棒回答。至关重要,完整。我赞同这一点:) – sehe

+1

不是每个日志字符串的set_formatter调用集格式? 也许我的问题有点误导。我想要做的是为boost :: posix_time :: ptime类型的变量设置为使用BOOST_LOG_TRIVIAL输出时的所有情况设置格式。 –

相关问题