Logrotate Il file originale riuscito torna alle dimensioni originali


11

Qualcuno ha avuto problemi con logrotate prima che causasse la rotazione di un file di registro e quindi la stessa dimensione originale? Ecco i miei risultati:

Logrotate Script:

/var/log/mylogfile.log {
    ruotare 7
    quotidiano
    comprimere
    olddir / log_archives
    missingok
    notifempty
    copytruncate
}

Output dettagliato di Logrotate:

copiando /var/log/mylogfile.log in /log_archives/mylogfile.log.1
troncando /var/log/mylogfile.log
compressione del registro con: / bin / gzip
rimozione del vecchio registro /log_archives/mylogfile.log.8.gz

Si verifica il file di registro dopo il troncamento

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 parte 1 parte 1 0 gennaio 11 17:32 /var/log/mylogfile.log

Letteralmente pochi secondi dopo:

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 parte 1 parte 1 3,5 G 11 gennaio 17:32 /var/log/mylogfile.log

Versione RHEL:

[root @ server ~] # cat / etc / redhat-release 
Red Hat Enterprise Linux ES versione 4 (aggiornamento Nahant 4)

Versione Logrotate:

[root @ DAA21529WWW370 ~] # rpm -qa | grep logrotate
logrotate-3.7.1-10.RHEL4

Alcune note:

  • Il servizio non può essere riavviato al volo, quindi è per questo che sto usando copytruncate
  • I registri ruotano ogni notte, in base alla olddirdirectory che contiene i file di registro di ogni notte.

Risposte:


18

Ciò è probabilmente dovuto al fatto che, anche se il file viene troncato, il processo di scrittura sul file continuerà a scrivere a prescindere dal suo offset. Quindi quello che sta succedendo è che logrotate tronca il file, la dimensione è zero, il processo scrive di nuovo sul file, continuando all'offset che aveva interrotto e ora hai un file con byte NULL fino al punto in cui lo hai troncato più il nuovo voci scritte nel registro.

od -c dopo troncamento + crescita improvvisa, output generato lungo le linee di:

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

Ciò che dice è dall'offset da 0 a 33255657600 il file è composto da byte null e quindi da alcuni dati leggibili. Arrivare a questo stato non richiede lo stesso tempo necessario per scrivere effettivamente tutti quei byte null. I filesystem ext {2,3,4} supportano qualcosa chiamato file sparse, quindi se cerchi oltre una regione di un file che non contiene nulla, si presume che quella regione contenga byte nulli e non occupi spazio su disco. Quei byte nulli non verranno effettivamente scritti, ma si presume che siano lì, quindi il tempo necessario per passare da 0 a 3,5 GB non richiede molto tempo. (Puoi testare il tempo necessario facendo qualcosa del genere dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1, questo dovrebbe generare un file di oltre 3 GB in pochi millisecondi).

Se corri ls -lssui tuoi file di log dopo che sono stati troncati e hanno avuto di nuovo una crescita improvvisa, ora dovrebbe riportare un numero all'inizio della riga che rappresenta la dimensione effettiva (in blocchi occupati sul disco), che probabilmente è un ordine di grandezza più piccolo delle dimensioni riportate da just ls -l.


Non credo - in pochi secondi il file di registro passa da 0 byte a 3,5 GB. Il tempo totale necessario per il completamento di logrotate è di circa 5 minuti. I file di registro non vengono scritti così velocemente E la dimensione è sempre la dimensione originale, che sembra troppo coincidente.
Drewrockshard,

Dovrebbe esserci un modo semplice per verificarlo, ispezionare il file e vedere se c'è davvero qualcosa al suo interno. Inizia eseguendo od -c nomefile | head -n 100. È probabile che ti dirà in poche righe che c'è un camion carico di byte null, oltre alle ultime voci di registro.
Kjetil Joergensen,

In questo caso, possiamo verificare se cat / dev / null> /var/log/mylogfile.log tronca il file in un modo che risolve questo problema, anziché utilizzare logrotate incorporato in copytruncate?
mtinberg,

2
Il problema non sta nel modo in cui il file viene troncato, il problema si trova nel modo in cui il programma scrive il file di registro. Affinché il troncamento del file di registro sia un approccio praticabile, dovrai far sì che il programma scriva nel file di registro in qualche modo cerchi la posizione 0. È possibile che un filesystem che non supporti file sparsi non abbia questo problema, anche se non c'è modo di testarlo proprio ora.
Kjetil Joergensen,

1
Questa risposta finale ha effettivamente avuto più senso e probabilmente la correzione finirà per riavviare l'applicazione.
Drewrockshard,

2

Sono estremamente fiducioso che Kjetil l'abbia colpito. Drew, potresti non essere ancora convinto della sua spiegazione, ma ti esorto a leggere attentamente ciò che ha detto.

Se lo accetti, la correzione consiste nell'arrestare e riavviare l'applicazione quando i registri vengono ruotati o utilizzare uno strumento come "rotatelogs" di apache, in cui si invia l'output del registro allo strumento tramite una pipe e lo strumento si occupa di ruotando il file di registro ogni tanto. Ad esempio, una delle mie istanze di Apache si registra

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

che causa molti file di log con nomi come

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

apparire senza riavviare apache; Posso quindi comprimerli manualmente dopo il fatto. Nota come viene eseguita la rotazione ogni settimana, ovvero ogni 604800 secondi, a cui è passato l'argomento rotatelogs.

Se non riesci a interrompere e riavviare l'app e non è possibile accedere tramite una pipe, penso che tu abbia un vero problema. Forse altri avranno suggerimenti.


0

sarebbe davvero fantastico se tu potessi inviare l'intero logrotate.

Perché provare a usare kill -HUP? Metodo (ricarica classica non riavviata ).

Inoltre ... controlla con lsof chi accede al file.


Impossibile utilizzare in kill -HUPquanto questa applicazione non può essere toccata in alcun modo - è un'applicazione sensibile che non possiedo (non la gestisco nemmeno - gestisco solo il lato del sistema operativo) quindi devo essere in grado di fare le logazioni modo.
Drewrockshard,

1
Siamo spiacenti, il messaggio originale è stato inviato in anticipo, ecco il resto del mio messaggio originale: stamattina ho effettuato l'accesso al sistema e il file è tornato alla normalità dopo l' /etc/cron.dailyavvio del logrotate pianificato . Domanda a tutti: c'è qualcosa che lo script logrotate fa diversamente dall'esecuzione manuale di logrotate? Il mio script logrotate sembra letteralmente /usr/sbin/logrotate /etc/logrotate.conf. Questo è abbastanza sconcertante.
Drewrockshard,

-1

Basta usare ">>" che significa aggiungere invece di ">" che significa creare dai tuoi script che scrivono in questo file. Ho avuto lo stesso identico problema e l'ho risolto usando append nel mio script.

SomeScript.sh >> output.txt

Spero sia più chiaro.


Non vi è alcuna indicazione che la scrittura nel file di registro venga eseguita utilizzando >da uno script. Inoltre questa risposta è confusa perché c'è una grande differenza tra >e >( )negli script. Infine, se il codice che esegue la scrittura viene aggiornato, sarebbe molto meglio che iniziasse semplicemente a scrivere nel nuovo file di registro dopo logrotateaver fatto la sua cosa.
Kasperd,

Modifica la mia risposta in modo che sia più chiara.
user578558
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.