使用 bash,您如何在文件停止更新时收到警报?

Using bash, how do you get alerts when a file stops being updated?

如果文件在 x 分钟内没有更改,我希望收到提醒,比如通过电子邮件。

就上下文而言,应用程序 运行 24/7 在无人值守的系统上收集推文。如果存储推文的文件在 x 分钟内没有变化,我需要去检查应用程序是否没有意外终止。

有什么想法吗?我考虑过 watch 但我对 bash 和 Linux 总体上是新手。

例如,在目录“tmp”中有一个名为“tweets”的文件,我们可以运行一个包含带有 mmin 标志的查找的脚本。我们可以用 -5 表示最近 5 分钟内对文件的任何更改。如果 find 命令返回的文件数不为 0(通过管道传输到 wc -l),我们将 运行 命令发送到电子邮件。

#!/bin/bash

if [[ "$(find /tmp -name "*tweets" -mmin -5 | wc -l)" != "0" ]]
then
     echo "There is an issue" | mailx -s alert someone@someemail.com
fi

然后可以将其设置为每 5 分钟关闭一次 cron 作业 运行。

好吧,如果你说服务不是那么关键,你可以创建一个 cronjob 来检查某个文件的修改时间,如果满足某些条件则调用你的警报脚本。

如果是这样,google 一些关键字,例如“crontab”、“find mmin”,然后构建您的 cronjob。

否则,IMO,一个好方法可能是使用 grafana 之类的东西。在那里,您可以定义当某些事件发生时您或您的团队如何得到通知。

您的程序需要以某种方式注册其状态。例如。普罗米修斯指标。

通过这种方式,您的 alert/monitoring 与您的应用程序 运行 所在的服务器分离。您还可以跟踪服务的所有历史状态。

想想你是否在服务器上 运行 一个 cronjob 或 shell 脚本来检查文件修改时间戳并在某些事件上发出警报。如果服务器出现故障,您将不会收到警报,当然,您认为服务运行宁好。

同样,这完全取决于您的服务有多重要。

使用inotifywait

#!/usr/bin/env sh

MONITOREDFILE=/path/to/monitoredfile

TIMEOUT=600 # 600s or 10 minutes

EMAIL=user@example.com

lastmodified="monitoring started on $(date -R)"
while inotifywait \
  --quiet \
  --timeout $TIMEOUT \
  --event 'MODIFY' \
  "$MONITOREDFILE"
do
  printf '%s has been modified before %s seconds timeout\n' \
  "$MONITOREDFILE" $TIMEOUT
  lastmodified=$(date -R)
done
printf '!!! ALERT !!!\nFile %s has not been modified since %s seconds\n' \
    "$MONITOREDFILE" $TIMEOUT >&2
mailx -s "Stalled file $MONITOREDFILE" "$EMAIL" <<ENDOFMAIL
Monitored file $MONITOREDFILE has not been modified since $lastmodified.
ENDOFMAIL

使用 GNU date 获取文件上次修改的不同方法,并使循环为空:

#!/usr/bin/env sh

MONITOREDFILE=/path/to/monitoredfile
TIMEOUT=600 # 600s or 10 minutes
EMAIL=user@example.com

while inotifywait --quiet --timeout $TIMEOUT --event 'MODIFY' "$MONITOREDFILE"
do :;done
lastmodified=$(date --utc --iso-8601=seconds --reference="$MONITOREDFILE")
mailx -s "Stalled file $MONITOREDFILE" "$EMAIL" <<ENDOFMAIL
Monitored file $MONITOREDFILE has not been modified since $lastmodified.
ENDOFMAIL