Funzione per scrivere su File di LOG come una printf

Ho cercato in giro qualcosa come “write log file in C like printf” senza grandi risultati, o meglio: nulla di “prefatto”, ho realizzato una cozzaglia di codice trovato qua e là, realizzando quanto propongo.

In pratica desideravo qualcosa di semplice, non mi serviva utilizzare chissà quale libreria o funzionalità impestata, sostanzialmente: volevo scrivere su un file di testo una stringa “formattata” passando i parametri come fosse una “printf”.

Sì, detta così è un po’ criptica la faccenda, ma se qualcuno cerca di risolvere questo problema – probabilmente – capisce cosa intendo dire.

Mi aspetto che lo capisca almeno dal codice che ho scritto:

#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#define MAXBUFFERSIZE   2048

int print_log(const char *log_file,     // Path of log file
              const char log_msg_type,  // Letter of Log Type (ex: I = Info, A = Alert, E = Error)
              const char *format,       // Parameters like printf
              ...
              ) {
  va_list arg;
  int done;

  char  psBuffer[MAXBUFFERSIZE];
  char  psLogData[MAXBUFFERSIZE * 2];
  char  psTime[MAXBUFFERSIZE];

  time_t t;   // not a primitive datatype
  struct tm *tmp;

  memset(psBuffer, '\0', MAXBUFFERSIZE - 1);
  memset(psLogData, '\0', (MAXBUFFERSIZE * 2) - 1);
  memset(psTime, '\0', MAXBUFFERSIZE - 1);

  va_start (arg, format);
  done = vsnprintf(psBuffer, MAXBUFFERSIZE - 2, format, arg);
  va_end (arg);

  time(&t);
  tmp = localtime(&t);
  if (tmp == NULL) {
    perror("localtime");
    exit(EXIT_FAILURE);
  }
  strftime(psTime, MAXBUFFERSIZE - 1, "%F %T", tmp);
  sprintf(psLogData, "[%c] %s :: %s\n", log_msg_type, psTime, psBuffer);

  FILE* fp;
  fp = fopen(log_file, "a+");
  fputs(psLogData, fp);
  fclose(fp);

  return done;
}

Per usare il tutto è sufficiente salvare il codice di cui sopra in un file che potrebbe chiamarsi “printlog.h” e quindi usarlo in qualcosa di simile a questo:

#include "printlog.h"

int main (int argc, char **argv) {
  print_log("/tmp/test.log", 'I', "Parametro: %s", argv[1]);

  return EXIT_SUCCESS;
}

Il programma di test l’ho salvato in “printlog.c” e compilato (su Linux Debian) con questo comando:

gcc -o printlog printlog.c

Spero sia utile a qualcuno, fatemi sapere.

PS: Se uno guarda bene il codice, si accorgerà che fa un po’ schifo, soprattutto nella gestione della dimensione massima delle stringhe, ma avevo fretta…

Autore: BuDuS

Disegnatore Meccanico, con la passione per l'Informatica. Come hobby, produco piccoli software di (in)utilità.