11

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

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

但是通配符语句在它被传递给tail之前被resolved并且不会在每次tail重试时重新执行。

有什么建议么?

4

6 回答 6

13

我相信最简单的解决方案如下:

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

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

tail -f `ls -tr | grep SoftwareLog | tail -n 1`
于 2011-01-12T16:14:17.687 回答
7

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

您可能想尝试 multitail - http://www.vanheusden.com/multitail/

如果您想坚持 Dennis Williamson 的回答(我已经相应地为他 +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”]

于 2010-08-06T02:04:16.880 回答
3

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

于 2010-08-06T01:26:58.447 回答
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*'

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

于 2014-09-25T22:11:00.853 回答
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'`
于 2020-01-03T05:58:39.380 回答
0

我相信最简单的方法是使用taillshead,试试这样的

tail -f `ls -t SoftwareLog* | head -1`
于 2022-01-05T07:29:05.977 回答