__func__ и ведение журнала

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

Я думаю, это не очень большая проблема, но я наткнулся на __func__ идентификатор, который в основном будет хранить имя функции текущей функции.

Так что у меня есть статическая функция в моем классе журнала называется Write, он занимает уровень журнала и список изменений. Я бы назвал это так:

Log::Write(LOG_DEBUG, "this is an integer: %d", 10);

и он напечатает:

2013-01-02 => 10:12:01.366 [DEBUG]: this is an integer: 10

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

2013... => 10:12:... (functionName) [DEBUG]: blah

Так что я могу сделать (конечно), чтобы добавить __func__ в качестве параметра для Log::WriteОднако это будет означать, что в любое время я звоню Log::Write Мне нужно также отправить __func__ что всегда будет одним и тем же, и я чувствую, что это можно сделать без явного указания.

Итак, что я хочу, это функциональность, которая будет обеспечена:

Log::Write(LOG_DEBUG, __func__, "message");

без необходимости явно набирать FUNC каждый раз.

Я не знаю, возможно ли это на самом деле, лучше всего я понимаю, что есть какой-то способ разыменования вызывающей стороны внутри функции WriteМаловероятно, что я могу просто «вывести» такой параметр. Но стоит хотя бы спросить, и, возможно, я смогу посмотреть, какие есть варианты.

Благодарю.

4

Решение

Обычно это делается с помощью макросов вместе с именем файла __FILE__ и номер строки __LINE__,

void Log::Write(Level l,
char const* function,
char const* file,
int line,
char const* format,
...);

оборачивается в макрос:

#define LOG(Level_, Format_, ...) \
Log::Write(Level_, __func__, __FILE__, __LINE__, Format_, __VA_ARGS__);

Обратите внимание, что вы можете «сохранить» некоторые вычисления, проверив, регистрироваться ли на этом уровне или нет:

// suppose availability of "bool Log::Enabled(Level l)"#define LOG(Level_, Format_, ...)   \
while (Log::Enabled(Level_)) {  \
Log::Write(Level_, __func__, __FILE__, __LINE__, Format_, __VA_ARGS__);  \
break;  \
}

Использование while вместо if это, чтобы избежать висящей проблемы.

Примечание: вы можете исследовать использование потоков для регистрации. Вопрос с printf Стиль в том, что он не является составным. С помощью потоков вы можете перегружать std::ostream& operator<<(std::ostream&, X const&) для любого X а потом только пиши один раз метод, чтобы сбросить его содержимое в журналах.

7

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

#define WRITE_LOG(X,...) Log::Write(LOG_DEBUG, __func__, (X),__VA_ARGS__);

Используйте этот макрос для записи логов вместо функции, и он автоматически добавит FUNC параметр. Как упоминает Мат, это типичный способ, я не могу придумать, как избежать макросов в этом случае.

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector