2009-11-24 3 views
9

J'ai vérifié ce question, mais ce n'est pas ce que je recherche.Implémentation d'un fichier journal de taille fixe ou d'un tampon circulaire sur le disque

J'essaie de comprendre comment plafonner une taille de fichier journal (par exemple, 10 Mo), et dès qu'il est touché, soit:

  • commencer à écrire au début, plutôt que annexant, ou
  • garder annexant, mais supprimer le contenu depuis le début que je fais

ne se soucient vraiment de la langue - aussi longtemps qu'il est possible :)


Remarque: Je suis conscient de l'approche des fichiers journaux glissants (atteinte d'une taille cible, renommer et poursuivre la journalisation). Je cherche à éviter un tel roulement.

+0

http://stackoverflow.com/a/9075604 – chocolateboy

Répondre

3

Si vous implémentez tant l'auteur et le lecteur, alors vous pouvez faire quelque chose comme ceci:

struct logentry { 
    timestamp ts; 
    char  msg [4000]; 
}; 

class logger { 
private: 
    int write_recordnum; // next record number to write 
    int max_recordnum; // controls maximum size of file 
    FILE *logfile; 

public: 
    logger (const char *filename, int max_records) 
    { 
     max_recordnum = max_records; 
     logfile = fopen (filename, "a+"); 
    } 

    void write_next_entry (const char *msg, ...) 
    { 
     struct logentry ent; 
     // format message into entry 
     va_list ap; 
     va_start (ap, msg); 
     vsnprintf (ent.msg, sizeof(ent.msg), msg, ap); 
     va_end (ap); 
     ent.ts = gettimestamp(); 

     // position logfile 
     if (write_recordnum > max_recordnum) 
      write_recordnum = 0; 

     fseek (logfile, write_recordnum * sizeof (ent), 0); 
     fwrite (&ent, 1, sizeof(ent), logfile); 
    } 

    bool read_entry (int recnum, char *msg) 
    { 
     struct logentry ent; 
     if (recnum >= max_recordnum) 
      return false; 
     fseek (logfile, recnum * sizeof (ent), 0); 
     fread (&ent, 1, sizeof(ent), logfile); 
     strcpy (msg, ent.msg); 
     return true; 
    } 
}; 

L'idée est de gérer une mémoire tampon circulaire par un nombre record explicite de taille fixe. Nécessaire est la logique pour gérer si l'enregistrement N existe, et pour vérifier les erreurs. Pourquoi ne pas faire des fichiers journaux roulants?

+1

Une suggestion reçue hors bande consistait à utiliser des enregistrements de taille fixe et à stocker une brève quantité de métadonnées au début du fichier , indiquant de quel enregistrement commencer par – warren

2

Est-ce que ça doit être précisément 10 Mo? Si 10 Mo est votre quota, une pratique courante serait d'écrire dans blah.log, et quand il frappe, disons 1 Mo, renommer le fichier en blah.log.1 et commencer à écrire à blah.log. Beaucoup plus simple, et une pratique très commune. En fait, sous Linux, si vous utilisez syslog, c'est gratuit.

+2

oui, je sais à propos de rouler les fichiers journaux (et logrotate, etc) - je regarde plus si j'ai une taille absolue ne pas dépasser, et je ne veux pas garder trace de qui fichier dans lequel je suis, avoir un fichier journal auto-roulant serait sympa – warren

1

Si vous utilisez Log4 [j/net], vous disposez d'options pour un journal de roulement. Voir le RollingFileAppender. En outre, il existe une option lors de la spécification des attributs du fichier journal pour définir la taille de fichier maximale pour le journal. (Param: MaxFileSize)

+1

cela semble automatiser rouler les fichiers journaux, si je l'ai lu correctement - pas roulant * à l'intérieur * un fichier journal – warren

Questions connexes