Трассировка с отступом в C ++ - PullRequest
1 голос
/ 02 июня 2011

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

 void FunctionA()
{
     TR_ENTER("Function A");
     TR_PRINT("Dignostic message Function A");
     FunctionB(); // Call function B   
}

 void FunctionB()
{
    TR_ENTER("Function B");
    TR_PRINT("Dignostic message Function B");
    FunctionC(); // Call function B  
}

void FunctionC()
{
   TR_ENTER("Function C");
   TR_PRINT("Dignostic message Function C");          
}

Как вы видите вышеупомянутые вызовы вложены друг в друга.Я хочу создать журнал трассировки, как показано ниже:

Function A - Start
Dignostic message Function A
     Function B - Start
     Dignostic message Function B
            Function C - Start
            Dignostic message Function C
            Function C - End
     Function B - End
Function A - End

TR_ENTER и TR_PRINT - это некоторые макросы, которые я использую в качестве примера.Чтобы сказать, что функция запускалась, я использовал TR_ENTER, а для печати некоторых сообщений с достоинствами я использовал TR_PRINT.

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

Спасибо, Омки

Ответы [ 2 ]

7 голосов
/ 02 июня 2011

Вам необходимо отслеживать глубину вызова:

class trace_entry;

class trace_log {
public:
    trace_log() : depth_(0) { }

private:
    // noncopyable so we don't accidentally copy it
    trace_log(trace_log&);
    void operator=(trace_log);

    friend trace_entry;

    int depth_;
};

class trace_entry {
public:
    trace_entry(trace_log& log, const std::string& frame)
        : log_(log), frame_(frame) {
        std::cout << std::string(4 * log.depth_, ' ') 
                  << "ENTER " << frame_ << std::endl;
        ++log_.depth_;
    }

    ~trace_entry() {
        --log_.depth_;
        std::cout << std::string(4 * log_.depth_, ' ') 
                  << "EXIT " << frame_ << std::endl;
    }
private:
    // noncopyable so we don't accidentally copy it
    trace_entry(trace_entry&);
    void operator=(trace_entry);

    trace_log& log_;
    std::string frame_;
};

Пример использования:

void a(trace_log& log) {
    trace_entry e(log, "a");
}

void b(trace_log& log) { 
    trace_entry e(log, "b");
    return a(log);
}

int main() {
    trace_log log;
    trace_entry e(log, "main");
    b(log);
}

Вывод:

ENTER main
    ENTER b
        ENTER a
        EXIT a
    EXIT b
EXIT main

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

0 голосов
/ 02 июня 2011

Существует множество библиотек журналов для C ++, в частности, я могу порекомендовать Log4cxx .Они помогут вам создать и настроить вывод сообщений журнала вашего приложения.Для анализа файлов журнала вам понадобится дополнительный инструмент, например Apache Chainsaw .

См. Также Есть ли анализатор файлов журнала для файлов log4j?

...