/* Ajith - Syntax Higlighter - End ----------------------------------------------- */

8.07.2010

Printing logs based on log levels in C

LOG LEVELS ??
As per my definition LOG LEVEL means a way to differentiate the importance of logs in our application. We can divide the logs into categories based on their importance and effect for e.g. ERROR logs are more important than DEBUG logs.


Why do we need to print logs based on LOG LEVEL ??
It is really helpful in projects with millions of lines of source code where the user can't use #defines or #ifdef's in order to maintain DEBUG prints. It is really tiresome to maintain #defines and #ifdef atleast for printing logs.

printk which is a part of LINUX KERNEL supports printing logs based on LOG LEVEL and it is really helpful in debugging kernel.

printf or any of its brothers & sisters don't support the option to print logs depending upon the log levels.

I have written a sample program where we can create our own printf function with LOG LEVEL. At present I am just supporting the option to print a character, string and a integer.
#include <stdio.h>
#include <stdarg.h>

//LOG LEVELS
typedef enum
{
  LOG_DEFAULT,
  LOG_INFO,
  LOG_ERROR,
  LOG_DEBUG
}LOG_LEVEL;
 
void LOG_TRACE(LOG_LEVEL lvl, char *fmt, ... );

int main()
{
  int i =10;
  char *string="Hello World";
  char c='a';
       
  LOG_TRACE(LOG_INFO, "String - %s\n", string);
  LOG_TRACE(LOG_DEBUG, "Integer - %d\n", i);
  LOG_TRACE(LOG_INFO, "Character - %c\n", c);
       
  LOG_TRACE(LOG_INFO, "\nTOTAL DATA: %s - %d - %c\n", string, i, c);
  return 1;
}

/* LOG_TRACE(log level, format, args ) */
void LOG_TRACE(LOG_LEVEL lvl, char *fmt, ... )
{
  va_list  list;
  char *s, c;
  int i;

  if( (lvl==LOG_INFO) || (lvl==LOG_ERROR))
  {
     va_start( list, fmt );

     while(*fmt)
     {
        if ( *fmt != '%' )
           putc( *fmt, stdout );
        else
        {
           switch ( *++fmt )
           {
              case 's':
                 /* set r as the next char in list (string) */
                 s = va_arg( list, char * );
                 printf("%s", s);
                 break;

              case 'd':
                 i = va_arg( list, int );
                 printf("%d", i);
                 break;

              case 'c':
                 c = va_arg( list, int);
                 printf("%c",c);
                 break;

              default:
                 putc( *fmt, stdout );
                 break;
           }
        }
        ++fmt;
     }
     va_end( list );
  }
  fflush( stdout );
}

No comments :

Post a Comment

Your comments are moderated