Saturday 19 January 2013

How to Implement the Debug Logging Mechanisms for Real Time Applications

In this post, I would like to introduce with the "DEBUG LOGGING MECHANISM" for real time applications.

To debug any code, Developer always depend on the LOGS (i.e. prints) which gives useful info about that application.

In case of real time applications, displaying too many LOGS while running the application is not a good idea. ( In real time traffic applications, having too many prints may lead application to CRASH.)

Then what is the way to LOG the prints in real time applications? Solution is that all prints(LOGS) should be under some DEBUG MACROS and it get enabled whenever user need to debug the issue.

Developer can enable the prints based on the Levels ( In other words user can get selective prints).

I have written sample program to demonstrate the "DEBUG LOG MECHANISM" . There are two files debug.h and sample_program.cc.  debug.h contains the debug LOG Mechanism logic. 

Compile sample_program.cc using  " c++  sample_program.cc -o test.exe" 

 
debug.h

/* Initialized to Zero , It can extended as unsigned long*/
unsigned char application_debug;


#define ENABLE_DEBUG_FLAG_LEVEL_0       (1 << 0)
#define ENABLE_DEBUG_FLAG_LEVEL_1       (1 << 1)

/*  Generally LOGS are enabled during RUN TIME
 *  ENABLE DEBUG LOGS */
#define MUNI_DEBUG_ON(value)  (application_debug |= ENABLE_DEBUG_FLAG_ ##value)

/* OFF DEBUG LOGS */
#define MUNI_DEBUG_OFF(value) (application_debug &= ~ENABLE_DEBUG_FLAG_ ##value)

/* Here application_debug is initialized to Zero.

*  When code calls this Macro MUNI_DEBUG(LEVEL_0) leads to  application_debug &         
*   ENABLE_DEBUG_FLAG_ ## =  application_debug & ENABLE_DEBUG_FLAG_LEVEL_0 
*   (##" concatenates the Value given in Macro)
*/
 
#define MUNI_DEBUG(value)  (application_debug & ENABLE_DEBUG_FLAG_ ## value)


/* Define LOG_DEBUG */
#define LOG_DEBUG(fmt, args...)  \
    printf(fmt, ##args)



sample_program.cc


#include<iostream.h>
#include "debug.h"
int main()
{
    int X, level;  
 do
  { 
    cout<<endl<<" Enter The Value of X"<<endl;
    cin>>X;

    cout<<endl<<"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"<<endl;
    cout<<" Enter which debug Level LOG to be Enable/Disable in application"<<endl;
    cout<<" HELP : ON  : level == 1 = LEVEL_0, level == 2 = LEVEL_1 "<<endl;
    cout<<"        OFF : level == 3 = LEVEL_0, level == 4 = LEVEL_1" <<endl;
    cout<<"        EXIT: Enter the value as 100"<<endl;
    cout<<endl<<"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"<<endl;
    cin>>level;
   
    // LOGGING LOGIC
    if(level == 1)
    {
       MUNI_DEBUG_ON(LEVEL_0);
    }
    else if(level == 2)
    {
       MUNI_DEBUG_ON(LEVEL_1);
    }
    else if(level == 3)
    {
       MUNI_DEBUG_OFF(LEVEL_0);
    }
    else if(level == 4)
    {
       MUNI_DEBUG_OFF(LEVEL_1);
    }
    else
    {
       cout<<" Invalid Input"<<endl;
    }
    // END LOGGING LOGIC
   
    // CHECK the value of X
    if(X==0)
      {
         // If DEBUG_LEVEL_0 is enabled then only print the LOG
         if(MUNI_DEBUG(LEVEL_0))
         {
            LOG_DEBUG(" LEVEL 0 LOG: The value of X is ZERO");
         }
        
         cout<<endl;
        
         // If DEBUG_LEVEL_1 is enabled then only print the LOG
         if(MUNI_DEBUG(LEVEL_1))
         {
            LOG_DEBUG(" LEVEL 1 LOG: The value of X is ZERO");
         }

         if(!(MUNI_DEBUG(LEVEL_0)) && !(MUNI_DEBUG(LEVEL_1)))
         {
           LOG_DEBUG(" NO DEBUG LEVEL LOGS (LEVEL_0 and LEVEL_1) ARE ENABLED");
         }
         cout<<endl;
      }
    else
      {         
          // If DEBUG_LEVEL_0 is enabled then only print the LOG
          if(MUNI_DEBUG(LEVEL_0))
          {
             LOG_DEBUG(" LEVEL 0 LOG: The value of X is NOT ZERO and its value: %d", X);
          }
           cout<<endl;

          // If DEBUG_LEVEL_1 is enabled then only print the LOG
          if(MUNI_DEBUG(LEVEL_1))
          {
             LOG_DEBUG(" LEVEL 1 LOG: The value of X is NOT ZERO and its value:%d", X);
          }

          if(!(MUNI_DEBUG(LEVEL_0)) && !(MUNI_DEBUG(LEVEL_1)))
          {
             LOG_DEBUG(" NO DEBUG LEVELS(LEVEL_0 and LEVEL_1) LOGS ARE ENABLED");
          }
      }

  } while(level!= 100); //Exit
  return 0;
}