memonitor file (à la tail -f) di seluruh direktori (bahkan yang baru)


53

Saya biasanya menonton banyak log di direktori lakukan tail -f directory/*. Masalahnya adalah bahwa log baru dibuat setelah itu, tidak akan muncul di layar (karena *sudah diperluas).

Apakah ada cara untuk memonitor setiap file dalam direktori, bahkan yang dibuat setelah proses dimulai?

Jawaban:


44

Anda bisa ekor multi- file ple dengan ... MultiTail .

multitail -Q 1 'directory/*'

-Q 1 PATTERNartinya memeriksa konten baru di file yang ada atau file baru yang cocok dengan POLA setiap 1 detik. Baris dari semua file ditampilkan di jendela yang sama, gunakan -qbukannya -Qmemiliki jendela terpisah.


10

xtailjuga merupakan alternatif. Halaman manualnya menggambarkannya sebagai:

Xtail memonitor satu atau lebih file, dan menampilkan semua data yang ditulis ke file sejak pemanggilan perintah. Ini sangat berguna untuk memonitor banyak file log secara bersamaan. Jika entri yang diberikan pada baris perintah adalah direktori, semua file dalam direktori itu akan dipantau, termasuk yang dibuat setelah permintaan xtail. Jika entri yang diberikan pada baris perintah tidak ada, xtail akan melihatnya dan memonitornya setelah dibuat. Saat berpindah file di layar, spanduk yang menunjukkan pathname file dicetak.

Karakter interrupt (biasanya CTRL / C atau DEL) akan menampilkan daftar file termodifikasi yang paling baru ditonton. Kirim sinyal keluar (biasanya CTRL / backslash) untuk menghentikan xtail.


1
Tautan rusak, tetapi saya pikir sama dengan: manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
edpaez

7

Tidak tahu tentang solusi shell, tetapi (dengan asumsi Linux 1) inotifybisa menjadi cara untuk pergi ... lihat contoh ini menirutail -F (menggunakan pyinotify), mungkin itu dapat digunakan sebagai dasar untuk mengikuti seluruh direktori .

Secara umum, inotifydapat memonitor direktori (mengutip man 7 inotify)

Bit-bit berikut ini dapat ditentukan dalam mask saat memanggil inotify_add_watch (2) dan dapat dikembalikan dalam bidang mask yang dikembalikan oleh baca (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 (*).

Saat memantau direktori , peristiwa yang ditandai dengan tanda bintang (*) di atas dapat terjadi untuk file dalam direktori, dalam hal ini bidang nama dalam struktur inotify_event yang dikembalikan mengidentifikasi nama file dalam direktori.

(... dan pyinotifyikuti dengan cermat opsi-opsi tesis ini)

1: BSD memiliki hal serupa kqueue,. Mungkin solusi lintas-platform dapat dicapai dengan menggunakan GIO ( Python bindings ) sebagai lapisan abstraksi karena dapat, di samping inotify, juga menggunakankqueue


2

Saya menulis yang cepat yang memenuhi kebutuhan.

#!/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
Sebenarnya, Anda bisa menghilangkan sleep 1 di loop utama, akan lebih cepat untuk mendapatkan file baru. Tapi saya tidak suka menunggu yang sibuk seperti itu
Itamar

Karena sleepini bukan menunggu sibuk tetapi lunak pada CPU, hanya polling. Seseorang dapat mengubahnya ke sleep 0.2s(tidur GNU) atau apa pun untuk membuatnya lebih cepat jika diperlukan.
Ned64

2

Anda juga dapat menonton direktori dengan watch

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

Minor nitpick: watchmenggambar ulang layar di buffer alternatif, dengan x baris pertama output dari perintah. Di sejumlah file tanpa perubahan, jika file sebelumnya tidak berubah, tailmungkin membuat hal yang sama setiap kali, sehingga Anda mendapatkan tampilan tidak ada entri tambahan, karena mereka diambil di file kemudian 'di bawah' bagian bawah layar. Namun, untuk file pendek, ini tidak apa-apa ...
jimbobmcgee

Ini tidak memberikan solusi untuk masalah aslinya. Ini hanya menampilkan (beberapa baris terakhir) daftar direktori (berulang kali, selalu terkini - terima kasih watch), bukan baris terbaru dari semua file (termasuk yang baru) di direktori itu.
trs
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.