11 votes

Comment faire un tail -f du dernier fichier journal avec un motif donné

Je travaille avec un système d'enregistrement qui crée un fichier journal toutes les heures, comme suit :

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

J'essaie de suivre le dernier fichier journal en donnant un modèle (par exemple SoftwareLog*) et je me rends compte qu'il y en a un :

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

mais qui ne suivent qu'un seul nom spécifique - et ceux-ci ont des noms différents selon la date et l'heure. J'ai essayé quelque chose comme :

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

mais l'instruction joker est traitée avant d'être transmise à tail et n'est pas ré-exécutée à chaque fois que tail réessaie.

Des suggestions ?

13voto

devup Points 131

Je pense 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 que vous ne voulez que le dernier fichier "SoftwareLog", il vous suffit d'inclure un grep comme suit :

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

7voto

whaley Points 8789

[Edit : après une rapide recherche d'un outil sur Google].

Vous pourriez vouloir essayer le multitail - http://www.vanheusden.com/multitail/

Si vous voulez vous en tenir à la réponse de Dennis Williamson (et j'ai mis un +1 en conséquence), voici les blancs remplis pour vous.

Dans votre shell, exécutez le script suivant (ou son équivalent zsh, je l'ai fait en bash avant de voir le tag 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

Mettez ce processus en arrière-plan en utilisant la méthode normale (encore une fois, je ne connais pas zsh, donc ça peut être différent)...

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

Puis tail -F $SYMLINK_PATH de façon à ce que la queue gère le changement du lien symbolique ou une rotation du fichier.

C'est un peu compliqué, mais je ne connais pas d'autre moyen de faire cela avec la queue. Si quelqu'un d'autre connaît un utilitaire qui gère cela, alors qu'il se manifeste parce que j'adorerais le voir moi-même aussi - les applications comme Jetty par défaut font des journaux de cette façon et je script toujours un symlinking script exécuter sur un cron pour compenser cela.

[Edit : Suppression d'un 'j' erroné à la fin d'une des lignes. Vous aviez également un mauvais nom de variable "lastModifiedFile" qui n'existait pas, le nom correct que vous avez défini est "lastModified"].

3voto

Dennis Williamson Points 105818

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

1voto

allanon256 Points 11
#!/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-le en tant que : tail.sh 'SoftwareLog*'

Le script perdra certaines lignes de journal si les journaux sont écrits entre les vérifications. Mais au moins, c'est un seul script, sans lien symbolique nécessaire.

0voto

Shashank Agrawal Points 14533

Nous avons des fichiers journaux qui tournent quotidiennement comme : /var/log/grails/customer-2020-01-03.log . Pour tail la dernière, la commande suivante a bien fonctionné pour moi :

tail -f /var/log/grails/customer-`date +'%Y-%m-%d'`.log

( NOTE : pas d'espace après le + dans l'expression)

Donc, pour vous, ce qui suit devrait fonctionner (si vous êtes dans le même répertoire que les journaux) :

tail -f SoftwareLog.`date +'%Y-%m-%d-%H'`

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X