2010-08-05 5 views
9

я работаю с некоторыми журнала системы, которая создает файл журнала каждый час, как следует:Как хвост -f последней лог-файл с заданным шаблоном

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

Я пытаюсь хвосту следовать последним лог-файл дает образец (например, SoftwareLog *) и я понимаю, что есть:

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

но следовать только одно конкретное имя - и они имеют разные названия по дате и времени. Я пытался что-то вроде:

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

но подстановочные заявление resoved, прежде чем она будет передана на хвост и не переоформить каждый раз хвостовые повторные попытки.

Любые предложения?

ответ

6

[Edit: после быстрого Googling для инструмента]

Вы могли бы хотеть попробовать multitail - http://www.vanheusden.com/multitail/

Если вы хотите придерживаться ответа Деннис Уильямсона (и я имею Добавили +1 он соответственно), вот пробелы, заполненные для вас.

В вашей оболочке, запустите скрипт (или его ЗШ эквивалента, я взбитое это в Баше, прежде чем я увидел ЗШ тега):

#!/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 

фон, что процесс, используя обычный метод (опять же, я не знаю, ЗШ, так что он может быть разным) ...

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

Тогда tail -F $SYMLINK_PATH так, что хвост отдаёт изменение символической ссылки или вращения файла.

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

[Изменить: Удалено ошибочное «j» из конца одной из строк.Кроме того, было плохое имя переменной «lastModifiedFile» не существовало, собственно имя, которое вы установили в «LastModified»]

+0

спасибо, мне, возможно, придется это сделать. Я смотрел многопользовательский режим, но, к сожалению, он интерактивен, что означает, что я не могу его вывести в другом месте. Я попробую и посмотрю, где я. Дело в том, что мне бы хотелось, чтобы это выполнялось только при запуске хвоста и выходе из него, и я не уверен, как это сделать. – Axiverse

+0

Спасибо! Это в основном единственное решение, которое мне понравилось (и я много искал для этого). –

+0

Neato. Отредактировано, чтобы исправить ошибку, где она не будет работать в первый раз для меня. (Поскольку getCurrentlySymlinkedFile возвращал пустую строку, а typo'd несуществующий lastModifiedDate также оценивался пустой строкой.) – funroll

2

Я не тестировал это, но подход, который может работать, - это запустить фоновый процесс, который создает и обновляет символическую ссылку до последнего файла журнала, а затем вы должны указать tail -f (или tail -F) символическую ссылку.

11

Я считаю, что самое простое решение заключается в следующем:

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

Теперь, если ваш каталог содержит другие файлы журналов, как «SystemLog», и вы хотите только последний файл «SoftwareLog», то вы бы просто включать Grep следующим образом:

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

или использовать голову вместо хвоста, чтобы сделать вещи проще =) ls -t | head -1 | xargs tail -F –

+0

Или может использоваться: '' 'tail -f SoftwareLog.'date + '% Y-% m-% d-% H''' '' –

0
#!/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 

затем запустите его как: tail.sh 'SoftwareLog*'

Сценарий потеряет некоторые строки журнала, если журналы записываются между проверками. Но, по крайней мере, это единственный скрипт, без каких-либо символических ссылок.