使用 bash,如何在文件停止更新时收到警报?
Posted
技术标签:
【中文标题】使用 bash,如何在文件停止更新时收到警报?【英文标题】:Using bash, how do you get alerts when a file stops being updated? 【发布时间】:2020-11-05 15:58:05 【问题描述】:如果文件在 x 分钟内没有更改,我想通过电子邮件收到提醒。
就上下文而言,应用程序在无人值守的系统上 24/7 全天候运行收集推文。如果存储推文的文件在 x 分钟内没有变化,我需要去检查应用程序是否没有意外终止。
有什么想法吗?我考虑过watch
,但总的来说我是 bash 和 Linux 的新手。
【问题讨论】:
在每 5 分钟运行一次 cron 作业的脚本中查找 -mmin -5 怎么样? 考虑将您的应用程序设置为服务,并在它崩溃时让 systemd 重新启动它:ma.ttias.be/auto-restart-crashed-service-systemd -- 这样就无需监控日志文件来衡量应用程序的运行状况。跨度> 将应用程序设置为服务不会捕获应用程序不崩溃但不获取推文的更常见问题。例如,由于多种原因(例如速率限制),Twitter 经常无法恢复地停止发送推文。 曾几何时,Twitter 发布了标准的 RSS 提要。我想现在他们的闭源非标准 API 不那么可靠,并且由于无法调试的原因而中断。 【参考方案1】:例如,在目录“tmp”中有一个名为“tweets”的文件,我们可以运行一个包含带有 mmin 标志的 find 的脚本。我们可以用 -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 作业。
【讨论】:
我认为您的意思是if [[ "$(find /tmp -name "*tweets" -mmin -5 | wc -l)" = "0" ]]
不是 !="0"
。好主意。【参考方案2】:
好吧,如果您说服务不是那么重要,您可以创建一个 cronjob 来检查某个文件的修改时间,如果满足某些条件,则调用您的警报脚本。
如果是这样,谷歌搜索一些关键字,如“crontab”、“find mmin”,然后构建你的 cronjob。
否则,IMO,一个好方法可能是使用像 grafana 这样的东西。在那里,您可以定义当某些事件发生时您或您的团队如何获得通知。
您的程序需要以某种方式注册其状态。例如。普罗米修斯指标。
通过这种方式,您的警报/监控与您的应用程序运行所在的服务器分离。您还可以跟踪服务的所有历史状态。
想想你是否在服务器上运行 cronjob 或 shell 脚本来检查文件修改时间戳并在某些事件上发出警报。万一服务器宕机了,你不会得到警报,当然,你认为服务运行良好。
同样,这完全取决于您的服务有多重要。
【讨论】:
grafana 在这个场合有点过分,但很高兴知道。【参考方案3】:使用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
【讨论】:
我希望我能对此表示赞同。 cron 作业不是比循环更优雅吗? 只有在文件被修改或超时时才会真正运行循环。所以不多。 Cron 作业必须轮询文件修改。inotifywait
暂停脚本执行,完全由事件驱动。以上是关于使用 bash,如何在文件停止更新时收到警报?的主要内容,如果未能解决你的问题,请参考以下文章