2010-08-05 14 views
9

Je travaille avec un système de journal qui crée un fichier journal toutes les heures, comme suit:Comment tail -f le dernier fichier journal avec un modèle donné

SoftwareLog.2010-08-01-08 
SoftwareLog.2010-08-01-09 
SoftwareLog.2010-08-01-10 

Je suis en train de queue pour suivre la dernière le fichier journal donnant un motif (par exemple SoftwareLog *) et je me rends compte qu'il ya:

tail -F (tail --follow=name --retry) 

mais seulement suivre un nom spécifique - et ceux-ci ont des noms différents par date et heure. J'ai essayé quelque chose comme:

tail --follow=name --retry SoftwareLog*(.om[1]) 

mais la déclaration générique est resoved avant qu'il ne soit transmis à la queue et ne réexécuter pas everytime queue retries.

Des suggestions?

Répondre

6

[Edit: après une googler rapide pour un outil]

Vous pouvez essayer multitail - http://www.vanheusden.com/multitail/

Si vous voulez coller avec la réponse de Dennis Williamson (et je l'ai + 1'ed lui en conséquence) voici les blancs remplis pour vous.

Dans votre shell, exécutez le script suivant (ou son équivalent zsh, je fouetté ce en bash avant d'avoir vu l'étiquette zsh):

#!/bin/bash 

TARGET_DIR="some/logfiles/" 
SYMLINK_FILE="SoftwareLog.latest" 
SYMLINK_PATH="$TARGET_DIR/$SYMLINK_FILE" 

function getLastModifiedFile { 
    echo $(ls -t "$TARGET_DIR" | grep -v "$SYMLINK_FILE" | head -1) 
} 

function getCurrentlySymlinkedFile { 
    if [[ -h $SYMLINK_PATH ]] 
    then 
     echo $(ls -l $SYMLINK_PATH | awk '{print $NF}') 
    else 
     echo "" 
    fi 
} 

symlinkedFile=$(getCurrentlySymlinkedFile) 
while true 
do 
    sleep 10 
    lastModified=$(getLastModifiedFile) 
    if [[ $symlinkedFile != $lastModified ]] 
    then 
     ln -nsf $lastModified $SYMLINK_PATH 
     symlinkedFile=$lastModified 
    fi 
done 

Contexte que processus selon la méthode normale (encore une fois, je ne sais pas zsh, il peut être différent) ...

./updateSymlink.sh 2>&1 > /dev/null

Puis tail -F $SYMLINK_PATH de telle sorte que la queue remet le changement du lien symbolique ou une rotation du fichier.

Ceci est légèrement compliqué, mais je ne connais pas d'autre moyen de le faire avec queue. Si quelqu'un d'autre connaît un utilitaire qui gère cela, alors laissez-les aller de l'avant parce que j'aimerais le voir moi aussi - des applications comme Jetty par défaut se connectent de cette façon et j'écris toujours un script symlinking sur un cron pour compenser pour ça. [Edit: Suppression d'un "j" erroné à la fin de l'une des lignes.Vous avez également eu un mauvais nom de la variable « lastModifiedFile » n'existait pas, le nom propre que vous avez défini est « lastModified »]

+0

merci, je pourrais avoir à le faire. J'ai regardé dans multitail, mais malheureusement c'est interactif seulement qui signifie que je ne peux pas diriger sa sortie ailleurs. Je vais essayer et voir où je vais. La chose est que je voudrais que cela ne fonctionne que lorsque la queue est en cours d'exécution et de sortie lorsque cela se termine, et je ne suis pas sûr de savoir comment faire cela. – Axiverse

+0

Merci! C'est fondamentalement la seule solution que j'ai aimé (et j'ai beaucoup cherché pour cela). –

+0

Neato. Edité pour corriger un bug où ça ne marcherait pas la première fois pour moi. (Parce que getCurrentlySymlinkedFile renvoyait une chaîne vide, et le lastModifiedDate inexistant typo'd a également évalué à une chaîne vide.) – funroll

2

Je n'ai pas testé cela, mais une approche qui pourrait fonctionner serait d'exécuter un processus d'arrière-plan qui crée et met à jour un lien symbolique vers le dernier fichier journal, puis tail -f (ou tail -F) le lien symbolique.

11

Je crois que la solution la plus simple est la suivante:

tail -f `ls -tr | tail -n 1` 

Maintenant, si votre répertoire contient d'autres fichiers journaux comme « SystemLog » et vous ne voulez que le dernier fichier « SoftwareLog », alors vous simplement inclure un grep comme suit:

tail -f `ls -tr | grep SoftwareLog | tail -n 1` 
+6

ou utiliser la tête au lieu de la queue, pour rendre les choses plus simples =) ls -t | tête -1 | xargs tail -F –

+0

Ou peut être utilisé: '' 'tail -f SoftwareLog.'date + '% Y-% m-% d-% H''' '' –

0
#!/bin/bash 

PATTERN="$1" 

# Try to make sure sub-shells exit when we do. 
trap "kill -9 -- -$BASHPID" SIGINT SIGTERM EXIT 

PID=0 
OLD_FILES="" 
while true; do 
    FILES="$(echo $PATTERN)" 
    if test "$FILES" != "$OLD_FILES"; then 
    if test "$PID" != "0"; then 
     kill $PID 
     PID=0 
    fi 
    if test "$FILES" != "$PATTERN" || test -f "$PATTERN"; then 
     tail --pid=$$ -n 0 -F $PATTERN & 
     PID=$! 
    fi 
    fi 
    OLD_FILES="$FILES" 
    sleep 1 
done 

ensuite, exécutez comme: tail.sh 'SoftwareLog*'

Le script perd certaines lignes de journal si les journaux sont écrits entre les contrôles. Mais au moins, c'est un script unique, sans lien symbolique requis.