如何使用给定模式尾随最新的日志文件

时间:2010-08-05 15:42:36

标签: linux logging zsh tail

我使用一些日志系统,每小时创建一个日志文件,如下所示:

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])  

但是通配符语句在传递给尾部之前已经重新发送,并且不会在每次尾部重试时重新执行。

有什么建议吗?

5 个答案:

答案 0 :(得分:12)

我认为最简单的解决方案如下:

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

现在,如果您的目录包含其他日志文件,如“SystemLog”,并且您只需要最新的“SoftwareLog”文件,那么您只需要包含一个grep,如下所示:

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

答案 1 :(得分:7)

[编辑:快速搜索工具后]

您可能想要试用多笔 - http://www.vanheusden.com/multitail/

如果你想坚持丹尼斯威廉姆森的回答(而且我已经相应地给他做了1次),这里有填空的空白。

在你的shell中,运行以下脚本(或者它的zsh等价物,我在看到zsh标签之前用bash鞭打了它):

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

答案 2 :(得分:3)

我没有对此进行测试,但可行的方法是运行后台进程,创建并更新符号链接到最新的日志文件,然后你tail -f(或tail -F )符号链接。

答案 3 :(得分:1)

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

如果在检查之间写入日志,脚本将丢失一些日志行。但至少它是一个单独的脚本,不需要符号链接。

答案 4 :(得分:0)

我们每天的循环日志文件为:/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'`