【问题标题】:C++ boost log formaterC++ 提升日志格式化程序
【发布时间】:2020-04-20 15:28:27
【问题描述】:

我使用 boost v1.60 并尝试编写一个函数来初始化和配置 boost::log,但我遇到了一个我无法解释的奇怪行为。我调用以下函数。

更新:我忘了提到我的记录器是在 DLL 中定义的,并且我尝试通过 DLL API 推送格式化程序。如果从 DLL 内部定义和设置,格式化程序本身就可以完美地工作。

using formater_cb_t = boost::function<void(boost::log::record_view const&, boost::log::formatting_ostream& strm)>;
using filter_cb_t = boost::function<bool(const boost::log::attribute_value_set&)>;  
void AddCustomConsoleLogging(const formater_cb_t& formater_func, const filter_cb_t& filter_func) {
    auto pSink = boost::log::add_console_log(std::cout);
    pSink->set_formatter(formater_func);
    pSink->set_filter(filter_func);
  }

我尝试推送 2 个 lambda,如下所示:

void AddCustomConsoleLogging(
      [](boost::log::record_view const& rcrd, boost::log::formatting_ostream& strm)-> void {
      namespace blog = boost::log;
      auto attr_set = rcrd.attribute_values();

      if (rcrd[boost::log::expressions::smessage]) {
        strm = *rcrd[boost::log::expressions::smessage] << ",";
      }
      if (attr_set["EventLevel"]) {
        strm << level_to_string(attr_set["EventLevel"].extract<Framework::EventLevel>().get());
        strm << ",";
      }
      },
      [](const boost::log::attribute_value_set& attr_set)->bool {return true; }
    );

问题在于 formater lambda。如果我使用以下代码在命令行输出上触发一些日志行,它会因断言log/utility/value_ref.hpp, line 150 而失败。事实上,我可以运行并打印所有EventLevel 或所有message,但不能同时打印这两件事!

BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(LoggerImpl, boost::log::sources::severity_logger_mt<EventLevel>)
const std::string buf = "test message !";
BOOST_LOG_SEV(LoggerImpl::get(), TRACE) << message;

【问题讨论】:

  • 能否添加回溯以显示触发断言的位置?

标签: c++ boost-log


【解决方案1】:

由于没有给出回溯,我无法确定问题出在哪里。但是,我可以说对“EventLevel”属性值的处理不正确,可能会导致您看到的断言失败。

if (attr_set["EventLevel"]) 检查仅测试日志记录中是否存在名为“EventLevel”的属性值,但不检查其类型。这意味着后续的extract&lt;Framework::EventLevel&gt;()可能会返回一个空值引用,这将触发get上的断言失败。

我不确定实际发生的情况,因为您没有显示完整的代码,特别是,“EventLevel”没有添加到您显示的代码中的任何位置。

测试属性值是否存在的正确方法是检查提取的值引用是否为空。通过利用属性关键字,对smessage 的第一次检查是正确的,尽管效率低下。你也可以对“EventLevel”做同样的事情。

// Declare a keyword for the EventLevel attribute
BOOST_LOG_ATTRIBUTE_KEYWORD(a_event_level, "EventLevel", EventLevel)

void AddCustomConsoleLogging(
      [](boost::log::record_view const& rcrd, boost::log::formatting_ostream& strm)-> void {
      auto msg = rcrd[boost::log::expressions::smessage];
      if (msg) {
        strm << *msg << ",";
      }

      auto lvl = rcrd[a_event_level];
      if (lvl) {
        strm << level_to_string(*lvl);
        strm << ",";
      }
      },
      [](const boost::log::attribute_value_set& attr_set)->bool {return true; }
    );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多