如何在boost log 2.0中记录编码器的行号?

Dea*_*hen 9 boost-log

我可以使用LineID属性吗?我希望我可以使用sink :: set_formatter来执行此操作而不是使用

__LINE__
Run Code Online (Sandbox Code Playgroud)

__FILE__
Run Code Online (Sandbox Code Playgroud)

在每个日志语句中.

Chr*_*ris 11

我一直在努力,直到找到这个片段

#define LFC1_LOG_TRACE(logger) \
BOOST_LOG_SEV(logger, trivial::trace) << "(" << __FILE__ << ", " << __LINE__ << ") "
Run Code Online (Sandbox Code Playgroud)

奇迹般有效


Hor*_*rus 6

LineID属性是一个序列号,对于每个日志记录消息都会递增.所以你不能使用它.

您可以使用属性来记录行号等.这允许您使用格式字符串进行灵活格式化,而使用Chris'回答您的格式是固定的.

在日志记录初始化函数中注册全局属性:

using namespace boost::log;
core::get()->add_global_attribute("Line", attributes::mutable_constant<int>(5));
core::get()->add_global_attribute("File", attributes::mutable_constant<std::string>(""));
core::get()->add_global_attribute("Function", attributes::mutable_constant<std::string>(""));
Run Code Online (Sandbox Code Playgroud)

在日志记录宏中设置这些属性:

#define logInfo(methodname, message) do {                           \
    LOG_LOCATION;                                                       \
    BOOST_LOG_SEV(_log, boost::log::trivial::severity_level::info) << message; \
  } while (false)

#define LOG_LOCATION                            \
  boost::log::attribute_cast<boost::log::attributes::mutable_constant<int>>(boost::log::core::get()->get_global_attributes()["Line"]).set(__LINE__); \
  boost::log::attribute_cast<boost::log::attributes::mutable_constant<std::string>>(boost::log::core::get()->get_global_attributes()["File"]).set(__FILE__); \
  boost::log::attribute_cast<boost::log::attributes::mutable_constant<std::string>>(boost::log::core::get()->get_global_attributes()["Function"]).set(__func__);
Run Code Online (Sandbox Code Playgroud)

不是很漂亮,但它有效,对我来说还有很长的路要走.可惜的是,并没有提供开箱即用的功能.

do {...} while(false)是使宏在语义上保持中立.


小智 5

Chris展示的解决方案有效,但如果您想自定义格式或选择在每个接收器中显示哪些信息,则需要使用可变常量属性:

   logging::core::get()->add_global_attribute("File", attrs::mutable_constant<std::string>(""));
   logging::core::get()->add_global_attribute("Line", attrs::mutable_constant<int>(0));
Run Code Online (Sandbox Code Playgroud)

然后,您创建一个包含这些新属性的自定义宏:

// New macro that includes severity, filename and line number
#define CUSTOM_LOG(logger, sev) \
   BOOST_LOG_STREAM_WITH_PARAMS( \
      (logger), \
         (set_get_attrib("File", path_to_filename(__FILE__))) \
         (set_get_attrib("Line", __LINE__)) \
         (::boost::log::keywords::severity = (boost::log::trivial::sev)) \
   )

// Set attribute and return the new value
template<typename ValueType>
ValueType set_get_attrib(const char* name, ValueType value) {
   auto attr = logging::attribute_cast<attrs::mutable_constant<ValueType>>(logging::core::get()->get_global_attributes()[name]);
   attr.set(value);
   return attr.get();
}

// Convert file path to only the filename
std::string path_to_filename(std::string path) {
   return path.substr(path.find_last_of("/\\")+1);
}
Run Code Online (Sandbox Code Playgroud)

下一个完整的源代码创建两个接收器。第一个使用 File 和 Line 属性,第二个不使用。

#include <boost/log/trivial.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/attributes/mutable_constant.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/attributes/mutable_constant.hpp>

namespace logging  = boost::log;
namespace attrs    = boost::log::attributes;
namespace expr     = boost::log::expressions;
namespace src      = boost::log::sources;
namespace keywords = boost::log::keywords;

// New macro that includes severity, filename and line number
#define CUSTOM_LOG(logger, sev) \
   BOOST_LOG_STREAM_WITH_PARAMS( \
      (logger), \
         (set_get_attrib("File", path_to_filename(__FILE__))) \
         (set_get_attrib("Line", __LINE__)) \
         (::boost::log::keywords::severity = (boost::log::trivial::sev)) \
   )

// Set attribute and return the new value
template<typename ValueType>
ValueType set_get_attrib(const char* name, ValueType value) {
   auto attr = logging::attribute_cast<attrs::mutable_constant<ValueType>>(logging::core::get()->get_global_attributes()[name]);
   attr.set(value);
   return attr.get();
}

// Convert file path to only the filename
std::string path_to_filename(std::string path) {
   return path.substr(path.find_last_of("/\\")+1);
}

void init() {
   // New attributes that hold filename and line number
   logging::core::get()->add_global_attribute("File", attrs::mutable_constant<std::string>(""));
   logging::core::get()->add_global_attribute("Line", attrs::mutable_constant<int>(0));

   // A file log with time, severity, filename, line and message
   logging::add_file_log (
    keywords::file_name = "sample.log",
    keywords::format = (
     expr::stream
      << expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d_%H:%M:%S.%f")
      << ": <" << boost::log::trivial::severity << "> "
      << '['   << expr::attr<std::string>("File")
               << ':' << expr::attr<int>("Line") << "] "
      << expr::smessage
    )
   );
   // A console log with only time and message
   logging::add_console_log (
    std::clog,
    keywords::format = (
     expr::stream
      << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
      << " | " << expr::smessage
    )
   );
   logging::add_common_attributes();
}

int main(int argc, char* argv[]) {
   init();
   src::severity_logger<logging::trivial::severity_level> lg;

   CUSTOM_LOG(lg, debug) << "A regular message";
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

该语句CUSTOM_LOG(lg, debug) << "A regular message";生成两个输出,以这种格式写入日志文件...

2015-10-15_15:25:12.743153: <debug> [main.cpp:61] A regular message
Run Code Online (Sandbox Code Playgroud)

...并输出到控制台:

2015-10-15 16:58:35 | A regular message
Run Code Online (Sandbox Code Playgroud)