Supprimer les N premières lignes d'un fichier journal actif

26

Existe-t-il un moyen de supprimer les premières Nlignes d'un journal qui est activement ajouté par une application?

Adam Matan
la source

Réponses:

10

Non, les systèmes d'exploitation comme Linux, et ses systèmes de fichiers, ne prévoient pas de supprimer les données au début d'un fichier. En d'autres termes, le point de départ du stockage d'un fichier est fixe.

La suppression des lignes au début d'un fichier s'effectue généralement en écrivant les données restantes dans un nouveau fichier et en supprimant l'ancien. Si un programme a l'ancien fichier ouvert pour l'écriture, la suppression de ce fichier est reportée jusqu'à ce que l'application ferme le fichier.


Comme l'ont noté les commentateurs, pour les raisons indiquées dans ma phrase précédente, vous devez généralement coordonner l'élagage du fichier journal avec les programmes qui écrivent les journaux. La façon exacte dont vous procédez dépend des programmes. Certains programmes fermeront et rouvriront leurs fichiers journaux lorsque vous leur enverrez un signal (par exemple HUP) et cela peut être utilisé pour empêcher l'écriture des enregistrements de journaux dans un fichier journal «supprimé», sans interrompre le service.

Il existe de nombreux utilitaires pour gérer la taille des fichiers journaux, par exemple logrotate

Certains programmes ont leurs propres utilitaires. Par exemple, le serveur Web Apache inclut un utilitaire rotatelogs .

RedGrittyBrick
la source
3
Mais vous ne devez pas le faire tant que le fichier est ouvert et qu'il y est toujours ajouté, car il écrirait dans le fichier maintenant supprimé et vous perdriez ces messages de journal.
Tarnay Kálmán
Vrai. Même si vous avez utilisé le même nom de fichier.
Hennes
dommage que le système d'exploitation ne vous laisse pas, ce serait certainement pratique pour les rotateurs de journaux de ne pas avoir à recharger les processus après la rotation: |
rogerdpack
25

Je pense que cette tâche peut être accomplie avec sed

sed -i '1,10d' myfile

supprimerait les lignes de la 1 re à la 10 e ligne du fichier.

Je pense que tout le monde devrait au moins jeter un oeil à cette doublure sed 1 .

Notez que cela ne fonctionne pas pour les fichiers journaux qui sont activement ajoutés à une application (comme indiqué dans la question).

sed -iva créer un nouveau fichier et «supprimer» le fichier en cours d'écriture. La plupart des applications continueront d'écrire des enregistrements de journal dans le fichier journal supprimé et continueront à remplir l'espace disque. Le nouveau fichier journal tronqué ne sera pas ajouté à. Cela ne cessera que lorsque l'application sera redémarrée ou qu'il sera autrement signalé de fermer et de rouvrir ses fichiers journaux. À ce stade, il y aura un écart (enregistrements de journal manquants) dans le nouveau fichier journal s'il y a eu une activité pouvant être enregistrée entre l'utilisation de sed et le redémarrage de l'application.

Un moyen sûr de le faire serait d'arrêter l'application, d'utiliser sed pour tronquer le journal, puis de redémarrer l'application. Cette approche peut être inacceptable pour certains services (par exemple, un serveur Web avec un débit élevé et des exigences de continuité de service élevées)

l1zard
la source
2
Savez-vous ce qu'il advient des applications en annexe?
Adam Matan
1
Supposons un gestionnaire de fichiers ouvert normal qui ajoute de temps en temps des lignes et des vidages.
Adam Matan
1
Je connais bien sed et extraire des lignes dans un nouveau fichier est une évidence avec sed. Le problème est de tout garder dans le même fichier.
Adam Matan
10
Non, cela ne devrait pas fonctionner. sed -icrée un nouveau fichier avec le contenu modifié et l'ancien est supprimé afin que vous n'éditiez pas le fichier actif: $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile------ Veuillez vérifier comment cela sed -ifonctionne. Pourquoi cette mauvaise réponse a-t-elle autant de votes positifs?
pabouk
1
La question indique "à partir d'un journal qui est activement ajouté par une application". Le mot clé est "activement". Peut-être que cette clarification a été ajoutée après la parution de votre réponse. Mais en l'état, les lecteurs qui gravitent vers «la plupart des votes positifs» seront trompés. Je n'ai pu voter qu'une seule fois.
Scott Prive
5

Non. Une solution à ce problème générique de croissance des fichiers journaux est la rotation des journaux. Cela implique le déplacement régulier (de nuit ou hebdomadaire, généralement) d'un fichier journal existant vers un autre nom de fichier et un nouveau démarrage avec un fichier journal vide. Après un certain temps, les anciens fichiers journaux sont jetés.

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

Tarnay Kálmán
la source
2

