使用 boost log 时如何更改时间戳输出?

问题描述 投票:0回答:1

我正在尝试找到一种最简单的方法来更改时间戳的输出。这就是我初始化日志库的方式

  boost::log::add_common_attributes();
  boost::log::register_simple_formatter_factory<SeverityLevel, char>("Severity");
  boost::log::register_simple_formatter_factory<boost::posix_time::ptime, char>("TimeStamp");
  boost::log::add_file_log(
     boost::log::keywords::file_name = strFileName,
     boost::log::keywords::open_mode = std::ios_base::out | std::ios_base::app,
     boost::log::keywords::format = "[%TimeStamp%] {%Severity% @ %Channel%} %Message%",
     boost::log::keywords::auto_flush = true
  );

我还添加以下声明

enum class SeverityLevel {
   Debug = 0,
   Info,
   Warning,
   Error,
   Critical
};

BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", SeverityLevel)
BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)

std::ostream& operator <<(std::ostream& objStream, SeverityLevel eLevel);
boost::log::formatting_ostream& operator <<(boost::log::formatting_ostream& objStream, boost::log::to_log_manip<SeverityLevel, tag::severity> const& objManipulator);

std::ostream& operator <<(std::ostream& objStream, boost::posix_time::ptime objTime);
boost::log::formatting_ostream& operator <<(boost::log::formatting_ostream& objStream, boost::log::to_log_manip<boost::posix_time::ptime, tag::timestamp> const& objManipulator);

当然,我实现了这些运算符,但它们的实现对于问题来说并不重要。

结果中与严重性相关的运算符“std::ostream& 运算符 <<(std::ostream& objStream, SeverityLevel eLevel)" is called as it's supposed to, when I write a log entry, but the operator related to TimeStamp is not. What am I doing wrong here?

我为什么需要这个是为了自定义时间戳的写入方式。我知道还有其他方法可以完全不同地做到这一点,例如设置接收器格式化程序。我想使用字符串格式模板,如本示例所示。

c++ boost boost-log boost-logging
1个回答
0
投票

首先,你要求“最简单的方法” - 我认为这是来自docs的方法:

void init()
{
    logging::add_file_log
    (
        keywords::file_name = "sample_%N.log",
        // This makes the sink to write log records that look like this:
        // YYYY-MM-DD HH:MI:SS: <normal> A normal severity message
        // YYYY-MM-DD HH:MI:SS: <error> An error severity message
        keywords::format =
        (
            expr::stream
                << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
                << ": <" << logging::trivial::severity
                << "> " << expr::smessage
        )
    );
}

除此之外,你说:

我实现了这些运算符,但它们的实现对于这个问题并不重要。

实现不是,但是定义它们的地方是。使用参数相关查找查找运算符。对于它们来说,位于声明您的参数类型的命名空间中很重要。

这可能说明您自己的枚举

SeverityLevel
正在为您工作,但不是
boost::posix_time::ptime
。我不建议您将
operator<<(ostream&
覆盖为
ptime
。相反,请考虑使用 DateTime 库中的 output 方面

这是一个概念证明,证明 ADL 技巧将会发挥作用:

住在Coliru

#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/log/common.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup.hpp>

namespace MyLib {
    enum class SeverityLevel { Debug, Info, Warning, Error, Critical };

    BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", SeverityLevel)
    BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)

    std::ostream& operator<<(std::ostream& os, SeverityLevel l) { //
        return os << "[Severity:" << static_cast<int>(l) << "]";
    }
} // namespace MyLib

namespace boost::posix_time { // DO NOT DO THIS IN PRODUCTION CODE
    std::ostream& operator<<(std::ostream& os, boost::posix_time::ptime) {
        return os << "[TODO:" << __LINE__ << "]";
    }
} // namespace boost::posix_time

using MyLib::SeverityLevel;

void init_logging(std::string const& strFileName) {

    namespace l  = boost::log;
    namespace kw = l::keywords;
    l::add_common_attributes();

    l::register_simple_formatter_factory<SeverityLevel, char>("Severity");
    l::register_simple_formatter_factory<boost::posix_time::ptime, char>("TimeStamp");
    l::add_file_log(                                                         //
        kw::file_name  = strFileName,                                        //
        kw::open_mode  = std::ios_base::out | std::ios_base::app,            //
        kw::format     = "[%TimeStamp%] {%Severity% @ %Channel%} %Message%", //
        kw::auto_flush = true                                                //
    );
}

int main() {
    init_logging("test.log");

    boost::log::sources::severity_logger<SeverityLevel> lg;
    BOOST_LOG(lg) << "A trace severity message";
}

记录例如

[[TODO:21]] {[Severity:0] @ } A message
[[TODO:21]] {[Severity:0] @ } A message
[[TODO:21]] {[Severity:0] @ } A message
[[TODO:21]] {[Severity:0] @ } A message
[[TODO:21]] {[Severity:0] @ } A message
© www.soinside.com 2019 - 2024. All rights reserved.