Featured Post

Trie implementation in C

Simple Logger in C

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 !!!

//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

  1. Why don't you ride on the back of sprintf rather than writing your own function?

    ReplyDelete
  2. This is just an illustration of writing a logger, it can be customized to great extent. sprintf will only provide a standard format for printing.
    Its just a Wrapper.

    ReplyDelete
  3. You have a memleak right here: fprintf(fp,"%s ",print_time()); print_time() returns malloc()-ed memory that is never free()-d.
    And 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.

    ReplyDelete
    Replies
    1. Thanks for pointing it out, I'll update it soon

      Delete
  4. Also, please note that there is a vararg version of fprintf called vfprintf. Really no need to write your own limited version.

    ReplyDelete
  5. given code is working fine but i want create log file with datatime and size..., can you help me

    ReplyDelete
    Replies
    1. You can add as many parameters as you like to the macro LOG_PRINT
      Just use some function which calculates the current time and formats it into string and add it after _FILE_, _LINE_,

      Delete
  6. Hi Varun, is this implementation thread safe?

    ReplyDelete
  7. Hi Varun, Thanks for this simplest understanding of the logger, but my question, is the above implementation thread safe?

    ReplyDelete
    Replies
    1. Hi,
      This is just a simple implementation. It's not thread safe. For that you need to use synchronisation primitives.

      Delete
  8. Hello, Varun,
    Thank 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.

    ReplyDelete
  9. thats cool. very simple and lightweight. Thanks a lot!!!

    ReplyDelete

Post a Comment

Please post your valuable suggestions