我正在尝试找到一种最简单的方法来更改时间戳的输出。这就是我初始化日志库的方式
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?
我为什么需要这个是为了自定义时间戳的写入方式。我知道还有其他方法可以完全不同地做到这一点,例如设置接收器格式化程序。我想使用字符串格式模板,如本示例所示。
首先,你要求“最简单的方法” - 我认为这是来自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 技巧将会发挥作用:
#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