Visual C++ Developer Center > Visual C++ Forums > Visual C++ General > reporting logging error messages
Ask a questionAsk a question
 

Answerreporting logging error messages

  • Saturday, November 07, 2009 9:16 AMsteve1_rm Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hello,

    I would like to log messages and have decided to use the following format. However, as I am coming from C# I am not too sure how to go any further.

    Basically I have the following messages that I would like to report on.
    //Enum for the error codes
    typedef enum
    {
        DEV_START_ERR = 0,
        LIB_ERR,
        SDD_FAILURE,
    
    LAST_ENTRY //This SHOULD be the last entry
    
    } ErrorCode;
    
    And using this for displaying but I am not sure how I would get this to work.

    void log_msg(FILE *out, const char *fmt, ...)
    {
        va_list ap;
        va_start(ap_fmt);
        vfprintf(out, fmt, ap);
        va_end(ap);
    }
    
    log_msg(stderr,
        "%s: Invalid range of %ld near line %d", __func__, range, __LINE__);
    

    Many thanks for any advice,



Answers

  • Monday, November 09, 2009 3:43 PMWyck Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Variable number of arguments and automatic parameters, eh?  Well it's not going to be pretty.

    The preprocessor will help you get the function and line encoded into your call based on context.  But the variable arguments have to be double parenthesized.

    Here's a little gem I've used a few times.

    #include <stdarg.h>
    #include <stdio.h>
    
    #define LogMessage( x ) Context(__FUNCTION__,__LINE__) x
    
    class Context
    {
    	const char* fn;
    	int line;
    public:
    	Context( const char* fn, int line ) : fn(fn),line(line) {}
    	void operator()( const char* format, ... )
    	{
    		printf( "%s(%d): ", fn, line );
    		va_list args;
    		va_start(args,format);
    		vprintf( format, args );
    		va_end( args );
    		printf("\n");
    	}
    };
    
    
    int main( void )
    {
    	LogMessage(( "%d %s %d", 100,  "hello", 200 ));
    }
    
  • Monday, November 09, 2009 10:58 AMWesley YaoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Hello,

    Seeing from the code, log_MSG() is a "variable argument" function to log information, you just need to use log_MSG like the CRT function printf():

    log_MSG(stderr, "Error Code: %d, Func: %s, Range: %s, Line: %d", DEV_START_ERR, "Function Name", "Range text", LineNo);

    Sincerely,
    Wesley
    Please mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.

All Replies

  • Saturday, November 07, 2009 5:11 PMsteve1_rm Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hello,

    I don't think I very clear.

    I have re-edited my source code with what I am having a problem.

    typedef enum
    {
        DEV_START_ERR,
        LIB_ERR,
        SDD_FAILURE,
        Last_ENTRY
    } ErrorCode;
    
    void log_MSG(FILE *out, const char *fmt, ...)
    {
        va_list ap;
        va_start(ap, fmt);
        vfprintf(out, fmt, ap);
        va_end(ap);
    }
    
    int main(void)
    {
        if(dev_start() != DEV_SUCCESS)
        {
            /* print error message here with the __func__, range, and __LINE__ */
            /* However, I am not sure how to add __func__, range, and the __LINE to print this on the screen */
            log_MSG(stderr, "Error code: %d", DEV_START_ERR);        
        }
        return 0;
    }
    
    Many thanks for any suggestions,

  • Monday, November 09, 2009 10:58 AMWesley YaoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Hello,

    Seeing from the code, log_MSG() is a "variable argument" function to log information, you just need to use log_MSG like the CRT function printf():

    log_MSG(stderr, "Error Code: %d, Func: %s, Range: %s, Line: %d", DEV_START_ERR, "Function Name", "Range text", LineNo);

    Sincerely,
    Wesley
    Please mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Monday, November 09, 2009 3:43 PMWyck Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Variable number of arguments and automatic parameters, eh?  Well it's not going to be pretty.

    The preprocessor will help you get the function and line encoded into your call based on context.  But the variable arguments have to be double parenthesized.

    Here's a little gem I've used a few times.

    #include <stdarg.h>
    #include <stdio.h>
    
    #define LogMessage( x ) Context(__FUNCTION__,__LINE__) x
    
    class Context
    {
    	const char* fn;
    	int line;
    public:
    	Context( const char* fn, int line ) : fn(fn),line(line) {}
    	void operator()( const char* format, ... )
    	{
    		printf( "%s(%d): ", fn, line );
    		va_list args;
    		va_start(args,format);
    		vprintf( format, args );
    		va_end( args );
    		printf("\n");
    	}
    };
    
    
    int main( void )
    {
    	LogMessage(( "%d %s %d", 100,  "hello", 200 ));
    }
    
  • Wednesday, November 18, 2009 3:05 PMWyck Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    You could also use a variadic macro :

    #define LogMessage( x, ... ) Something( __FUNCTION__,__LINE__, x, __VA_ARGS__ )

    and define Something( const char* fn, int line, char* format, ... )
    {
       printf( "%s(*%d): ", fn, line );
       va_list args;
       va_start( args, format );
       vprintf( format, args );
       va_end( args );
       printf( "\n" );
    }