Results 1 to 5 of 5
Hi,
I have a function for logging purposes in c used by my applications. Now I want to incorporate logging levels to log messages of the category configured.
So I ...
- 04-13-2010 #1Just Joined!
- Join Date
- Apr 2010
- Posts
- 18
logging levels in C
Hi,
I have a function for logging purposes in c used by my applications. Now I want to incorporate logging levels to log messages of the category configured.
So I am thinking 3 levels of logging 0 for basic msgs and any errors, 1 for some more and 2 for low level debugging. I have 2 methodologies in mind for this and would like some input on which is better and more efficient or if you can suggest a better new method, please do.
1. have 3 #defines for the 3 levels say DEBUG_ONE, DEBUG_TWO,DEBUG_THREE and at each log call based on the logging level i wud check for that #define so if that is a basic msg I would say
#ifdef DEBUG_ONE
log....
#endif
and ofcourse in the header I would #define or undef them.
2. pass a parameter to the log function and check it inside the log function. validate it against the set config value and if yes, print it.
Thanks,
- 04-13-2010 #2
The only way that I could see doing the #define method would be to have multiple functions, that would work something like:
This prevents debugging from being set programmatically and prevents, for instance, config files.Code:#ifdef DEBUG_ONE #define debug_one(...) fprintf(stderr, __VA_ARGS__) #else #define debug_one(...) ; #endif
For these reasons, I suggest using the function-based one.
I would note that there is already a library that does this called log4c:
log4c: Log4c : Logging for C Library
This is based on log4j, which is essentially the standard logging facility for Java.DISTRO=Arch
Registered Linux User #388732
- 04-14-2010 #3Just Joined!
- Join Date
- Apr 2010
- Posts
- 18
Can you explain a little more on how you mean for the #define to work in your method. Sorry but I dont understand what u mean by calling debug_one function in both and then fprintf in one case..thank you in advance
- 04-14-2010 #4
So by using #define, there are basically two routes that you can take. One is to handle the log level in one location, and the other is to handle it everywhere. The first case is what I showed:
Now in your code:Code:#ifdef DEBUG_ONE #define debug_one(...) fprintf(stderr, "LOG LEVEL 1: " __VA_ARGS__) #else #define debug_one(...) ; #endif
Whether the debug_one() output will actually appear is controlled by the define at the top of the file. This means that you can just call debug_one() whenever you want, and if DEBUG_ONE was defined for the file, the output will print. Otherwise it will not.Code:int foo(int bar) { debug_one("bar is %d\n", bar); ... debug_one("about to return %d\n", retval); return retval; }
The second approach (which may be what you were thinking of) would be to do this:
It should be obvious why this is an inferior solution. In the first solution, you only need to have the check for the DEBUG_ONE macro in a single place, whereas here you have to check for it whenever you want to print out debug information.Code:int foo(int bar) { #ifdef DEBUG_ONE fprintf(stderr, "bar is %d\n", bar); #endif ... #ifdef DEBUG_ONE fprintf(stderr, "about to return %d\n", retval); #endif return retval; }
If you were to use the first solution I gave, this works reasonably well for a single project that is reasonably contained (I'm actually using it for a project right now). However, if you want to create a more fully-featured system, you will find a function-based parameter solution a bit better, I think. Something like:
The "logger" function could then check for whether DEBUG_ONE output is currently enabled. The cool thing about such a system is that these values could be configured from sort of external configuration file, like how log4c works (it uses a combination of config files and programmatic configuration).Code:logger(DEBUG_ONE, "bar is %d\n", bar);
Does this help at all?DISTRO=Arch
Registered Linux User #388732
- 04-14-2010 #5Just Joined!
- Join Date
- Apr 2010
- Posts
- 18
Thanks! I definitely got a better picture.
Herez the thing though.. I plan on having 3-4 levels of logging.
0 - Basic mesgs
1 - Level 1 troubleshooting (tracing the application flow)
2 - Level 2 troubleshooting (printing variable values etc at higher levels)
3 - Level 3 (printing more detailed stuff)
So based on the situation I could update my file to say this level and the application would log msgs of that category and lower
So in the first scenario you mentioned I could not implement it without 4 functions for logging.
That leaves me with the 2nd and 3rd scenario..now my qn is which is more efficient..more macros or more function calls.
I thought about passing a parameter in the logMessage function but I was not sure if the function overhead caused by each time invoking it and passing all the parameters and then checking if reqd and returning ...though neater...is it better compared to checking macro definition at each level.
Ofcourse if you have a solution to maintain the 4 levels and just do 1 check at 1 level that would be excellent.
Thank you...


Reply With Quote