Trasformazione di un file di registro in una sorta di buffer circolare


22

Gente, c'è una soluzione * nix che farebbe funzionare il file di registro come un buffer circolare? Ad esempio, vorrei che i file di registro memorizzassero un massimo di 1 GB di dati e scarti le voci precedenti una volta raggiunto il limite.

È possibile affatto? Credo che al fine di ottenere che un file di registro debba essere trasformato in una sorta di dispositivo speciale ...

PS Sono a conoscenza di strumenti di logrotazione diversi ma questo non è ciò di cui ho bisogno. Logrotating richiede un sacco di IO, di solito accade una volta al giorno mentre ho bisogno di una soluzione "runtime".


3
Non sono sicuro del motivo per cui ritieni che la rotazione del registro richiederebbe un sacco di IO. La rotazione di 10 file di registro comporta 10 operazioni di ridenominazione e un HUP del servizio. Non esattamente un'operazione omicida ... Ed è la soluzione standard al tuo problema :)
pehrs,

2
Uno potrebbe eseguire uno script / eseguibile che non funziona bene con HUP.
Scott,

1
Questo serve a fornire un altro caso d'uso per la tua domanda. Ho un lettore musicale demonizzato. Voglio un registro di lunghezza di poche righe, in modo da poter vedere cosa sta suonando e cosa ha suonato prima. A tail -f somefilelo farebbe. Ho appena provato con i registri ruotati e tail -fnon funziona con quelli.
Vorac,

Risposte:


14

Linux ha un buffer dell'anello del kernel. Puoi usarlo dmesgper visualizzarlo .

Oppure ecco un modulo del kernel Linux che sembra fare quello che vuoi.

Che cos'è emlog?

emlog è un modulo del kernel Linux che semplifica l'accesso all'output più recente (e solo il più recente) da un processo. Funziona proprio come "tail -f" su un file di registro, tranne per il fatto che la memoria richiesta non cresce mai. Ciò può essere utile nei sistemi embedded in cui non c'è memoria o spazio su disco sufficienti per mantenere i file di registro completi, ma a volte sono necessari i messaggi di debug più recenti (ad esempio, dopo che si è verificato un errore).

Il modulo del kernel emlog implementa un driver di dispositivo a caratteri semplici. Il driver si comporta come una pipa denominata che ha un buffer circolare finito. La dimensione del buffer è facilmente configurabile. Man mano che vengono scritti più dati nel buffer, i dati più vecchi vengono eliminati. Un processo che legge da un dispositivo emlog leggerà prima il buffer esistente, quindi vedrà il nuovo testo mentre è scritto, simile al monitoraggio di un file di registro usando "tail -f". (Sono supportate anche letture non bloccanti, se un processo deve ottenere il contenuto corrente del registro senza bloccare per attendere nuovi dati.)


1
Grazie per il link! A proposito, la home page di emlog ha un link a ulogbufd che probabilmente è anche una soluzione più appropriata per me.
Pachanga,

Il modulo del kernel emlog è ora gestito su github: github.com/nicupavel/emlog
dbernard

4

La cosa più vicina a cui riesco a pensare è RRDTools, ma probabilmente non è quello che stai cercando. Un'altra soluzione sarebbe quella di monitorare il file di registro (diciamo ogni secondo o in Linux con inotify), ad esempio scrivi uno script come:

while :; do
  if [[ $(stat -c %s $FILE) -gt 10000 ]]; then
    # rotate the log
  fi
  sleep 1
done

con inotify:

while :; do
  if inotifywait [some options] $FILE; then
    # check size and rotate the file
  fi
done

+1 per menzionare RRDtool, un vero esempio di registrazione della struttura dei dati dell'anello.
Cory J,

Grazie, ad esempio, per aver mostrato l'utilizzo del comando shell inotifywait
pachanga,

4

Puoi usare il multilog da Daemontools di djb. Invii l'output del log in esso. Sì, è la rotazione del registro, ma le rotazioni sono semplicemente:

ln current $tai64nlocaltimestamp

