контролировать файлы (а-ля tail -f) во всем каталоге (даже в новых)


53

Я обычно смотрю много логов в директории делаю tail -f directory/*. Проблема в том, что новый журнал создается после этого, он не будет отображаться на экране (потому что *уже был расширен).

Есть ли способ контролировать каждый файл в каталоге, даже те, которые создаются после запуска процесса?

Ответы:


44

Вы можете создать несколько файлов с помощью ... multitail .

multitail -Q 1 'directory/*'

-Q 1 PATTERNозначает проверять наличие нового содержимого в существующих или новых файлах, соответствующих шаблону, каждую 1 секунду. Строки из всех файлов отображаются в одном и том же окне, используйте -qвместо того, -Qчтобы иметь отдельные окна.


10

xtailтоже альтернатива. Его страница руководства описывает это как:

Xtail контролирует один или несколько файлов и отображает все данные, записанные в файл с момента вызова команды. Это очень полезно для мониторинга нескольких файлов журнала одновременно. Если запись, указанная в командной строке, является каталогом, будут отслеживаться все файлы в этом каталоге, включая файлы, созданные после вызова xtail. Если запись, заданная в командной строке, не существует, xtail будет отслеживать ее и отслеживать после ее создания. При переключении файлов на дисплее печатается баннер с указанием пути к файлу.

Символ прерывания (обычно CTRL / C или DEL) отображает список последних просмотренных измененных файлов. Отправьте сигнал выхода (обычно CTRL / обратный слеш), чтобы остановить xtail.


1
Ссылка не работает, но я думаю, что это то же самое, что и manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
— edpaez

7

Не знаю, как решить проблему с оболочкой, но (предполагая, что Linux 1) inotifyможет стать способом ... посмотрите на этот пример, имитирующийtail -F (использующий pyinotify), может быть, его можно использовать как основу для следования целому каталогу .

В общем, inotifyможно отслеживать каталоги (цитируя man 7 inotify)

Следующие биты могут быть указаны в маске при вызове inotify_add_watch (2) и могут быть возвращены в поле маски, возвращаемом 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 (*).

При мониторинге каталога события, отмеченные звездочкой (*) выше, могут происходить для файлов в каталоге, и в этом случае поле имени в возвращенной структуре inotify_event идентифицирует имя файла в каталоге.

(... и pyinotifyвнимательно следит за этими вариантами)

1У BSD есть похожая вещь kqueue. Возможно, кросс-платформенное решение достижимо, используя GIO ( привязки Python ) в качестве уровня абстракции, так как оно может, кроме того inotify, использоватьkqueue


2

Я написал быстрый, который удовлетворяет потребности.

#!/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
На самом деле, вы можете опустить сон 1 в главном цикле, будет более быстро получать новые файлы. Но мне не нравятся такие занятые ожидания
— Итамар

Из-за того, что sleepэто не занятое ожидание, а мягкая загрузка процессора, просто опрос. Можно изменить его на sleep 0.2s(GNU sleep) или что-то еще, чтобы сделать его быстрее, если это необходимо.
— Нед64

2

Также вы можете посмотреть каталог с watch

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

Незначительный зазор: watchперерисовывает экран в альтернативном буфере с первыми x строками вывода команды. В нескольких файлах без изменений, если более ранние файлы не изменяются, они tailмогут каждый раз отображать одно и то же, так что у вас не появляется дополнительных записей, так как они отображаются в более поздних файлах «ниже» в нижней части окна. экран. Для короткого файла, тем не менее, это хорошо ...
— jimbobmcgee

Это не дает решения исходной проблемы. Это просто выводит (последние несколько строк) список каталогов (многократно, всегда актуальный - спасибо watch) вместо самых последних строк всех файлов (включая новые) в этом каталоге.
— trs
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.