Средство форматирования журналов повышения C++

Я использую boost v1.60 и пытаюсь написать функцию для инициализации и настройки boost::log, но сталкиваюсь со странным поведением, которое не могу объяснить. Я вызываю следующую функцию.

ОБНОВЛЕНИЕ: я забыл упомянуть, что мой регистратор определен в DLL и что я пытаюсь протолкнуть средство форматирования через API DLL. Сам форматер отлично работает, если его определить и установить изнутри 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 лямбды, как показано ниже:

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; }
    );

Проблема связана с лямбдой former. Если я использую следующий код для запуска некоторой строки журнала в выводе командной строки, это приведет к ошибке с утверждением log/utility/value_ref.hpp, line 150. На самом деле я могу запустить и распечатать все EventLevel или все message, но не 2 вещи одновременно!

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;

person alexbuisson    schedule 20.04.2020    source источник
comment
Не могли бы вы добавить обратную трассировку, чтобы показать, где срабатывает утверждение?   -  person Andrey Semashev    schedule 21.04.2020


Ответы (1)


Поскольку обратная трассировка не указана, я не могу точно сказать, в чем проблема. Однако я могу сказать, что обработка значения атрибута EventLevel неверна и может привести к ошибке утверждения, которую вы видите.

Проверка if (attr_set["EventLevel"]) проверяет только наличие значения атрибута с именем "EventLevel" в записи журнала, но не проверяет его тип. Это означает, что последующий extract<Framework::EventLevel>() может вернуть ссылку на пустое значение, что приведет к ошибке утверждения в 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; }
    );
person Andrey Semashev    schedule 21.04.2020