Come continuare a reindirizzare lo stdout su un file dopo che logrotate lo sposta?


22

Ho un semplice script che genera un sacco di registri sullo schermo e ho reindirizzato STDOUT a un file per archiviare i registri. Dato che questo script ha una lunga esecuzione, avevo bisogno di ruotare i file di registro in modo che vengano suddivisi in file più piccoli e più gestibili.

Il problema che ho riscontrato è stato che una volta logrotatespostato il file di registro corrente in uno nuovo, il file di registro appena creato non viene più popolato con i registri. Sembra che una volta rimosso il file di registro originale, il suo gestore di file sia perso e il reindirizzamento non funzionerà più.

Ho anche trovato questo post che aveva lo stesso mio problema e afferma che può essere risolto usando >>invece di >reindirizzare l'output. Ho testato la sua soluzione ma non ha funzionato per me. Qualcuno ha idea di come mantenere il reindirizzamento funziona?


4
Consiglio comunque, nel tuo caso, di usare ">>" invece di ">" se intendi scrivere in un file troncato: come ">>" si aprirà in modalità append, cercherà fino alla fine del file ogni volta che scrive. In questo modo, quando tronchi il file (facendolo passare da XXXX byte a 0 byte), "cercherà fino alla fine", quindi saprà che ora deve scrivere dopo il byte 0. Altrimenti potrebbe scrivere dopo il byte XXXX, e quindi crea un file sparse con XXXX byte nulli prima di esso (cioè, quando ">", il fd può semplicemente ricordare dove si trovava in quel file e scrivere da lì, senza rendersi conto della dimensione del file ridotta!)
Olivier Dulac

Risposte:


25

È necessario utilizzare la direttiva copytruncate nella configurazione di logrotate per questo file di registro.

copytruncate Tronca il file di registro originale in posizione dopo aver creato una copia, invece di spostare il vecchio file di registro e opzionalmente crearne uno nuovo. Può essere utilizzato quando ad alcuni programmi non è possibile dire di chiudere il suo file di registro e quindi potrebbe continuare a scrivere (aggiungendo) al file di registro precedente per sempre. Si noti che c'è un intervallo di tempo molto piccolo tra la copia del file e il suo troncamento, quindi alcuni dati di registrazione potrebbero andare persi. Quando viene utilizzata questa opzione, l'opzione di creazione non avrà alcun effetto, poiché il vecchio file di registro rimane in posizione


2
Vale la pena ricordare: per un breve periodo, prima compressdell'operazione, i dati vengono duplicati. Ciò ci ha causato un problema una volta, ma è stato un problema poiché non avremmo dovuto essere così vicini al lvlimite di spazio. Inoltre, come indicato nello mansnippet, potresti perdere alcuni dati di registro tra le operazioni di copia e troncamento.
Belmin Fernandez,

6

In alternativa, puoi anche:

  • utilizzare l'utilità di registrazione nel proprio script anziché in piping, con una funzione dedicata (ad esempio local5), ad esempio:

    logger -p local5.info -t myscriptname "this is some log data"

  • configurare syslog per scrivere questa funzione nel file di registro desiderato, ad esempio (rsyslog.conf):

    local5.* /var/log/mylogfile

  • regola regola logrotate per questo registro.


Funziona solo se hai comandi di output espliciti come echo. L'output di strumenti di terze parti che vengono richiamati dallo script e anche output di qualcosa non può essere reindirizzato al logger in questo modo
Daniel Alder,

4

Un'altra alternativa alla soluzione Iain è quella di utilizzare uno postrotatescript per riavviare lo script una volta avvenuta la rotazione. Questo viene fatto per molti demoni (riavvia o ricarica il demone), ma non conoscendo il tuo script non so se questa soluzione ti si adatta o no (il tuo script dipende da uno stato generato qualche tempo fa?).

Contenuto di /etc/logrotate.d/your-script-name:

/var/log/your-script-name.log {
    # your current logrotate options
    ...
    postrotate
        # this supposing you have the current pid stored
        cat /run/your-script-name.pid | xargs -r kill
        #relaunch it again
        /usr/local/bin/your-script-name
    endscript
}

0

È possibile reindirizzare stdout a "dividere" (parte di coreutils in linux). Ti permette di dividere file / stdin in blocchi in base a dimensioni, numero di linee, ecc. Una volta ottenuto, puoi gestirlo con logrotate se necessario.

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.