如何使用tail命令查看频繁重建的日志文件?

23

我需要创建一个脚本,可以跟踪一个日志文件的变化,当该文件达到一定大小后重新创建(文件名相同)。

使用“tail -f”会在文件被重新创建/轮换时停止跟踪。

我想创建一个脚本,它可以尾随文件,并在文件达到100行时重新启动命令……或者更好的是,在文件重新创建时重新启动命令?

这个可行吗?

4个回答

23

是的!使用此代码(retry 会在文件不存在或因其他原因无法访问时进行尾部重试,而不是直接失败 - 可能是当你正在更改文件时):

tail -f --retry <filename>

或者

tail --follow=name --retry

或者

tail -F <filename>

~> tail -f --follow=name --retry /logs/logs/log.log tail:无法打开输入 - gfunk
看起来你在那里有两个 /logs。这是有意为之吗?如果该文件不存在或您没有权限,则会出现错误。但是,使用 --retry 选项,它将不断尝试,直到文件存在或您对其具有权限为止。首先在当前目录中使用测试文件进行尝试。 - evan
是的,那是故意的。这是我的日志存储目录。不幸的是,这个版本的tail不支持-F或--follow=name选项。我正在尝试用脚本找到另一种方法来实现这个功能。 - gfunk
2
OS X的tail命令不支持“--retry”选项。 - bonh
5
在 macOS 上,你可以使用 homebrew 轻松安装和使用 GNU 版本的 tail。 安装命令为:brew install coreutils。使用命令为:gtail -f --follow=name --retry <filename>(GNU 工具前缀为 g,以避免与 macOS 核心工具冲突)。 - fiedl

2
如果没有tail -F命令,且您正在尝试从logrotate中恢复,您可以将copytruncate选项添加到您的logrotate.d/规范文件中,以便在旋转后不会每次创建新文件,而是保留并截断文件,同时将一个副本旋转出来。
这样,旧文件句柄将继续指向新的(截断)日志文件,新的日志将被追加在其中。
请注意,此copy-truncate过程可能会导致一些数据丢失。

2

尝试运行

watch "tail -f" yourfile.log

很抱歉,我正在运行的系统上无法使用watch。 - gfunk

0

由于您没有支持所有功能的尾部,并且因为您没有手表,您可以使用一个简单的脚本无限循环执行尾部。

#!/bin/bash 

PID=`mktemp`
while true;
do
  [ -e "$1" ] && IO=`stat -c %i "$1"`
  [ -e "$1" ] && echo "restarting tail" && { tail -f "$1" 2> /dev/null & echo $! > $PID; }

  # as long as the file exists and the inode number did not change
  while [[ -e "$1" ]] && [[ $IO = `stat -c %i "$1"` ]]
  do
     sleep 0.5
  done
  [ ! -z $PID ] && kill `cat $PID` 2> /dev/null && echo > $PID
  sleep 0.5
done 2> /dev/null
rm -rf $PID

你可能想要使用trap来干净地退出这个脚本。这取决于你。

基本上,这个脚本检查inode号码(使用stat -c %i "$1")是否改变,以杀死tail命令并在文件重新创建时启动一个新的命令。

注意:你可以摆脱echo "restarting tail",它会污染你的输出。它只对测试有用。如果在我们检查inode号码之后,启动tail进程之前替换了文件,则可能会出现问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接