monitoruj pliki (à la tail -f) w całym katalogu (nawet nowym)


53

Zwykle oglądam wiele dzienników w katalogu tail -f directory/*. Problem polega na tym, że po utworzeniu nowego dziennika nie będzie on wyświetlany na ekranie (ponieważ *został już rozwinięty).

Czy istnieje sposób monitorowania każdego pliku w katalogu, nawet tych, które są tworzone po rozpoczęciu procesu?

Odpowiedzi:


44

Można ogon obsługujący kilka plików z ple ... multitail .

multitail -Q 1 'directory/*'

-Q 1 PATTERNoznacza sprawdzanie nowej zawartości w istniejących lub nowych plikach pasujących WZÓR co 1 sekundę. Linie ze wszystkich plików są wyświetlane w tym samym oknie, użyj -qzamiast, -Qaby mieć osobne okna.


10

xtailjest również alternatywą. Strona man opisuje to jako:

Xtail monitoruje jeden lub więcej plików i wyświetla wszystkie dane zapisane do pliku od czasu wywołania polecenia. Jest to bardzo przydatne do monitorowania wielu plików dziennika jednocześnie. Jeśli pozycja podana w wierszu poleceń to katalog, wszystkie pliki w tym katalogu będą monitorowane, w tym pliki utworzone po wywołaniu xtail. Jeśli wpis podany w wierszu poleceń nie istnieje, xtail będzie go szukał i monitorował po utworzeniu. Podczas przełączania plików na wyświetlaczu drukowany jest baner pokazujący nazwę pliku.

Znak przerwania (zwykle CTRL / C lub DEL) wyświetli listę ostatnio modyfikowanych plików do oglądania. Wyślij sygnał wyjścia (zwykle CTRL / ukośnik odwrotny), aby zatrzymać xtail.


1
Link jest uszkodzony, ale myślę, że jest taki sam jak: manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
edpaez

7

Nie mam pojęcia o rozwiązaniu powłoki, ale (zakładając, że Linux 1) inotifymoże być właściwą drogą ... zobacz ten przykład naśladującytail -F (korzystający pyinotify), może może być wykorzystany jako podstawa do śledzenia całego katalogu .

Ogólnie inotifymożna monitorować katalogi (powołując się man 7 inotify)

Następujące bity można określić w masce podczas wywoływania inotify_add_watch (2) i mogą zostać zwrócone w polu maski zwróconym przez read (2):

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 (*).

Podczas monitorowania katalogu , zdarzenia oznaczone gwiazdką (*) powyżej mogą wystąpić dla plików w katalogu, w którym to przypadku pole nazwy w zwróconej strukturze inotify_event identyfikuje nazwę pliku w katalogu.

(... i pyinotifyściśle przestrzega tych opcji)

1: BSD mają podobną rzecz, kqueue. Może to rozwiązanie przekroju platforma jest osiągalna przy użyciu GIO ( wiązań Python ) jako warstwa abstrakcji, ponieważ mogą obok inotify, również użyćkqueue


2

Napisałem szybki, który spełnia potrzeby.

#!/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
W rzeczywistości możesz pominąć tryb uśpienia 1 w głównej pętli, będzie bardziej zgryźliwy, aby uzyskać nowe pliki. Ale nie lubię tego rodzaju zajętych oczekiwań
Itamar

Z sleeptego powodu nie jest to zajęte oczekiwanie, ale łagodny procesor, tylko odpytywanie. Można to zmienić na sleep 0.2s(sen GNU) lub cokolwiek, aby w razie potrzeby przyspieszyć.
Ned64

2

Możesz także oglądać katalog za pomocą watch

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

Drobny nitpick: watchprzerysowuje ekran w alternatywnym buforze, z pierwszymi x liniami wyjścia z polecenia. W przypadku wielu plików bez zmian, jeśli wcześniejsze pliki nie ulegną zmianie, tailmoże to renderować to samo za każdym razem, więc pojawia się brak dodatkowych wpisów, ponieważ są one rysowane w późniejszych plikach „poniżej” dolnej części ekran. Krótko mówiąc, w porządku ...
jimbobmcgee,

To nie daje rozwiązania pierwotnego problemu. To tylko wypisuje (kilka ostatnich wierszy) listę katalogów (wielokrotnie, zawsze aktualna - dzięki watch), zamiast najnowszych linii wszystkich plików (w tym nowych) w tym katalogu.
trs
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.