Ceci est une réponse , pas une solution. Il n'y a PAS de solution à la question. Le demandeur déclare clairement: "à partir d'un journal qui est activement ajouté par une application". Vous pouvez continuer à lire pour en savoir plus et passer à la fin pour une suggestion que je fais en fonction de ma présomption pourquoi ce code ne suit pas les meilleures pratiques de journalisation.

Pour être clair: d'autres «réponses» offrent ici la fausse promesse . Aucun changement de nom n'incitera l'application à utiliser le nouveau fichier. Les informations les plus utiles sont enfouies dans les commentaires faits à ces réponses incorrectes.

Les fichiers ACTIVE ne sont pas une sorte de conteneur dans lequel vous placez simplement des données. Un nom de fichier pointe vers UN inode (début du fichier) et chaque inode a un pointeur vers un autre inode (s'il y a plus de données). Cela signifie qu'un fichier continuellement écrit a un flux constant d'inodes qui y est ajouté, et ce que vous pensez d'un "fichier" est en fait une séquence de journaux d'inodes.

Imaginez que vous suiviez quelqu'un sur Google Maps et que cette personne pouvait se téléporter n'importe où dans le monde, à tout moment, et que vous essayiez de connecter ces points.

L'outil Linux "tronquer" peut supprimer les données à la fin du fichier, en parcourant simplement l'arborescence des inodes et (à l'emplacement / taille que vous désignez), il supprimera tous les pointeurs suivants de la pile. Faire l'inverse - supprimer les données au début du fichier - serait un processus si horriblement complexe et risqué de réécrire l'arbre inode en temps réel que personne n'écrira de tels outils pour le public, car ils échoueraient souvent et conduiraient à perte de données. Le wiki Inodes est court mais explique certains de ces concepts.

** Mon conseil: retournez ce problème - POURQUOI cette application se comporte-t-elle ainsi? Il existe de nombreuses bonnes pratiques de journalisation, mais elles sont souvent liées à ce qu'est réellement votre système de journalisation (syslog, etc.). Au fond, une application devrait "libérer" sa gestion du fichier, donc logrotate (etc) peut gérer le traitement ultérieur des anciennes données.

Chaque fois que j'entends "vers un fichier journal ACTIVE", je demande immédiatement à cette personne de me dire "l'histoire spéciale" derrière cette application. Habituellement, c'est "le développeur quitte, et nous ne pouvons pas changer le code. C'est en fait l'inverse de la sécurité, il a son propre ensemble de risques. Mais je suppose que vous voulez une solution qui évite de toucher le code source. Si c'est le cas, une question plus spécifique est nécessaire.

Scott Prive
la source
0

Ouverture en texte sublime La suppression des lignes et l'enregistrement du fichier fonctionnent d'une manière ou d'une autre, même si le fichier est ajouté, mais je suis venu ici pour rechercher la solution pour une solution en ligne de commande, donc je laisserais cette solution fonctionnelle mais inutile ici !!

Ashok Kumar Sahoo
la source
-1

Peut-être copier, tronquer, ramener la copie à la troncature size = 0 et supprimer la copie?

Mieux encore, copie de queue à queue, tronquez l'original, concatendez la copie de queue sur l'original.

Vous obtenez des lignes dans le journal à la longueur de la queue, donc mieux qu'une limite de longueur d'octets.

Modification des détails du commentaire:

D'abord, nous avons un script de journalisation en Python3 tout ce que vous voulez

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)

Ensuite, nous avons notre troncateur

#!/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 affiche 80 à 89

le journal affiche 90 à la fin

De toute façon, là où il y a une volonté, il y a un moyen.

De nombreux exemples plus complexes de consolidateurs et de la façon dont le flux d'écriture est ouvert ou fermé peuvent nécessiter un ajustement par cœur de processeur, etc.

Maître James
la source
"à partir d'un journal qui est activement ajouté par une application". Le problème que votre solution ignore est que le fichier journal est utilisé "en permanence" par l'application - ce qui signifie que l'inode du fichier journal reste en jeu. Votre solution «sauvegarde» les données du fichier journal, qui peuvent avoir des utilisations en dehors de cette question.
Scott Prive
Merci pour votre commentaire et vote négatif? J'ai modifié un exemple rapide et bon marché comme matière à réflexion, vous devrez réfléchir plus profondément à votre situation, mais là où il y a une volonté, il y a un moyen.
Master James
Ne pensez pas que c'était mon vote négatif, mais je pense que le point a été martelé dans les commentaires de l'autre réponse: SI vous copiez un fichier journal, alors ce n'est plus le fichier journal actif ... quoi que vous fassiez. Le descripteur de fichier de l'application pointera toujours vers l'inode du fichier journal d'origine. Pensez-y de cette façon: vous avez une application qui utilise des fonctions de journalisation non standard et ajoute continuellement des octets au fichier qu'elle a ouvert.
Scott Prive
1
Désolé de déduire. Oui, l'inode doit rester le même, c'est pourquoi l'exemple / la preuve donné utilise tronquer, et encore une fois cela dépend de la situation (les options pour tous se cachent apparemment dans le site).
Master James