Как установить последний файл журнала с заданным шаблоном
Я работаю с некоторой системой журналов, которая создает файл журнала каждый час, как показано ниже:
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])
но подстановочный оператор восстанавливается до того, как он будет передан хвосту, и не будет выполняться каждый раз при повторных попытках хвоста.
Какие-либо предложения?
6 ответов
[Редактировать: после быстрого поиска в инструменте]
Вы можете попробовать мультитейл - http://www.vanheusden.com/multitail/
Если вы хотите придерживаться ответа Денниса Уильямсона (и я его соответственно добавил +1), вот вам заполненные пробелы.
В вашей оболочке запустите следующий скрипт (или это эквивалентно zsh, я поднял это в bash до того, как увидел тег zsh):
#!/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
Фоновая обработка этого процесса с использованием обычного метода (опять же, я не знаю, zsh, поэтому он может отличаться)...
./updateSymlink.sh 2>&1 > /dev/null
затем tail -F $SYMLINK_PATH
так что хвост передает изменение символической ссылки или вращение файла.
Это немного запутанно, но я не знаю другого способа сделать это с хвостом. Если кто-то еще знает об утилите, которая обрабатывает это, то пусть они сделают шаг вперед, потому что я тоже хотел бы увидеть это сам - приложения, такие как Jetty, по умолчанию делают логи таким образом, и я всегда пишу скрипт для запуска символьных ссылок, запускаемый на cron, чтобы компенсировать для этого.
[Редактировать: убрал ошибочный 'j' с конца одной из строк. У вас также было неверное имя переменной "lastModifiedFile", которого не было, правильное имя, которое вы указали, - "lastModified"]
Я считаю, что самое простое решение заключается в следующем:
tail -f `ls -tr | tail -n 1`
Теперь, если ваш каталог содержит другие файлы журнала, такие как "SystemLog", и вам нужен только самый последний файл "SoftwareLog", тогда вы просто добавили бы grep следующим образом:
tail -f `ls -tr | grep SoftwareLog | tail -n 1`
Я не проверял это, но подход, который может работать, состоял бы в том, чтобы запустить фоновый процесс, который создает и обновляет символическую ссылку на последний файл журнала, а затем вы бы tail -f
(или же tail -F
) символическая ссылка.
#!/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*'
Скрипт потеряет несколько строк журнала, если записи записываются между проверками. Но, по крайней мере, это один скрипт, без символических ссылок.
У нас есть ежедневно меняющиеся файлы журналов: /var/log/grails/customer-2020-01-03.log
. Чтобыtail
самый последний, у меня отлично сработала следующая команда:
tail -f /var/log/grails/customer-`date +'%Y-%m-%d'`.log
(ПРИМЕЧАНИЕ: после+
подпишитесь в выражении)
Итак, для вас должно работать следующее (если вы находитесь в том же каталоге журналов):
tail -f SoftwareLog.`date +'%Y-%m-%d-%H'`
Я считаю, что самый простой способ - использовать tail с ls и head , попробуйте что-то вроде этого
tail -f `ls -t SoftwareLog* | head -1`