【问题标题】:how to customize "TimeStamp" format of Boost.Log如何自定义Boost.Log的“TimeStamp”格式
【发布时间】:2011-05-10 08:06:08
【问题描述】:

如果我使用“%Y-%m-%d %H:%M:%S.%f”,我想得到年月日时:分:秒.分数(2位),我几乎得到了我想要的分数(最后一部分)的例外情况,它在我的 Windows XP 上显示 6 位数字,我不知道如何只获得 2 位数字,知道吗?

【问题讨论】:

    标签: boost format timestamp logging boost-log


    【解决方案1】:

    我在用这个

    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())
    

    【讨论】:

      【解决方案2】:

      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() 两位数。

      【讨论】:

        【解决方案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();
        

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

        【讨论】:

          【解决方案4】:

          试试这个。它适用于我在 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")]);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-30
            • 2016-02-24
            • 2021-03-08
            • 1970-01-01
            • 2021-09-21
            相关资源
            最近更新 更多