Thread: Creating our own fprintf function in our library

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    5

    Unhappy Creating our own fprintf function in our library

    My Project is having 15000 files and around 2000000 lines of code, Developers used fprintf (sdterr,”%s”,string) function to generate logs, Now we are asked to put time stamp on each log it is generated. Changing each file is not possible; we are planning to create our own “fprintf” function in one of our library. I’ll appreciate your guidance to solve this issue ( else some out of box ideas ).

    Thanks in advance.

    Baskar

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Don't post multiple times on the same subject.

    you can use vs(n)printf() to generate a string for output. A macro or replacement function (linked in before the standard library) should do the trick of replacing the standard printf.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Code:
    #define fprintf   my_fprintf

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Mar 2008
    Posts
    5

    overriding glibc library

    I have found interesting solution to solve this issue. We have tried lot of solutions for this issue(i.e. logger daemon, message pipes etc ) finally everyone agreed for this. Just I want to share this information with Team.


    This a good way to override glibc (or any library) functions with our own version. This can be done without recompiling our source and glibc source. It is a thrill of writing our own version of glibc functions. This will be helpful to debug our code with out source compilation.



    We have created own “fprintf” and “printf” functions and created “.so” for that . Please refer attached file.

    “.so” creation

    gcc -shared -o libfuncs.so libfuncs.c

    copy this “so” to libs


    export LD_PRELOAD=/libs/libfuncs.so

    Now start your application


    Code:
    ///libfunc.c
    
    // Test code for fprintf time stamp  
    // This will add  File name, Line number & Time stamp on stderr
    // [Baskar]   time stamp test
    
    
    #include <stdio.h>
    #include <string.h> 
    #include <stdarg.h>
    #include <time.h>
    #include <stdlib.h>
    #include <sys/time.h>
    
    #define DATA_SIZE	1024
    #define DATE_TIME_SIZE 256
    #define ERROR  -1
    
    
    
    //************************ Method Header ****************************
    // Method Name        : fprintf [SJM]
    // Purpose            : Wrapper for time stamp impl.
    //                      
    //                      
    // Author             : Baskar
    // Exceptions Thrown  : None
    //*******************************************************************
    
    int  fprintf(FILE *fp,const char *format,...)
    {
    		int l_nNumOfChars=0;
    		va_list args;
    		va_start(args, format);
    		//If it is Standard error or Standard out………. proceed further
    		if(fp == stderr || fp == stdout )
    		{
    			 char l_carrTmpData[DATA_SIZE]={0};
    			 char l_carrTmpDateTime[DATE_TIME_SIZE]={0};
    			 char l_carrTmpDataAndTime[DATA_SIZE + DATE_TIME_SIZE]={0};
    			
    			 struct timeval timeNalue;
    			 if( gettimeofday(&timeNalue, NULL) != ERROR )
    			 {
    				struct tm *st_pTimeSt = localtime(&timeNalue.tv_sec);
    			
    				 if(st_pTimeSt)
    				 {
    					snprintf(l_carrTmpDateTime,DATE_TIME_SIZE, "%02d/%02d/%04d %02d:%02d:%02d:%02d",
    						st_pTimeSt->tm_mday, st_pTimeSt->tm_mon+1, st_pTimeSt->tm_year+1900,st_pTimeSt->tm_hour, st_pTimeSt->tm_min, st_pTimeSt->tm_sec,(timeNalue.tv_usec/1000));
    				 }
    				
    			 }
    			 vsnprintf(l_carrTmpData, DATA_SIZE, format, args);
    
    			if(l_carrTmpData[0] == '\n' )
    			{
    				l_carrTmpData[0]=' ';
    				snprintf(l_carrTmpDataAndTime,DATA_SIZE + DATE_TIME_SIZE,"\n%s-%s",l_carrTmpDateTime,l_carrTmpData );
    
    			}
    			else
    			{
    				snprintf(l_carrTmpDataAndTime,DATA_SIZE + DATE_TIME_SIZE,"%s - %s",l_carrTmpDateTime,l_carrTmpData );
    			}
    
    			l_nNumOfChars = fwrite(l_carrTmpDataAndTime,1,strlen(l_carrTmpDataAndTime),stderr);
    
    		}
    		else // else write to mentioned file
    		{
    			
    			l_nNumOfChars = vfprintf(fp, format, args);
    			
    		}
    		va_end(args);
    		return l_nNumOfChars;
    }		
    //************************ Method Header ****************************
    // Method Name        : printf [SJM]
    // Purpose            : Wrapper for time stamp impl.
    //                      
    //                      
    // Author             : Baskar
    // Exceptions Thrown  : None
    //*******************************************************************
    int printf (const  char *format, ...)
    {
    		int l_nNumOfChars=0;
    		char l_carrTmpData[DATA_SIZE]={0};
    		char l_carrTmpDateTime[DATE_TIME_SIZE]={0};
    		char l_carrTmpDataAndTime[DATA_SIZE + DATE_TIME_SIZE]={0};
    		struct timeval timeNalue;
    
    		va_list args;
    		va_start(args, format);
    		
    		if( gettimeofday(&timeNalue, NULL) != ERROR )
    		{
    			struct tm *st_pTimeSt = localtime(&timeNalue.tv_sec);
    			if(st_pTimeSt)
    			{
    				snprintf(l_carrTmpDateTime,DATE_TIME_SIZE, "%02d/%02d/%04d %02d:%02d:%02d:%02d",
    						st_pTimeSt->tm_mday, st_pTimeSt->tm_mon+1, st_pTimeSt->tm_year+1900,st_pTimeSt->tm_hour, st_pTimeSt->tm_min, st_pTimeSt->tm_sec,(timeNalue.tv_usec/1000));
    			}
    
    		}
    		vsnprintf(l_carrTmpData, DATA_SIZE, format, args);
    		va_end(args);
    
            if(l_carrTmpData[0] == '\n' )
    		{
    			l_carrTmpData[0]=' ';
    			snprintf(l_carrTmpDataAndTime,DATA_SIZE + DATE_TIME_SIZE,"\n%s - %s",l_carrTmpDateTime,l_carrTmpData );
    
    		}
    		else
    	    {
    			snprintf(l_carrTmpDataAndTime,DATA_SIZE + DATE_TIME_SIZE,"%s - %s",l_carrTmpDateTime,l_carrTmpData );
    		}
    		
    
    		
    		l_nNumOfChars = fwrite(l_carrTmpDataAndTime,1,strlen(l_carrTmpDataAndTime),stderr);
    
    		return 	l_nNumOfChars;		
    		
    }
    
    
    /// Add required functions.../.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I don't like this solution because it makes it impossible to call printf() or fprintf() in a normal way, even if you wanted to. Why not just make a special logging function log_printf() and call this instead of calling printf() directly? It would also actually have a chance of working correctly on other platforms.

  7. #7
    Registered User
    Join Date
    Mar 2008
    Posts
    5
    Hi,
    We don't want to compile our legacy code. It required lot of testing effort.. This technique is useful for Legacy app enhancements. This will override dynamically linked APIs

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  4. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  5. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM