Dateien (à la tail -f) in einem ganzen Verzeichnis überwachen (auch neue)


53

Normalerweise schaue ich mir viele Logs in einem Verzeichnis an tail -f directory/*. Das Problem ist, dass danach ein neues Protokoll erstellt wird, das nicht auf dem Bildschirm angezeigt wird (da *es bereits erweitert wurde).

Gibt es eine Möglichkeit, jede Datei in einem Verzeichnis zu überwachen, auch die, die nach dem Start des Prozesses erstellt wurden?

Antworten:


44

Sie können tail Multi ple Dateien mit ... multitail .

multitail -Q 1 'directory/*'

-Q 1 PATTERNbedeutet, alle 1 Sekunde nach neuen Inhalten in vorhandenen oder neuen Dateien zu suchen, die mit PATTERN übereinstimmen . Zeilen aus allen Dateien werden im selben Fenster angezeigt. Verwenden Sie diese -qOption -Q, um separate Fenster zu erstellen .


10

xtailist auch eine Alternative. Seine Manpage beschreibt es als:

Xtail überwacht eine oder mehrere Dateien und zeigt alle Daten an, die seit dem Aufruf des Befehls in eine Datei geschrieben wurden. Dies ist sehr nützlich, um mehrere Protokolldateien gleichzeitig zu überwachen. Wenn ein in der Befehlszeile angegebener Eintrag ein Verzeichnis ist, werden alle Dateien in diesem Verzeichnis überwacht, einschließlich der Dateien, die nach dem xtail-Aufruf erstellt wurden. Wenn ein in der Befehlszeile angegebener Eintrag nicht vorhanden ist, wird er von xtail gesucht und überwacht, sobald er erstellt wurde. Beim Wechseln der Dateien in der Anzeige wird ein Banner mit dem Pfadnamen der Datei gedruckt.

Ein Unterbrechungszeichen (normalerweise STRG / C oder ENTF) zeigt eine Liste der zuletzt überwachten geänderten Dateien an. Senden Sie ein Quit-Signal (normalerweise CTRL / Backslash), um xtail zu stoppen.


1
Link ist gebrochen, aber ich denke , ist das gleiche wie: manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
edpaez

7

Keine Ahnung von einer Shell - Lösung, aber (unter der Annahme , Linux 1) inotifykönnte der Weg zu gehen ... sehen Sie dieses Beispiel nachahmentail -F (mit pyinotify), vielleicht kann sie als Grundlage verwendet werden , für die folgenden ein ganzes Verzeichnis .

Im Allgemeinen inotifykönnen Verzeichnisse überwachen (unter Berufung auf man 7 inotify)

Die folgenden Bits können in mask angegeben werden, wenn inotify_add_watch (2) aufgerufen wird, und können in dem von read (2) zurückgegebenen Maskenfeld zurückgegeben werden:

IN_ACCESS         File was accessed (read) (*).
IN_ATTRIB         Metadata changed, e.g., permissions, timestamps,
                    extended attributes, link count (since Linux 2.6.25),
                    UID, GID, etc. (*).
IN_CLOSE_WRITE    File opened for writing was closed (*).
IN_CLOSE_NOWRITE  File not opened for writing was closed (*).
IN_CREATE         File/directory created in watched directory (*).
IN_DELETE         File/directory deleted from watched directory (*).
IN_DELETE_SELF    Watched file/directory was itself deleted.
IN_MODIFY         File was modified (*).
IN_MOVE_SELF      Watched file/directory was itself moved.
IN_MOVED_FROM     File moved out of watched directory (*).
IN_MOVED_TO       File moved into watched directory (*).
IN_OPEN           File was opened (*).

Bei der Überwachung eines Verzeichnisses können die oben mit einem Sternchen (*) gekennzeichneten Ereignisse für Dateien im Verzeichnis auftreten. In diesem Fall gibt das Namensfeld in der zurückgegebenen Struktur inotify_event den Namen der Datei im Verzeichnis an.

(... und pyinotifyfolgt genau diesen Optionen)

1: BSDs haben eine ähnliche Sache, kqueue. Möglicherweise ist eine plattformübergreifende Lösung unter Verwendung erreichbare GIO ( Python - Bindungen ) als Abstraktionsschicht kann , da sie, neben inotify, auch verwenden ,kqueue


2

Ich habe ein schnelles geschrieben, das das Bedürfnis erfüllt.

#!/bin/bash
LOG_PATTERN=$1
BASE_DIR=$(dirname $LOG_PATTERN* | head -1)

run_thread (){
    echo Running thread
    tail -F $LOG_PATTERN* &
    THREAD_PID=$!
}

# When someone decides to stop the script - killall children
cleanup () {
    pgrep -P $$ | xargs -i kill {}
    exit
}

trap cleanup SIGHUP SIGINT SIGTERM

if [ $# -ne 1 ]; then
    echo "usage: $0 <directory/pattern without * in the end>"
    exit 1
fi

# Wait for the directory to be created
if [ ! -d $BASE_DIR ] ; then
    echo DIR $BASE_DIR does not exist, waiting for it...
    while [ ! -d $BASE_DIR ] ; do
        sleep 2
    done
    echo DIR $BASE_DIR is now online
fi

# count current number of files
OLD_NUM_OF_FILES=$(ls -l $LOG_PATTERN* 2>/dev/null | wc -l)

# Start Tailing
run_thread

while [ 1 ]; do
    # If files are added - retail
    NUM_FILES=$(ls -l $LOG_PATTERN* 2>/dev/null | wc -l)
    if [ $NUM_FILES -ne $OLD_NUM_OF_FILES ]; then
        OLD_NUM_OF_FILES=$NUM_FILES
        kill $THREAD_PID
        run_thread
    fi
    sleep 1
done

1
Eigentlich kann man den Sleep 1 in der Hauptschleife weglassen, wird bissiger, um neue Dateien zu bekommen. Aber ich mag diese Art von beschäftigtem Warten nicht
Itamar

Aufgrund sleepdessen ist dies kein geschäftiges Warten, sondern schont die CPU lediglich beim Polling. Man könnte es in sleep 0.2s(GNU sleep) oder was auch immer ändern , um es bei Bedarf schneller zu machen.
Ned64

2

Auch können Sie Verzeichnis mit ansehen watch

watch -n0,1 "ls -lrt /directory/ | tail"

Minor nitpick: watchZeichnet den Bildschirm im alternativen Puffer mit den ersten x Zeilen der Ausgabe des Befehls neu. Wenn sich bei einer Reihe von Dateien ohne Änderungen die früheren Dateien nicht ändern, wird tailmöglicherweise jedes Mal dasselbe gerendert, sodass keine zusätzlichen Einträge angezeigt werden, da sie in späteren Dateien "unter" dem unteren Rand des Fensters angezeigt werden Bildschirm. Für eine kurze Datei ist dies jedoch in Ordnung ...
jimbobmcgee

Dies gibt keine Lösung für das ursprüngliche Problem. Dies gibt nur (die letzten paar Zeilen von) eine Verzeichnisliste aus (wiederholt, immer aktuell - dank watch), anstatt der neuesten Zeilen aller Dateien (einschließlich neuer) in diesem Verzeichnis.
trs
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.