- Get link
- X
- Other Apps
Featured Post
Posted by
Unknown
on
- Get link
- X
- Other Apps
This is a simple logger in C which logs the output of a C program to a file.
It has got following features:
1. Logging the time of compilation
2. Logging the file name from which the log is coming from
3. Line number at which the log function is called from.
Currently it outputs the logs to a file "log.txt" in the same directory as the logger file , but it can be customized as per usage.
To compile :
gcc -o output logger.c test.c
To Run :
./output
Open file "log.txt" in the same directory to see the logs.
Happy Logging !!!
It has got following features:
1. Logging the time of compilation
2. Logging the file name from which the log is coming from
3. Line number at which the log function is called from.
Currently it outputs the logs to a file "log.txt" in the same directory as the logger file , but it can be customized as per usage.
To compile :
gcc -o output logger.c test.c
To Run :
./output
Open file "log.txt" in the same directory to see the logs.
Happy Logging !!!
//logger.h void log_print(char* filename, int line, char *fmt,...); #define LOG_PRINT(...) log_print(__FILE__, __LINE__, __VA_ARGS__ )
//logger.c #include <stdio.h> #include <stdarg.h> #include <time.h> #include <string.h> #include <stdlib.h> #include "logger.h" FILE *fp ; static int SESSION_TRACKER; //Keeps track of session char* print_time() { int size = 0; time_t t; char *buf; t=time(NULL); /* get current calendar time */ char *timestr = asctime( localtime(&t) ); timestr[strlen(timestr) - 1] = 0; //Getting rid of \n size = strlen(timestr)+ 1 + 2; //Additional +2 for square braces buf = (char*)malloc(size); memset(buf, 0x0, size); snprintf(buf,size,"[%s]", timestr); return buf; } void log_print(char* filename, int line, char *fmt,...) { va_list list; char *p, *r; int e; if(SESSION_TRACKER > 0) fp = fopen ("log.txt","a+"); else fp = fopen ("log.txt","w"); fprintf(fp,"%s ",print_time()); fprintf(fp,"[%s][line: %d] ",filename,line); va_start( list, fmt ); for ( p = fmt ; *p ; ++p ) { if ( *p != '%' )//If simple string { fputc( *p,fp ); } else { switch ( *++p ) { /* string */ case 's': { r = va_arg( list, char * ); fprintf(fp,"%s", r); continue; } /* integer */ case 'd': { e = va_arg( list, int ); fprintf(fp,"%d", e); continue; } default: fputc( *p, fp ); } } } va_end( list ); fputc( '\n', fp ); SESSION_TRACKER++; fclose(fp); }
//test.c #include <stdio.h> #include "logger.h" int main() { int x = 199,i=0; char *s = "Bitter Truth"; while(i<5) { LOG_PRINT("Hello World "); LOG_PRINT("Zing is back !!! %s %d",s,x++); i++; } }
Comments
Why don't you ride on the back of sprintf rather than writing your own function?
ReplyDeleteThis is just an illustration of writing a logger, it can be customized to great extent. sprintf will only provide a standard format for printing.
ReplyDeleteIts just a Wrapper.
You have a memleak right here: fprintf(fp,"%s ",print_time()); print_time() returns malloc()-ed memory that is never free()-d.
ReplyDeleteAnd for fopen(..., "a+") open mode "a" is enough, you don't need the read-mode part.
And print_time calls ctime() 3 times which is highly redundant. And since snprintf(buf,strlen(ctime(&t)),"%s ", ctime(&t)); writes up to "second param" bytes including null byte, ctime will be truncated not to mention it will not include trailing space as specified by format string "%s ".
So, dear sir, this is very low quality code event for illustration of idea.
Thanks for pointing it out, I'll update it soon
DeleteAlso, please note that there is a vararg version of fprintf called vfprintf. Really no need to write your own limited version.
ReplyDeletegiven code is working fine but i want create log file with datatime and size..., can you help me
ReplyDeleteYou can add as many parameters as you like to the macro LOG_PRINT
DeleteJust use some function which calculates the current time and formats it into string and add it after _FILE_, _LINE_,
Hi Varun, is this implementation thread safe?
ReplyDeleteHi Varun, Thanks for this simplest understanding of the logger, but my question, is the above implementation thread safe?
ReplyDeleteHi,
DeleteThis is just a simple implementation. It's not thread safe. For that you need to use synchronisation primitives.
Hello, Varun,
ReplyDeleteThank you very much for your examples. May you share this code through github? After that we be able to commit fixes, which have not yet been made (lost free(), for example). And ofcourse we can do other improvements.
thats cool. very simple and lightweight. Thanks a lot!!!
ReplyDelete