如何自定义Boost.Log的“TimeStamp”格式

时间:2011-05-10 08:06:09

标签: boost format timestamp logging boost-log

我想得到年 - 月 - 日 - 小时:分:秒。分数(2位数),如果我使用“%Y-%m-%d%H:%M:%S%f”,我几乎得到了我想要的秒数分数(最后一部分)的异常,它在我的Windows XP上显示6位数,我不知道如何获得2位数,任何想法?

4 个答案:

答案 0 :(得分:4)

Boost.DateTime(Boost.Log所依赖的)似乎不支持专门的小数秒格式化,所以唯一的方法就是编写自己的自定义属性格式化程序,或者(更简单,但不太好)方式)稍微修改您的格式代码。

而不是像这样:

backend->set_formatter
(
    fmt::stream <<
      fmt::date_time<boost::posix_time::ptime>
        ("TimeStamp", keywords::format = "%Y-%m-%d %H:%M:%S.%f"));

backend->set_formatter
(
    fmt::stream <<
    fmt::date_time<boost::posix_time::ptime>
        ("TimeStamp", keywords::format = %Y-%m-%d %H:%M:%S.") <<
    (fmt::format("%.2s") % fmt::date_time<boost::posix_time::ptime>("%f"))
);

我自己没有测试过,但我相信它应该可行:第一个fmt::date_time()将返回没有小数秒的时间戳,而第二个fmt::date_time()将仅返回小数秒,将被fmt::format()剪切为两位数。

答案 1 :(得分:3)

我们用这堂课解决了这个问题:

    class TimeStamp : public boost::log::attributes::local_clock {
        public:
            typedef boost::log::attribute_value attribute_type;
            typedef boost::log::attributes::local_time_traits TimeTraitsT;
            typedef TimeTraitsT::time_type time_type;
            typedef boost::log::attributes::basic_attribute_value< std::string > result_value;

        public:
            boost::shared_ptr< attribute_type > get_value() {
                time_type posix_time = boost::date_time::microsec_clock< time_type >::universal_time();
                time_type::time_duration_type time = posix_time.time_of_day();
                time_type::date_type date = posix_time.date();
                std::stringstream formatter;

                formatter
                    << date.year() << "-"
                    << std::setfill('0') << std::setw(2) << int(date.month()) << "-"
                    << std::setfill('0') << std::setw(2) << date.day() << " "
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.hours()) << ":"
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.minutes()) << ":"
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.seconds()) << ","
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.fractional_seconds()) / 1000
                ;

                return boost::make_shared< result_value >(formatter.str());
            }
    };

初始化如下:

boost::log::core::get()->add_global_attribute("TimeStamp", boost::make_shared< TimeStamp >());

并像这样使用:

backend_ptr->set_formatter(
    boost::log::formatters::stream
        << boost::log::formatters::attr< std::string >("TimeStamp")
        << boost::log::formatters::message();

显然,该课程允许我们访问或格式化我们希望的日期的任何部分

答案 2 :(得分:3)

我正在使用这个

namespace boost
{
    BOOST_LOG_OPEN_NAMESPACE

    namespace attributes
    {
        template <typename date_time_type>
        void format_time_ms( std::ostringstream& formatter, const date_time_type& date_time)
        {
            auto time = date_time.time_of_day();
            using namespace std;
            formatter
                << setfill( '0') << setw( 2) << time.hours()   << ':'
                << setfill( '0') << setw( 2) << time.minutes() << ':'
                << setfill( '0') << setw( 2) << time.seconds() << ','
                << setfill( '0') << setw( 3) << time.fractional_seconds() / 1000;
        }

        template <typename date_time_type>
        std::string format_time_ms( const date_time_type& date_time)
        {
            std::ostringstream formatter;
            format_time_ms( formatter, date_time);
            auto time = date_time.time_of_day();
            return formatter.str();
        }

        template <typename date_time_type>
        std::string format_date_time_ms( const date_time_type& date_time, const char date_time_sep = ' ')
        {
            using namespace std;
            ostringstream formatter;
            auto date = date_time.date();
            formatter
                << date.year() << '-'
                << setfill( '0') << setw( 2) << int( date.month()) << '-'
                << setfill( '0') << setw( 2) << date.day() << date_time_sep;
            format_time_ms( formatter, date_time);
            return formatter.str();
        }

        template <typename date_time_type, const char date_time_sep = ' '>
        struct date_time_ms_formatter
        {           
            std::string operator () ( const date_time_type& date_time) { return format_date_time_ms( date_time, date_time_sep); }
        };

        struct time_ms_formatter
        {
            template <typename date_time_type>
            std::string operator () ( const date_time_type& date_time) { return format_time_ms( date_time); }
        };

        template <typename time_type>
        struct local_clock_source
        {
            time_type operator () () const
            {
                return date_time::microsec_clock<time_type>::local_time();
            }
        };

        template <typename time_type>
        struct universal_clock_source
        {
            time_type operator () () const
            {
                return date_time::microsec_clock<time_type>::universal_time();
            }
        };

        template <typename time_type, typename clock_source_type, typename formater_type>
        class custom_clock: public attribute
        {
        public:
            class impl: public attribute::impl
            {
            public:
                attribute_value get_value()
                {
                    auto str = formater_type()( clock_source_type()());
                    return make_attribute_value( str);
                }
            };

            custom_clock(): attribute( new impl()) {}

            explicit custom_clock( const cast_source& source): attribute( source.as<impl>()) {}
        };


        typedef custom_clock<boost::posix_time::ptime, local_clock_source<boost::posix_time::ptime>, date_time_ms_formatter<boost::posix_time::ptime, '\t'> >       local_date_time_ms_clock;
        typedef custom_clock<boost::posix_time::ptime, universal_clock_source<boost::posix_time::ptime>, date_time_ms_formatter<boost::posix_time::ptime, '\t'> >   universal_date_time_ms_clock;

        typedef custom_clock<boost::posix_time::ptime, local_clock_source<boost::posix_time::ptime>, time_ms_formatter>     local_time_ms_clock;
        typedef custom_clock<boost::posix_time::ptime, universal_clock_source<boost::posix_time::ptime>, time_ms_formatter> universal_time_ms_clock;
    }

    BOOST_LOG_CLOSE_NAMESPACE // namespace log
}

初始化为

BOOST_LOG_ATTRIBUTE_KEYWORD( dateTimeStamp,     "DateTime",     boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD( timeStamp,         "Time",         boost::posix_time::ptime)

core->add_global_attribute( dateTimeStamp.get_name(),   attrs::local_date_time_ms_clock());
core->add_global_attribute( timeStamp.get_name(),       attrs::local_time_ms_clock());

并用作

expr::stream << expr::attr<std::string>( dateTimeStamp.get_name())
expr::stream << expr::attr<std::string>( timeStamp.get_name())

答案 3 :(得分:0)

尝试这个。它在Linux下对我有效。

sink->set_formatter(log_expr::format("%1%") % log_expr::max_size_decor<char>(22)[log_expr::stream << log_expr::format_date_time<boost::posix_time::ptime>("Timestamp", "%Y-%m-%d %H:%M:%S.%f")]);