Техника для установки уровня трассировки отдельно для каждого исходного файла

Интересно, какой метод трассировки для вас самый лучший.
В настоящее время я определяю уровень трассировки для каждого исходного макроса ведьмы непосредственно перед включением заголовка трассы, который использует определенный макрос.

Например:
trace.h:

#if DEBUG == 0
#define debug(...)
#define trace(...)

#elif DEBUG==1
#define debug(...)
#define trace(...) printf(__VA_ARGS__)

#elif DEBUG==2
#define debug(...) printf(__VA_ARGS__)
#define trace(...) printf(__VA_ARGS__)

#else
#error Bad DEBUG value
#endif

Для всех sources.c (trace_value варьируется)

#define DEBUG trace_value
#include "trace.h"
void func(){
debug("func()");
trace("func() ok");
reurn;
}

Тем не менее, проект растет, и я хочу использовать предварительно скомпилированный заголовок. Было бы здорово включить заголовок трассировки в мой предварительно скомпилированный заголовок. Поэтому мне интересно, каковы ваши методы трассировки? Спасибо.

РЕДАКТИРОВАТЬ:
Я забыл написать важную вещь, мне интересна техника ведения журналов для приложений, критичных к задержкам.

2

Решение

Ведение журнала — сложная проблема, и то, что она делает / как вы ее используете, сильно зависит от потребностей вашего приложения.

В небольших приложениях я обычно использую либо вставленные ссылки std :: ostream, либо специальный код для регистрации. Я также держусь подальше от API-интерфейсов печати в формате C (и определяю свой собственный operator<< для вещей, которые мне нужно отследить).

В больших приложениях, если у вас есть сложные потребности в трассировке (чередование файлов журналов между выполнениями, журналы по категориям и возможность настройки извне приложения, автоматическое форматирование журналов, ведение журнала с высокой пропускной способностью / производительностью и т. Д.), Используйте внешнюю библиотеку (например, log4cpp).

Я также склонен использовать / определять макросы, только после того, как мой код может быть написан без них.

Пример реализации с внедренным потоком журналирования:

#include<iosfwd>

class http_server {
public:
http_server(std::string server, std::uint16_t listening_port,
std::ostream& log = cnull); // cnull is as defined at
// http://stackoverflow.com/a/6240980/186997
private:
std::ostream& log_;
};

Основной (консольный) код:

int main(...) {
http_server("localhost", 8080, std::clog);
}

Код юнит-теста:

std::ostringstream server_log;
http_server("localhost", 8080, server_log);
// assert on the contents of server_log

По сути, я считаю, что если мне нужно трассировать, это часть интерфейса API, а не запоздалая мысль, что-то, что я бы отключил с помощью макросов, или что-то для жесткого кода.

Если мне нужно отформатированное ведение журнала, я бы подумал о том, чтобы специализировать std :: ostream или (вероятнее всего) обернуть его в специализированный класс форматирования и внедрить его.

Макросы для трассировки кода обычно зарезервированы для кода, критичного к производительности (когда вы не можете позволить себе что-то называть, если он ничего не делает).

1

Другие решения


По вопросам рекламы [email protected]