Il che, praticamente su qualsiasi moderno filesystem linux, è un'operazione super veloce. È possibile specificare il numero di file di registro desiderati, la dimensione desiderata. crea 10 file da 1024mb e avrai il tuo buffer ad anello da 1 GB.

Si noti che a causa della rotazione automatica, è una fonte per istanza multilog. Ma puoi aggirare ciò scrivendo un semplice wrapper con netcat o manualmente.


Grazie per il consiglio! Sicuramente avrò anche a Multilog.
Pachanga,

1

È possibile creare una pipe FIFO e, successivamente, leggerla utilizzando uno script che viene inserito in un database. Quando il contatore raggiunge 1.000, riavviare il numero ID da inserire nel database. Ovviamente non funzionerebbe per dimensioni, ma l'hai usato come esempio, quindi presumo che questa sia una domanda teorica.


1

Domanda interessante; di solito non lo vedi come un disegno. Ho un programma che utilizza una tecnica leggermente simile per registrare la cronologia, ma utilizza un formato binario. Il "file di registro" ha quattro parti, tutte disposte in un formato neutro dal punto di vista della macchina:

  1. Un'intestazione contenente il numero magico e il (massimo) numero di voci nell'elenco usato e nell'elenco libero, il numero progressivo per la successiva voce della cronologia, il numero effettivo di voci nell'elenco usato, il numero effettivo di voci nell'elenco libero e la lunghezza del file (ognuno dei quali è 4 byte).
  2. L'elenco utilizzato, ogni voce che fornisce un offset e una lunghezza (4 byte per ogni parte di ogni voce).
  3. L'elenco libero, ogni voce simile alla voce dell'elenco utilizzata.
  4. I dati principali, ogni record di cronologia costituito da un insieme contiguo di byte terminato da un byte di terminazione nullo.

Quando viene allocato un nuovo record, se c'è spazio nella lista libera, allora sovrascrive una voce lì (non necessariamente usando tutto - nel qual caso il frammento rimane nella lista libera). Quando non c'è spazio nell'elenco gratuito, alla fine viene assegnato nuovo spazio. Quando un vecchio record viene ruotato, il suo spazio viene spostato nell'elenco libero e unito a tutti i record liberi adiacenti. È progettato per gestire le istruzioni SQL in modo che i record possano essere distribuiti su più righe. Questo codice funziona su un numero specificato di record. Non limita la dimensione del file di per sé (anche se non sarebbe difficile farlo farlo).

Il codice cronologico principale del codice è in due file, history.c e history.h, disponibile dalla fonte per il programma SQLCMD (la mia versione, non quella di Microsoft; la mia esisteva almeno un decennio prima di quella di Microsoft), che può essere scaricata da l' Archivio software del Gruppo utenti International Informix . Esiste anche un programma di dump di file di cronologia (histdump.c) e un tester di cronologia (histtest.ec - afferma di essere ESQL / C, ma è in realtà un codice C; una delle funzioni di supporto che chiama utilizza alcuni ESQL / C Informix funzioni di libreria). Contattami se vuoi sperimentare senza usare Informix ESQL / C - vedi il mio profilo. Ci sono alcune modifiche banali per consentirgli di compilare il più istante al di fuori del suo ambiente di progettazione, inoltre è necessario un makefile.


0

Sono d'accordo con il commento di Pehrs alla tua domanda. La rotazione del registro non è così difficile. È possibile impostare logrotate o un altro script per controllare periodicamente il file di registro, anche ogni volta che lo si desidera. Quando rileva che il file raggiunge una dimensione di 1 GB, esegue semplicemente una ridenominazione, che richiede quasi nessun I / O. Durante la ridenominazione il processo continua a scrivere il file di registro. Il log rotator può quindi inviare un HUP al demone syslog (il tuo demone sta registrando tramite syslog, giusto? In caso contrario, dovrebbe supportare il segnale HUP se è ben scritto ...) per riaprire il percorso del file originale . A questo punto inizierà a scrivere in un nuovo file nel percorso originale ed è possibile eliminare la versione ruotata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.