Rimuovere le prime N righe da un file di registro attivo


26

C'è un modo per rimuovere le prime Nrighe da un registro che viene attivamente aggiunto da un'applicazione?

Risposte:


10

No, i sistemi operativi come Linux ed i suoi filesystem, non prevedono la rimozione di dati dall'inizio di un file. In altre parole, il punto iniziale di archiviazione per un file è fisso.

La rimozione delle righe dall'inizio di un file viene generalmente eseguita scrivendo i dati rimanenti in un nuovo file ed eliminando il vecchio. Se un programma ha il vecchio file aperto per la scrittura, la sua cancellazione viene posticipata fino a quando l'applicazione non chiude il file.


Come notato dai commentatori, per i motivi indicati nella mia frase precedente, di solito è necessario coordinare la potatura dei file di registro con i programmi che stanno scrivendo i registri. Esattamente come lo fai dipende dai programmi. Alcuni programmi chiuderanno e riapriranno i loro file di registro quando invii loro un segnale (es. HUP) e questo può essere usato per impedire che i record di registro vengano scritti in un file di registro "cancellato", senza interrompere il servizio.

Esistono molte utilità disponibili per la gestione delle dimensioni dei file di registro, ad esempio logrotate

Alcuni programmi hanno le proprie utilità. Ad esempio, il server web Apache include un'utilità rotatelogs .


3
Ma non dovresti farlo mentre qualcosa ha ancora il file aperto e lo sta ancora aggiungendo, perché scriverebbe sul file ora cancellato e perderesti quei messaggi di log.
Tarnay Kálmán,

Vero. Anche se hai usato lo stesso nome file.
Hennes,

peccato che il sistema operativo non te lo permetta, sarebbe sicuramente conveniente per i rotatori di log non dover ricaricare i processi dopo la rotazione: |
rogerdpack,

25

Penso che questo compito possa essere realizzato con sed

sed -i '1,10d' myfile

rimuoverebbe le righe dalla alla 10ª riga del file.

Penso che tutti dovrebbero almeno dare un'occhiata a questa fodera sed 1 .

Si noti che ciò non funziona per i file di registro che vengono attivamente aggiunti da un'applicazione (come indicato nella domanda).

sed -icreerà un nuovo file ed "eliminerà" il file su cui si sta scrivendo. La maggior parte delle applicazioni continuerà a scrivere i record di registro nel file di registro eliminato e continuerà a riempire lo spazio su disco. Il nuovo file di registro troncato non verrà aggiunto. Questo cesserà solo quando l'applicazione verrà riavviata o altrimenti verrà segnalato di chiudere e riaprire i suoi file di registro. A quel punto ci sarà un gap (record di registro mancanti) nel nuovo file di registro se c'è stata qualche attività registrabile tra l'uso di sed e il riavvio dell'applicazione.

Un modo sicuro per farlo sarebbe quello di arrestare l'applicazione, utilizzare sed per troncare il registro, quindi riavviare l'applicazione. Questo approccio può essere inaccettabile per alcuni servizi (ad esempio un server Web con throughput elevato e requisiti di continuità del servizio elevati)


2
Sai cosa succede alle applicazioni aggiunte?
Adam Matan,

1
Supponiamo che un normale gestore di file aperto che accoda le linee e svuota di tanto in tanto.
Adam Matan,

1
Conosco il modo di aggirare sed, ed estrarre le linee in un nuovo file è un gioco da ragazzi con sed. Il problema è mantenere tutto nello stesso file.
Adam Matan,

10
No, questo non dovrebbe funzionare. sed -icrea un nuovo file con il contenuto modificato e quello vecchio viene rimosso in modo da non modificare il file attivo: $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile------ Controlla come sed -ifunziona. Perché questa risposta sbagliata ha tanti voti positivi?
pabouk,

1
La domanda indica "da un registro che viene attivamente aggiunto da un'applicazione". La parola chiave è "attivamente". Forse quel chiarimento è stato aggiunto dopo la tua risposta. Ma così com'è, i lettori che gravitano verso la "maggior parte dei voti" saranno fuorvianti. Ho potuto effettuare il downgrade solo una volta.
Scott Prive

5

No. Una soluzione a questo generico problema di crescita dei file di registro è la rotazione dei registri. Ciò comporta lo spostamento regolare (notturno o settimanale, in genere) di un file di registro esistente su un altro nome di file e l'avvio con un file di registro vuoto. Dopo un certo periodo i vecchi file di registro vengono eliminati.

Vedi: http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm


2

Questa è una risposta , non una soluzione. Non c'è soluzione alla domanda. Il richiedente afferma chiaramente: "da un registro che viene attivamente aggiunto da un'applicazione". Puoi leggere per capire di più e saltare alla fine per un suggerimento che faccio in base alla mia presunzione perché questo codice non segue le migliori pratiche di registrazione.

Per essere chiari: altre "risposte" qui offrono la falsa promessa . Nessuna ridenominazione indurrà l'applicazione a utilizzare il nuovo file. Le informazioni più utili sono sepolte nei commenti fatti a queste risposte errate.

