How to write a logging function or macro that can add the caller's name to the log output in C

I need a register function or a C macro that needs to work on Linux, that can take a format string and a list of arguments, and can add the name of the caller function to the output string.

Here's an example. Suppose the logging function (macro) is called smart_log. It looks like this:

smart_log(const char *fmt, ...)

      

The first argument to fmt is a format string, just like the format string in printf. The next fmt is a list of additional arguments to feed fmt.

Suppose a function called example_function calls smart_log like this:

void example_function() {
    smart_log("try to output number %d\n", 1);
}

      

Then the log line looks like this:

[example_function]: try to output number 1

      

So the key point is that smart_log adds the caller function to the format string.

I'm not sure how to do this in C. I think a macro can be used to achieve this.

+3


source to share


4 answers


There is no portable way for a function to know its caller in C. But you're right, the macro works:

#define smart_log(...) ( printf("[%s]: ", __func__) , printf(__VA_ARGS__) )

      

__func__

defined (C99 / C11 6.4.2.2 s .1)



as if, immediately after opening the parenthesis of each function definition, the declaration

static const char __func__

[] = " -";


where function -name is the name of the lexically enclosing function.


Thanks to Hagen von Eitzen for improving my initial attempt!

+6


source


This is very system / compiler dependent, as the exact mapping to get the function name is very compiler dependent. For Visual C ++, you have to use a macro __FUNCTION__

to get the current function name at compile time.

To make sure you register the function name correctly without putting the macro in every call smart_log

, you can call the logging function through the macro so that the macro that gets the function name is evaluated in the correct context - if you just add the macro to the function name, you always get the name of your logging function ...

So instead of calling this:

smart_log("log message");

      

You are calling:



smart_log("log message");

      

Which in turn is defined as follows:

#define SMART_LOG(message) smart_log(__FUNCTION__, message)

      

This is due to the assumption that your log function takes a function name as the first parameter, so customize it.

+2


source


If you don't want to use macros, you can use a stack for this. The function smart_log

will only be above the function that called it.

See How can you capture a stack trace in C?

+2


source


Define macros - SMART_LOG - which transmits __FILE__

, __FUNCTION__

and __LINE__

in smart_log

as arguments. Then whenever you use smart_log

it will automatically provide the smart_log

caller location code. Note, however, which __FUNCTION__

is non-standard but available in GCC (and Visual C, so I'm in luck): fooobar.com/questions/53460 / ... ).

+1


source







All Articles