HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerate

Generic logging class for tracing the function calls

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
callsgenericloggingthefunctionforclasstracing

Problem

#include
#include
using namespace std;

// Generic class for tracing the function call
class functionlogging {
private:
    string name;
    string in{ ">>" };
    string out{ "<<" };
public:
    functionlogging(string x) :name(x) {
        cout << in << name << endl;
    }
    ~functionlogging(){
        cout << out << name << endl;
    }
};

//uses
void generic_function() {
    functionlogging logger{ __func__ };
    int a = 10;
    int b = 100;
    a += b;
}

int main() {
    generic_function();
}


Many times, we do need to log when function call starts and ends for better understanding. With modern C++ concepts like __funct__/RAII, I wrote the small class which can be used to achieve trace. With this I was able to achieve this for above "generic_function()".

Output

>>generic_function
<<generic_function


I wanted others opinion about the functionlogging class and how to make it in such a way that user of this class would have to do the minimal work/code changes in his/her code base.

At present user of this class needs to create a object of this class and pass the __func__ information. Is it acceptable or in a way can it be embed inside something by which user of the class almost do not require to do anything?.

Solution

Stop doing this:

using namespace std;


see: Why is “using namespace std;” considered bad practice?

These two are not unique to the class.

string in{ ">>" };
string out{ "<<" };


May as well make them static. Also they re never modified so make them const.

No need to force a flush with std::endl

cout << in << name << endl;


Prefer "\n" when you don't need a flush (also cerr or clog may be better choices of output stream).

That seems like an overly verbose and error prone way of use.

void generic_function() {
    functionlogging logger{ __func__ };


You have to use up a variable and remember __func__. Can't we get a macro in here to do all the for you? I actually need to look up to see if func is a standard macro.

Just checked the standard:

8.4.1 In general
Paragrah 8:
The function-local predefined variable __func__ is defined as if a definition of the form  

static const char __func__[] = "function-name ";


So I would define the macros:

#define LOG_ENTRY_EXIT_FOR(x)       functionlogging  SomeLongNameThatIsNotLikelyToBeUsedInTheFunctionlogger(x)
#define LOG_ENTRY_EXIT              LOG_ENTRY_EXIT_FOR(__func__)


Then usage is simply:

void generic_function() {
    LOG_ENTRY_EXIT;

    int a = 10;
    int b = 100;
    a += b;
}

Code Snippets

using namespace std;
string in{ ">>" };
string out{ "<<" };
cout << in << name << endl;
void generic_function() {
    functionlogging logger{ __func__ };
8.4.1 In general
Paragrah 8:
The function-local predefined variable __func__ is defined as if a definition of the form  

static const char __func__[] = "function-name ";

Context

StackExchange Code Review Q#66417, answer score: 10

Revisions (0)

No revisions yet.