I file ACTIVE non sono un tipo di contenitore in cui vengono semplicemente inseriti i dati. Un nome file punta a UN inode (inizio del file) e ogni inode ha un puntatore a un altro inode (se ci sono più dati). Ciò significa che un file continuamente scritto ha un flusso costante di inode che viene aggiunto ad esso, e ciò che pensi di un "file" è in realtà una sequenza di registro di inode.

Immagina di rintracciare qualcuno su Google Maps e che quella persona possa teletrasportarsi in qualsiasi parte del mondo, in qualsiasi momento e che stavi cercando di collegare questi punti.

Lo strumento Linux "troncare" può scartare i dati alla fine del file, semplicemente camminando nella struttura di inode e (nella posizione / dimensione designata) eliminerà tutti i puntatori successivi nello stack. Fare il contrario - scartare i dati all'inizio del file - sarebbe un processo così orribilmente complesso e rischioso di riscrivere l'albero degli inode in tempo reale che nessuno scriverà tali strumenti per il pubblico, perché spesso fallirebbero e porterebbero a perdita di dati. La wiki di Inodes è breve ma spiega alcuni di questi concetti.

** Il mio consiglio: capovolgi questo problema - PERCHÉ questa applicazione si comporta in questo modo? Esistono molte best practice per la registrazione, ma spesso sono legate a ciò che è effettivamente il tuo sistema di registrazione (syslog, ecc.). Fondamentalmente, un'applicazione dovrebbe "rilasciare" il suo handle nel file, quindi logrotate (etc) può gestire l'ulteriore elaborazione dei vecchi dati.

Ogni volta che ascolto "un file di registro ATTIVO", chiedo immediatamente a quella persona di raccontarmi la "storia speciale" dietro questa applicazione. Di solito è "lo sviluppatore a smettere, e non possiamo cambiare il codice. Questo è in realtà il contrario della sicurezza, ha i suoi rischi. Ma ti chiedo una soluzione che eviti di toccare il codice sorgente. Se questo è il caso, è necessaria una domanda più specifica.


0

Apertura in testo sublime L'eliminazione delle righe e il salvataggio del file funzionano in qualche modo, anche se il file viene accodato, ma sono venuto qui per cercare la soluzione per una riga di comando, quindi lascerei questa soluzione funzionante ma inutile qui !!


-1

Magari copia, tronca, ritaglia la copia sulla dimensione = 0 troncamento ed elimina la copia?

Meglio ancora coda per copia coda, tronca l'originale, concatena copia coda sull'originale.

Ottieni linee nel registro alla lunghezza della coda, quindi meglio di un limite di lunghezza in byte.

Modifica dei dettagli dal commento:

Per prima cosa abbiamo uno script logger in Python3 quello che vuoi

from time import sleep

idx = 0
while 1 == 1:
    idx = (idx + 1)
    lf = open('tailTrunc.log', 'a')
    lf.write("line to file " + str(idx) + '\n')
    lf.close()
    sleep(0.01)

Quindi abbiamo il nostro troncatore

#!/usr/bin/env bash

trap "kill 0" EXIT

rm tailTrunc.log
touch tailTrunc.log

python3 logLoop.py &
loggerPID=$!
sleep 1

kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1

trimEnd.log mostra da 80 a 89

il registro mostra 90 alla fine

Comunque dove c'è una volontà c'è un modo.

Molti esempi più complicati di consolidatori e di come il flusso di scrittura viene aperto o chiuso potrebbe dover essere modificato per core della CPU, ecc. Basta mettere in pausa la scrittura e la coda se è possibile nel proprio logger del processo di registrazione ecc.


"da un registro che viene attivamente aggiunto da un'applicazione". Il problema che la tua soluzione trascura è che il file di registro è "permanentemente" in uso dall'applicazione, il che significa che l'inode del file di registro rimane in gioco. La soluzione esegue il "backup" dei dati del file di registro, che potrebbero essere utilizzati al di fuori di questa domanda.
Scott Prive

Grazie per il tuo commento e voto negativo? Ho modificato un rapido esempio economico come spunto di riflessione che dovrai pensare in modo più approfondito alla tua situazione, ma dove c'è una volontà c'è un modo.
Master James,

Non pensare che sia stato il mio voto negativo, ma penso che il punto sia martellato nei commenti dell'altra risposta: SE copi un file di registro, non è più il file di registro attivo ... qualunque cosa tu faccia. Il filehandle dell'applicazione punterà sempre all'inode del file di log originale. Pensala in questo modo: hai un'applicazione che utilizza funzioni di registrazione non standard e aggiunge continuamente byte al file che ha aperto.
Scott Prive,

1
Mi dispiace inferire. Sì, l'inode deve rimanere lo stesso ed è per questo che l'esempio / la prova forniti usa troncato, e di nuovo dipende dalla situazione (le opzioni per tutti apparentemente si nascondono in un sito normale).
Master James,
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.