2009-11-24 13 views
9

Ho controllato questo question, ma non è quello che sto cercando.Implementazione di un file di registro di dimensioni fisse o di un buffer circolare sul disco

Sto cercando di capire come cap dimensione di un file di log (ad esempio, 10 MB), e appena è colpito, o:

  • iniziare a scrivere all'inizio, piuttosto che aggiungendo, o
  • mantenere aggiungendo, ma eliminare il contenuto fin dall'inizio come lo faccio

non mi interessa sul linguaggio - il più a lungo è possibile :)


Nota: sono a conoscenza dell'approccio dei file di registro a rotazione (consente di raggiungere una dimensione di destinazione, rinominare e continuare la registrazione). Sto cercando di evitare un simile lancio.

+0

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

risposta

3

Se si implementa sia lo scrittore e il lettore, allora si può fare qualcosa di simile:

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'idea è quella di gestire un buffer circolare con numeri da record di dimensione fissa esplicite. Necessario è la logica per gestire se il record N esiste e per controllare gli errori.

+1

un suggerimento ricevuto fuori banda è stato quello di utilizzare record di dimensioni fisse e memorizzare una breve quantità di meta-dati nella parte anteriore del file , indicando quale record iniziare da – warren

2

Perché non eseguire i file di log in rotazione? Deve essere precisamente 10MB? Se 10 MB sono la tua quota, una pratica comune sarebbe scrivere su blah.log, e quando colpisce, diciamo 1MB, rinomina il file in blah.log.1 e inizia a scrivere su blah.log. Molto più semplice, e una pratica molto comune. In effetti, in Linux, se usi syslog, è gratuito.

+2

sì, so su rolling logfile (e logrotate, ecc.) - Sto guardando di più se ho una dimensione assoluta di non superamento, e non voglio tenere traccia di quale file in cui mi trovo, avere un file di registro autodiretto sarebbe bello – warren

1

Se si utilizza Log4 [j/net] ci sono opzioni per un registro a rotazione. Vedi lo RollingFileAppender. Inoltre, esiste un'opzione quando si specificano gli attributi del file di registro per impostare la dimensione massima del file per il registro. (Param: MaxFileSize)

+1

questo sembra automatizzare il rollare dei file di log, se l'ho letto correttamente - non rotolando * dentro * un file di log – warren

Problemi correlati