Средство ведения журнала C / C ++, которое поддерживает вызовы условных функций в зависимости от уровня журнала - PullRequest
4 голосов
/ 27 марта 2012

Некоторые исследования существующих решений для ведения журналов C / C ++ показали, что Pantheios может быть лучшим в моем случае, что является минимальными издержками, если ведение журнала отключено.

Кажется, что все регистраторыподдерживать вид сообщения журнала печати.Тем не менее, в моем случае у меня есть вызов функции, которого следует избегать, если ведение журнала отключено (поскольку это довольно дорого).

В настоящее время я использую очень простую настройку регистрации, такую ​​как

#ifdef DEBUG_L1    
cout << "msg 1" << endl // log level 1
#ifdef DEBUG_L2
printBuffer()           // log level 2
#endif
#endif

Он служит моим потребностям (на данный момент), так как я плачу нулевые накладные расходы, если регистрация отключена.Однако код быстро выглядит некрасивым и не очень гибким.

Это должно быть реализовано с помощью регистратора C ++.Как сказано, тело функции printBuffer() довольно дорого.Было бы хорошо, если бы его можно было избежать, если ведение журнала отключено.

Можно ли объявить весь вызов функции только для выполнения, когда он находится выше определенного уровня журнала?Или мне все еще нужен препроцессор в этом случае?

Редактировать:

Спасибо @BobTFish.Я на самом деле думал об использовании типа установки, которую вы описываете.Мне интересно, насколько гибко можно реализовать подобные вещи.Обычно я регистрирую набор строк и значений (int, float и указатели).В стиле

cout << "name1=" << int << " name2=" << (void*)(ptr) << endl;

Теперь я действительно не люблю переключаться на printf подобный синтаксис на данном этапе.Как с этим справится макроподход (поскольку он шаблонируется только одним параметром класса)?

Ответы [ 3 ]

2 голосов
/ 11 апреля 2016

Что мне приходит в голову, так это специфичные для c ++ каркасы журналов на основе шаблонов, такие как easylogging или spdlog. Например, в spdlog вы можете создавать собственные цели журналов, реализуя интерфейс приемника. Другой (может быть, лучший) вариант - использовать функцию уровня журнала.

Вот пример (скопировано из руководства spdlog):

    //
    // Runtime log levels
    //
    spd::set_level(spd::level::info); //Set global log level to info
    console->debug("This message shold not be displayed!");
    console->set_level(spd::level::debug); // Set specific logger's log level
    console->debug("Now it should..");

Реализуя оператор << для собственного пользовательского класса, вы можете контролировать, какие данные выгружаются в журнал. С <code>logger->should_log() вы можете проверить, включен ли указанный уровень журнала.

1 голос
/ 01 февраля 2016

Если вы беспокоитесь о производительности и накладных расходах во время выполнения, взгляните на библиотеку zf_log .Вещи, которые вам могут понравиться:

  • Он оценивает аргументы журналирования и вызывает фактическую функцию журналирования только тогда, когда это необходимо (когда уровень журнала позволяет это).
  • Он имеет уровень журнала во время выполнения Иуровень журнала времени компиляции.LOG() операторы ниже уровня журнала времени компиляции компилируются и не имеют никаких накладных расходов во время выполнения.
  • Уровень журнала времени выполнения может быть изменен во время выполнения, но когда уровень журнала сообщений ниже времени выполненияуровень журнала, аргументы не будут оцениваться, и фактическая функция журнала не будет вызвана.Единственное, что будет оценено, - это if (msg_log_level >= runtime_log_level).
  • У него очень маленький сайт вызовов (количество кода, сгенерированного на каждую LOG() строку), в 3–20 раз меньше, чем у других библиотек.
  • Это не замедляет компиляцию ваших источников, которые включают его заголовки (в отличие от некоторых библиотек только для заголовков).
1 голос
/ 05 августа 2014

Я думаю, вы можете использовать библиотеку журналов Google с здесь

Типичное использование glog с условием

#include <glog/logging.h>

{
  // Initialize logging. There are multiple options, so read the documentation
  google::InitGoogleLogging();

  void* p;
  LOG_IF(INFO, p == nullptr) << "We have nullptr. Bomb detected!";

  // Don't forget to shut that down
  google::ShutdownGoogleLogging();
}
...