简体   繁体   English

如何使用给定模式 tail -f 最新的日志文件

[英]How to tail -f the latest log file with a given pattern

I work with some log system which creates a log file every hour, like follows:我使用一些日志系统,它每小时创建一个日志文件,如下所示:

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

I'm trying to tail to follow the latest log file giving a pattern (eg SoftwareLog*) and I realize there's:我试图跟踪最新的日志文件给出一个模式(例如 SoftwareLog*),我意识到有:

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

but that only follow one specific name - and these have different names by date and hour.但这仅遵循一个特定的名称-它们按日期和小时具有不同的名称。 I tried something like:我试过类似的东西:

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

but the wildcard statement is resoved before it gets passed to tail and doesn't re-execute everytime tail retries.但是通配符语句在它被传递到尾部之前被解析并且不会在每次尾部重试时重新执行。

Any suggestions?有什么建议?

I believe the simplest solution is as follows:我相信最简单的解决方案如下:

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

Now, if your directory contains other log files like "SystemLog" and you only want the latest "SoftwareLog" file, then you would simply include a grep as follows:现在,如果您的目录包含其他日志文件,如“SystemLog”,而您只想要最新的“SoftwareLog”文件,那么您只需包含一个 grep 如下:

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

[Edit: after a quick googling for a tool] [编辑:在快速搜索工具后]

You might want to try out multitail - http://www.vanheusden.com/multitail/您可能想尝试使用 multitail - http://www.vanheusden.com/multitail/

If you want to stick with Dennis Williamson's answer (and I've +1'ed him accordingly) here are the blanks filled in for you.如果你想坚持丹尼斯威廉姆森的回答(我已经相应地 +1 给他),这里是为你填补的空白。

In your shell, run the following script (or it's zsh equivalent, I whipped this up in bash before I saw the zsh tag):在你的 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

Background that process using the normal method (again, I don't know zsh, so it might be different)...使用正常方法处理的背景(同样,我不知道 zsh,所以它可能会有所不同)...

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

Then tail -F $SYMLINK_PATH so that the tail hands the changing of the symbolic link or a rotation of the file.然后tail -F $SYMLINK_PATH以便tail处理符号链接的更改或文件的旋转。

This is slightly convoluted, but I don't know of another way to do this with tail.这有点令人费解,但我不知道用尾巴来做到这一点的另一种方法。 If anyone else knows of a utility that handles this, then let them step forward because I'd love to see it myself too - applications like Jetty by default do logs this way and I always script up a symlinking script run on a cron to compensate for it.如果其他人知道处理此问题的实用程序,那么让他们向前迈进,因为我也很想自己看到它 - 默认情况下,像 Jetty 这样的应用程序会以这种方式记录日志,并且我总是编写一个在 cron 上运行的符号链接脚本来补偿为了它。

[Edit: Removed an erroneous 'j' from the end of one of the lines. [编辑:从其中一行的末尾删除了错误的“j”。 You also had a bad variable name "lastModifiedFile" didn't exist, the proper name that you set is "lastModified"]您还有一个错误的变量名称“lastModifiedFile”不存在,您设置的正确名称是“lastModified”]

我尚未对此进行测试,但一种可行的方法是运行一个后台进程,该进程创建并更新指向最新日志文件的符号链接,然后您将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

Then run it as: tail.sh 'SoftwareLog*'然后将其运行为: tail.sh 'SoftwareLog*'

The script will lose some log lines if the logs are written to between checks.如果在检查之间写入日志,脚本将丢失一些日志行。 But at least it's a single script, with no symlinks required.但至少它是一个单一的脚本,不需要符号链接。

We have daily rotating log files as: /var/log/grails/customer-2020-01-03.log .我们每天轮换日志文件为: /var/log/grails/customer-2020-01-03.log To tail the latest one, the following command worked fine for me:tail的最新一个,下面的命令能正常工作对我来说:

tail -f /var/log/grails/customer-`date +'%Y-%m-%d'`.log

( NOTE: no space after the + sign in the expression) 注意:表达式中的+号后没有空格)

So, for you, the following should work (if you are in the same directory of the logs):因此,对您来说,以下应该有效(如果您在日志的同一目录中):

tail -f SoftwareLog.`date +'%Y-%m-%d-%H'`

我相信最简单的方法是将taillshead一起使用,尝试这样的操作

tail -f `ls -t SoftwareLog* | head -1`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM