如何编写仅作用于新日志条目的脚本

kar*_*met 7 scripting monitoring bash logging apache-2.2

我觉得这应该是一件简单的事情,但我很难弄清楚。

我正在尝试编写一个脚本来监视其中一个 apache 日志文件并采取一些特定的操作。但是我应该如何监视日志文件?

每次将新行写入日志时,我都希望检查该条目以查看它是否与我要查找的内容匹配,以及是否发生了 x。当我手动执行此操作时,我使用了 cat 或 tail -f。我不想通过 cron 每 30 秒运行一次脚本并浏览整个日志(甚至最后 5 行),找出自上次脚本运行以来哪些行是新的,然后是一些事情。

有没有办法只检查日志中的单个新条目?

Kha*_*led 6

你可以利用的已有的Linux工具,如tailgrepnamed pipes。首先,使用以下命令创建一个命名管道 (fifo):

$ mkfifo /tmp/myfifo
Run Code Online (Sandbox Code Playgroud)

其次,创建一个将从该 fifo 文件读取的简单脚本。这是一个简单的例子:

#!/bin/bash
pipe=/tmp/myfifo

while true
do
    if read line <$pipe; then
        if [[ "$line" == 'quit' ]]; then
            break
        fi
        echo $line
    fi
done
echo "Reader exiting"
Run Code Online (Sandbox Code Playgroud)

此脚本从命名管道中读取并将该行打印到标准输出,直到它获得“退出”字样。这只是一个可以自定义的示例。

第三,用于tail读取附加到 apache 日志文件的新行并将输出重定向到命名管道。

$ tail -n0 -F /var/log/apache2/access.log | grep some_text > /tmp/myfifo
Run Code Online (Sandbox Code Playgroud)

-F选项意味着按名称跟随文件,这应该使其不受 logrotate 影响。因此,它将始终遵循相同的文件名。-n0没有得到任何旧线路的手段。在grep仅仅是直接相关的线路是有用的。

使用此解决方案,您不需要任何 cron 作业。只需运行上面显示的脚本和 tail 命令。


Lad*_*ada 5

通过 cron 运行脚本但使用logtaillogtail2读取文件将避免每分钟读取整个文件。Logtail 会跟踪它上次读取的位置,并在您下次使用它时跳转到该点。

如果您想立即对新的日志行采取行动,而不是在两次 cron 调用之间等待长达 59 秒,则必须使用tail -f或某些等效项。

Janne 和 Khaled 的回答都希望能很好地解决这个问题。